如图是红外对管的原理图,左边为发射管,右边为接收管,接收管的电阻随光线的增强而减小,检测原理是红外发射管发射光线到路面,红外光遇到白底则被反射,接收管接收到反射光,经过比较器整形后输出低电平到单片机的IO口,当红外光遇到黑线时则被吸收,接受管没有接受到反射光,经比较器整形后输出高电平到IO口,从而实现小车的循迹功能。
#include<reg52.h>
sbit IN0 = P1^0;//定义小车电机的引脚
sbit IN1 = P1^1;//定义小车电机的引脚
sbit IN2 = P1^2;//定义小车电机的引脚
sbit IN3 = P1^3;//定义小车电机的引脚
sbit IN4 = P1^4;//定义小车电机的引脚
sbit IN5 = P1^5;//定义小车电机的引脚
sbit IN6 = P1^6;//定义小车电机的引脚
sbit IN7 = P1^7;//定义小车电机的引脚
sbit BUZZ = P2^6;//蜂鸣器引脚
sbit Leftled=P3^6;//使能引脚
sbit Rightled=P3^5;//使能引脚
sbit Rightpwm=P0^0;//PWM输出信号引脚
sbit Rightpwm1=P0^1;//PWM输出信号引脚
sbit Leftpwm=P0^2;//PWM输出信号引脚
sbit Leftpwm1=P0^3;//PWM输出信号引脚
#define Leftgo {IN4=1,IN5=0,IN7=1,IN6=0;}//左边车轮前进
#define Leftstop {IN4=0,IN5=0,IN7=0,IN6=0;}//左边车轮停止
#define Rightgo {IN0=1,IN1=0,IN3=1,IN2=0;}//右边车轮前进
#define Rightstop {IN0=0,IN1=0,IN3=0,IN2=0;}//右边车轮停止
unsigned char pwm_val_left=0;//变量定义
unsigned char push_val_left=0;//变量定义
unsigned char pwm_val_right=0;//变量定义
unsigned char push_val_right=0;//变量定义
bit Right_stop=1;//变量定义
bit Left_stop=1;//变量定义
void run();//前进函数
void leftrun();//左转函数
void rightrun();//右转函数
void pwm_out_left_moto();//左轮pwm
void pwm_out_right_moto();//右轮pwm
void main()
{
P1 = 0x00;//小车停止
TMOD &= 0xF0;//定时器0选择模式0
TMOD |= 0x01;
TH0 = 0xFC;定时1ms
TL0 = 0x18;
TR0 = 1;//开定时器0
ET0 = 1;//开启定时器0中断
EA = 1;//开总中断
while(1)
{
if(Leftled==0&&Rightled==0)//未检测到黑线
run();
else
{
if(Leftled==0&&Rightled==1)//右边检测到黑线
{
rightrun();
}
if(Leftled==1&&Rightled==0)//左边检测到黑线
{
leftrun();
}
}
}
}
void run()//前进函数
{
push_val_left=3;
push_val_right=3;
Leftgo;
Rightgo;
}
void leftrun()//左转函数
{
push_val_left=3;
push_val_right=3;
Rightgo;
Leftstop;
}
void rightrun()//右转函数
{
push_val_left=3;
push_val_right=3;
Rightstop;
Leftgo;
}
void pwm_out_left_moto()//左轮pwm
{
if(Left_stop)
{
if(pwm_val_left<=push_val_left)
{
Leftpwm=1;
Leftpwm1=1;
}
else
{
Leftpwm=0;
Leftpwm1=0;
}
if(pwm_val_left>=10)
pwm_val_left=0;
}
else
{
Leftpwm=0;
Leftpwm1=0;
}
}
void pwm_out_right_moto()//右轮pwm
{
if(Right_stop)
{
if(pwm_val_right<=push_val_right)
{
Rightpwm=1;
Rightpwm1=1;
}
else
{
Rightpwm=0;
Rightpwm1=0;
}
if(pwm_val_right>=10)
pwm_val_right=0;
}
else
{
Rightpwm=0;
Rightpwm1=0;
}
}
void InterruptTimer0() interrupt 1//定时器0中断服务函数
{
TH0 = 0xFC;
TL0 = 0x18;
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
程序不难理解,算法可以再进行改进,以使小车运动更稳定,仅供参考交流
还请各位高手斧正。
|