?智能小车的制作是学习51单片机中一个很重要的过程,下面是自己完成小车的一点心得,在这里和大家分享。
代码如下:
#include <reg51.h>? ? ? //IO引脚定义: sbit key1 = P3^7;?? ?//定义按键1 sbit key2 = P3^6;?? ?//定义按键2 sbit key3 = P3^5;?? ?//定义按键3 sbit key4 = P3^4;?? ?//定义按键4
sbit L_WXJ=P2^1;?? ? ?? ??? ?//四路寻迹模块接口第四路,左外录迹?? ? ?? ??? ? sbit R_WXJ=P2^3;?? ? ?? ??? ?//四路寻迹模块接口第一路,右外寻迹
sbit IN1=P3^0;?? ??? ? sbit IN2=P3^1; sbit IN3=P1^2; sbit IN4=P1^3; sbit IN11=P2^6;?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ? sbit IN22=P2^7; sbit IN33=P0^2; sbit IN44=P0^3;
sbit L_PWM=P1^4;?? ? ? //左轮调速,接驱动模块ENA使能端,在这里输入PWM信号 sbit R_PWM=P1^6;?? ? ? //右轮调速,接驱动模块ENB使能端,在这里输入PWM信号 sbit L_PWM1=P0^4;?? ? ? //左轮调速,接驱动模块ENA使能端,在这里输入PWM信号 sbit R_PWM1=P0^5;?? ? ? //右轮调速,接驱动模块ENB使能端,在这里输入PWM信号
//宏定义 #define L_go ? ? ?IN1=0;IN2=1; //左轮前进 #define L1_go ? ? ?IN33=0;IN44=1; //左轮前进 #define L_back ? ?IN1=1;IN2=0; //左轮后退 #define L1_back ? ?IN33=1;IN44=0; //左轮后退 ? ? #define R_go ? ??? ?IN3=0;IN4=1; //右轮前进 #define R1_go ? ??? ?IN11=0;IN22=1; //右轮前进 #define R_back ??? ?IN3=1;IN4=0; //右轮后退 #define R1_back ??? ?IN11=1;IN22=0; //右轮后退
#define car_go?? ??? ??? ??? ?L_go;R_go;?? ??? ?//小车前进 #define car_go1?? ??? ??? ??? ?L1_go;R1_go; ? ? ?? ??? ??? ? #define car_back?? ??? ??? ?L_back;R_back?? ?//小车后退 #define car_back1?? ??? ??? ?L1_back;R1_back; #define car_left?? ??? ??? ?R_go;L_back #define car_left1?? ??? ??? ?R1_go;L1_back?? ??? ?//小车左转弯 #define car_right?? ??? ??? ?L_go;R_back?? ??? ?//小车右转弯 #define car_right1?? ??? ??? ?L1_go;R1_back #define car_stop?? ??? ??? ?L_stop;R_stop;L_stop;R_stop;?? ?//小车停车
//数据定义 unsigned char l_tt=0;?? ?//定时器计数用
unsigned char l_Lpwm=0;?? ?//左轮PWM占空比值,我们设计3个格,0-2,0为停止,2为全速 unsigned char l_Rpwm=0;?? ?//右轮PWM占空比值,我们设计3个格,0-2,0为停止,2为全速 unsigned char l_Lpwm1=0;?? ?//左轮PWM占空比值,我们设计3个格,0-2,0为停止,2为全速 unsigned char l_Rpwm1=0;?? ?//右轮PWM占空比值,我们设计3个格,0-2,0为停止,2为全速
//TIMER0中断服务子函数产生PWM信号 void timer0()interrupt 1 ? using 2 { ?? ?TH0=0XFC;?? ? ?//定时1毫秒,10格调速,为100HZ频率,此频率下效果比较好,过大有噪声,过小振动大 ?? ?TL0=0X17; ?? ?l_tt++; ?? ?if(l_tt>3)l_tt=0;?? ?//比较用,3格调速 ?? ? ?? ?if((l_tt)<=l_Lpwm){//左调速,占空比数值越大,输出高电平时间越宽,电机转速越高,我们设计3个格,0-2,0为停止,2为全速 ?? ? ?? ?L_PWM=1; ?? ??? ?L_PWM1=1; ?? ?} ?? ?else{ ?? ??? ?L_PWM=0; ?? ??? ?L_PWM1=0; ?? ?} ?? ?if(l_tt<=l_Rpwm){//右调速,同上 ?? ??? ?R_PWM=1; ?? ??? ?R_PWM1=1; ?? ?} ?? ?else{ ?? ??? ?R_PWM=0; ?? ??? ?R_PWM1=0; ?? ?} }
void XJmoto(void) {?? ? ?? ?while(1){?? ??? ?//循环探测 ?? ??? ??? ?if((R_WXJ == 0)&&(L_WXJ == 0)) ?? ??? ??? ?{ ?? ??? ??? ?car_go; ?? ??? ??? ?car_go1; ?? ??? ??? ?} ?? ??? ??? ?else if((R_WXJ ==0)&&(L_WXJ == 1))? ?? ??? ??? ?{ ?? ??? ??? ?car_right; ?? ??? ??? ?car_right1; ?? ??? ??? ?} ?? ??? ??? ?else if((R_WXJ == 1)&&(L_WXJ == 0)) ?? ??? ??? ?{ ?? ??? ??? ?car_left; ?? ??? ??? ?car_left1; ?? ??? ??? ?} ?? ??? ??? ?else {?? ??? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ?car_go; ?? ??? ??? ?car_go1;? ?//如果写成后退,易出现问题 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ?} ?? ??? ?} }
/***********主函数开始********************************************************/?? ? void main(void) { ?? ?TMOD=0x01; ?//定时器0方式1,16位计数器,用来计数时间,定时器1做为波特率发生器 ??? ?TH0=(65536-100)/256;?? ? ? ?? ?TL0=(65536-100)%256; ?? ?TR0= 1; ?? ?ET0= 1; ?? ?EA=1;? ?? ? ?? ?l_Lpwm=0; ?? ?l_Rpwm=0; ?? ?l_Lpwm1=0; ?? ?l_Rpwm1=0;
?? ?while(1){?? ??? ?//按键选择不同车速,以适应不同的赛道 ?? ??? ?if(key1==0){?? ??? ?//按下按钮S1启动寻迹功能 ?? ??? ??? ?l_Lpwm=1;//设置速度 ?? ??? ??? ?l_Rpwm=1; ?? ??? ??? ?l_Lpwm1=1;//设置速度 ?? ??? ??? ?l_Rpwm1=1; ?? ??? ??? ?XJmoto(); ?? ??? ?} ?? ??? ?if(key2==0){?? ??? ?//按下按钮S2启动寻迹功能 ?? ??? ??? ?l_Lpwm=6;//设置速度 ?? ??? ??? ?l_Rpwm=6; ?? ??? ??? ?l_Lpwm1=6;//设置速度 ?? ??? ??? ?l_Rpwm1=6; ?? ??? ??? ?XJmoto(); ?? ??? ?} ?? ??? ?if(key3==0){?? ??? ?//按下按钮S3启动寻迹功能 ?? ??? ??? ?l_Lpwm=8;//设置速度 ?? ??? ??? ?l_Rpwm=8; ?? ??? ??? ?l_Lpwm1=8;//设置速度 ?? ??? ??? ?l_Rpwm1=8; ?? ??? ??? ?XJmoto(); ?? ??? ?} ?? ??? ?if(key4==0){?? ??? ?//按下按钮S4启动寻迹功能 ?? ??? ??? ?l_Lpwm=10;//设置速度 ?? ??? ??? ?l_Rpwm=10; ?? ??? ??? ?l_Lpwm1=10;//设置速度 ?? ??? ??? ?l_Rpwm1=10; ?? ??? ??? ?XJmoto(); ?? ??? ?} ?? ?}?? ??? ?
}
上面的代码可以实现按键调速,但因为自己只利用key1,所以占空比没改,5:5和1:1,占空比都是50%,但因为5:5加速时间更长,所以速度可能是更快的。
还有一个关于占空比设置的小细节,格数多会有个问题,就是如果你把运动时间设置的比较短,因为每个电机的灵敏性不同,容易导致轮子有的转,有的不转,就算都转动了,也容易有快有慢,导致小车转圈。
在连线时要注意L298N要和单片机共地,通过L298N的5V输出端给单片机供电,L298N的12V输入可由锂电池供电。
红外检测模块的高度设置是一个很重要的问题,通过实践总结的经验是可以在走的路线上实测,当红外模块在黑线上信号灯灭,在白板上信号灯亮时,说明高度合适。并不是很多人说的越低越好,这点很重要。?
当车轮打滑时,可以通过增加负重或减慢车速来有效规避。
以上是自己的一点拙见,希望对大家有用。
|