代码原理:
借用四个红外传感器来判断小车的运动状态(直行、转弯角度等)从而调节左右电机的转速以达到循迹的效果。
unsigned char pwm_val_left =0,push_val_left =0,pwm_val_right =0,push_val_right=0;
void timer0()interrupt 1
{
TH0=0XFc;
TL0=0X18;
time++;
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
void pwm_out_left_moto(void)
{
if(Left_moto_stop)
{
if(pwm_val_left<=push_val_left)
{
Left_moto_pwm=1;
}
else
{
Left_moto_pwm=0;
}
if(pwm_val_left>=20)
pwm_val_left=0;
}
else
{
Left_moto_pwm=0;
}
void pwm_out_right_moto(void)
{
if(Right_moto_stop)
{
if(pwm_val_right<=push_val_right)
{
Right_moto_pwm=1;
}
else
{
Right_moto_pwm=0;
}
if(pwm_val_right>=20)
pwm_val_right=0;
}
else
{
Right_moto_pwm=0;
}
}
调速思路:
定义pwm_val_left和right用作定时器的自加参数,push_val_left和right用作左右电机的控速,当push_val的值大于pwm_val时电机运行,反之停止来达到控制电机的pwm波的效果,电机速度最大为20.
#define Left_1_led P3_7
#define Right_1_led P3_6
#define Left_2_led P2_0
#define Right_2_led P2_1
12为左右两个传感器系统,left和right为传感器系统中的左右红外传感器
#define Left_moto_go {P1_2=1,P1_3=0;}
#define Left_moto_back {P1_2=0,P1_3=1;}
#define Left_moto_Stop {P1_2=0,P1_3=0;}
#define Right_moto_go {P1_4=1,P1_5=0;}
#define Right_moto_back {P1_4=0,P1_5=1;}
#define Right_moto_Stop {P1_4=0,P1_5=0;}
这几个定义了左右电机的状态:前进、后退、停止
下边是L298N的原理图
这里的讲解以Left_moto_go为例:
ENA=1时 左电机启动;
P1_2=1即IN1=1,经过IN1上边的与门后T1左端为高电平,T1右端导通。而经过IN1下边的非门之后为低电平,再经过与门T2为低电平,T2右端无法导通。
P1_3=0即IN2=0,同理,从中间竖直对称过去的T3经过与门后为低电平,T3左端断开,T4右端为高电平,T4左端导通
以上为左电机正转的示例,其他情况同理
ENA与ENB控制左右电机的启动,IN1 IN2和IN3 IN4分别控制左右电机的正转反转和停止
void run(void)
{
push_val_left=10;
push_val_right=10;
Left_moto_go ;
Right_moto_go ;
}
void backrun(void)
{
push_val_left=10;
push_val_right=10;
Left_moto_back;
Right_moto_back;
}
void stop(void)
{
Right_moto_Stop ;
Left_moto_Stop ;
}
此为左右电机共同前进后退停止的情况(速度为10以防小车速度过快转弯出现问题)
//左转全速
void leftrunmax(void)
{
push_val_left=5;
push_val_right=15;
Right_moto_go ;
Left_moto_back ;
}
//左转中速
void leftrun(void)
{
push_val_left=1;
push_val_right=10;
Right_moto_go ;
Left_moto_back ;
}
//左转低速
void leftrunlow(void)
{
push_val_left=5;
push_val_right=10;
Right_moto_go ;
Left_moto_go ;
}
//右转全速
void rightrunmax(void)
{
push_val_left=15;
push_val_right=5;
Left_moto_go ;
Right_moto_back ;
}
//右转中速
void rightrun(void)
{
push_val_left=10;
push_val_right=1;
Left_moto_go ;
Right_moto_back ;
}
//右转低速
void rightrunlow(void)
{
push_val_left=10;
push_val_right=5;
Left_moto_go ;
Right_moto_go ;
}
以上为调节左右电机转速(push_val)与方向(moto_go/back)从而改变转弯的速度以应对不同角度弯道的代码
接下来为主函数
#include <REGX52.H>
#include "pwm.h"
void main()
{
P1=0X00;
TMOD=0X01;
TH0= 0XFc;
TL0= 0X18;
TR0= 1;
ET0= 1;
EA = 1;
while(1)
{
//直线
if(Left_1_led==1&&Right_1_led==0&&Left_2_led==0&&Right_2_led==1)
run();
else
{
//钝角左转
if(Left_1_led==0&&Right_1_led==0&&Left_2_led==0&&Right_2_led==1)
leftrunlow();
//钝角右转
if(Left_1_led==1&&Right_1_led==0&&Left_2_led==0&&Right_2_led==0)
rightrunlow();
//直角左转
if(Left_1_led==0&&Right_1_led==0&&Left_2_led==1&&Right_2_led==1)
leftrun();
//直角右转
if(Left_1_led==1&&Right_1_led==1&&Left_2_led==0&&Right_2_led==0)
rightrun();
//锐角左转
if(Left_1_led==0&&Right_1_led==1&&Left_2_led==1&&Right_2_led==1)
leftrunmax();
//锐角右转
if(Left_1_led==1&&Right_1_led==1&&Left_2_led==1&&Right_2_led==0)
rightrunmax();
//停止
if(Left_1_led==1&&Right_1_led==1&&Left_2_led==1&&Right_2_led==1)
stop();
}
}
}
四个传感器的使用增加了小车转弯时灵敏度,可以使循迹小车适应更多的弯道