关于51智能循迹小车的电机驱动问题

超级羽 2019-11-02 01:16:56
各位大神请教一下小车的驱动问题:程序烧录进单片机,电源启动后,L298N有嗡嗡嗡的声音,小车的轮子不转,用手拨动一下会极小的速度转动(像功率不足,而且只有一侧转),占空比也调得比较高,不知道是哪里出问题了,请各位大神批评指教(用的是4节1.5伏的电池,驱动5个红外对管,超声波模块,电机,不知道是不是输入电压不足的问题,也可能是我理解错了pwm原理),下面是小车的代码,新手第一次写,请多包涵。(如有其他问题能帮忙一起指出吗,麻烦各位了)


#include <reg52.h>
#include<intrins.h>

sbit IN1=P0^1; //左电机//
sbit IN2=P0^2;
sbit ENA=P0^0;
sbit IN3=P0^3; //右电机//
sbit IN4=P0^4;
sbit ENB=P0^5;

sbit Trig=P1^1; //超声波模块的TRIG,具体接口需要改变//
sbit Echo=P1^2; //超声波模块的ECHO

#define uc unsigned char
#define ui unsigned int
#define juli 25 //距离障碍物的距离//

#define leftgo {IN1=1, IN2=0;} //左电机正传
#define leftback {IN1=0, IN2=1;} //左电机反转
#define rightgo {IN3=0, IN4=1;} //右电机正传
#define rightback {IN3=1, IN4=0;} //右电机反转

uc ZKBR=0;
uc ZKBL=0;
uc t=0; //定时器计数次数//

uc FLAG; //超声波超出测量范围的标志
ui sum; //超声波模块中定时器1所计的总数//
float L; //L为超声波模块中计算的与障碍物之间的距离//

sbit L1=P2^0; //五个红外循迹模块//

sbit L2=P1^2;
sbit M=P1^3;
sbit R2=P1^4;
sbit R1=P1^5;

void t0go() //定时器0开始工作的函数//
{
TMOD=0x01; //定时器t0工作方式为1//
TH0=(65536 - 100)/ 256; //定时器计时108.5微秒//
TL0=(65536 - 100)% 256;
EA=1; //开总中断//
ET0=1; //打开定时器0中断//
TR0=1; //开启定时器//
}

void t1go() //定时器1马上开始工作的函数//
{
TMOD=0x10;
EA=1; //可能出错//
ET1=1;
}

void t0() interrupt 1 //t0的中断函数//
{
TH0 =(65536-100)/ 256; //重装定时器的初值//
TL0 =(65536-100)% 256;
if(t<ZKBL)
{
ENA=1;
}
else
{
ENA=0;
}
if(t < ZKBR)
{
ENB=1;
}
else
{
ENB=0;
}
++t;
if(t>=50)
{
t=0;
}
}

void t1() interrupt 3 //超声波超出测量范围//
{
FLAG=1;
}
void turnleft1() //左转小转弯//
{
ZKBL=30;
ZKBR=10;
}
void turnleft2() //左转大转弯//
{
ZKBL=50;
ZKBR=10;
}
void turnright1() //右转小转弯//
{
ZKBL=10;
ZKBR=30;
}
void turnright2() //右转大转弯//
{
ZKBL=10;
ZKBR=50;
}
void go()
{
ZKBL=40;
ZKBR=40;
leftgo;
rightgo;
}
void back()
{
ZKBL=10;
ZKBR=10;
leftback;
rightback;
}
void stop()
{
ZKBL=0;
ZKBL=0;
}
void xunji()
{
uc flag;
if ((R2==0)&&(L1==1)&&(L2==1)&&(R1==1)) //小右转//
{
flag=1;
}
else if((R1==0)&&(R2==0)&&(L1==1)&&(L2==1)) //大右转//
{
flag=2;
}
else if((R2==0)&&(L2==1)) //停车
{
flag=3;
}
else if((R2==1)&&(R1==1)&&(L1==1)&&(L2==0)) //小左转//
{
flag=4;
}
else if((R1==1)&&(R2==1)&&(L1==0)&&(L2==0)) //大左转//
{
flag=5;
}
else if((L1==0)&&(L2==1)&&(M==1)&&(R1==1)&&(R2==1))
{
flag=5;
}
else if((L1==1)&&(L2==1)&&(M==1)&&(R1==0)&&(R2==1))
{
flag=2;
}
else if((L1==1)&&(L2==1)&&(M==1)&&(R1==1)&&(R2==1)) //特殊情况,当小车无法扫描到黑线时,小车后退//
{
flag=6;
}
switch(flag)
{
case 1:turnright1(); break;

case 2:turnright2(); break;

case 3:stop(); break;

case 4:turnleft1(); break;
case 5:turnleft2(); break;
case 6:back(); break;

default:go(); break;
}
}
void send() //使模块开始发送8个方波//
{
Trig=1;
_nop_(); //单片机延后一个机器周期//
_nop_(); //设置目的在于使Trig口开始发送方波//。
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
Trig=0;
}
void distance()
{
TH1=0; //使定时器1计数归位//
TL1=0;
send();
while(!Echo); //!echo=0,既echo=1输出高电平时跳出while,实质是等待输出开始后便打开计时器//
TR1=1;
while(Echo); //等待echo口输出高电平结束后(即输出低电平时)后便关闭计时器//
TR1=1;
sum=TH1*256+TL1; //得到计时器在过程中计的总数//
L=(sum*1.87)/100; //已得到的公式 1.87为在20度温度下的声速取值344,L的单位是厘米//
if(L<=juli && FLAG==0) //上边已经定义了距离障碍物的最小距离,单位是厘米//
{
back();
}
if(FLAG==1) //超出测量
{
FLAG=0;
}
}
void main()
{
t0go();
t1go();
leftgo;
rightgo;
while(1)
{
xunji();
distance();
}
}

...全文
给本帖投票
1577 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
jgj58 2019-11-18
  • 打赏
  • 举报
回复
电机都有驱动频率范围,这个是常识
超级羽 2019-11-14
  • 打赏
  • 举报
回复
我看了下,好像是定时器记时频率太高引起的
Glen_hsu 2019-11-12
  • 打赏
  • 举报
回复
楼上有道理,应该提高电机驱动电压或L298供电电压。有声音和转的趋势,说明没有问题
低头吃饭 2019-11-12
  • 打赏
  • 举报
回复
看下驱动频率,先试用一下单纯的IO驱动,高低电平,若是行,考虑PWM驱动问题!
jgj58 2019-11-11
  • 打赏
  • 举报
回复
代码没看,但是可以用示波器测量L298N输出的PWM波形是否想要的波形。 假如波形正确,看看电机和L298N是否匹配,如果电机过大,L298N是肯定带不动电机的

27,508

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧

手机看
关注公众号

关注公众号

客服 返回
顶部