寻迹小车+蓝牙遥控
此程序主要应用的是51中的定时器中断和串口中断
定时器中断主要是让小车进行循迹;
串口中断主要是为了实现蓝牙遥控;
其中m0和m1分别代表的是白线和黑线,也就是小车的红外接收管对黑线的判断;
然后zkb1和zkb2都代表的占空比,zkb1代表的是右轮的占空比,zkb2代表的是左轮的占空比;
IN1,IN2是控制右轮的,IN3,IN4是控制左轮的;
其中correct_left(),correct_right()都分代表的是向左或向右校正;
还有left(),right(),turn_right(),turn_left(),都是英文名来表示的左,右,向右转,向左转
这些都是子函数;
left1,left2,分别代表的是小车左边的两个红外接收管;
right1,right2,分别代表的是小车右边的两个红外接收管;
#include “reg51.h”
#include “intrins.h”
#define m0 0
#define m1 1
typedef unsigned int u16;
typedef unsigned char u8;
sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^3;
sbit IN4=P1^4;
sbit ENA=P1^2;
sbit ENB=P1^5;
sbit left1=P0^0;
sbit left2=P0^1;
sbit right1=P0^2;
sbit right2=P0^3;
unsigned char zkb1=0;
unsigned char zkb2=0;
unsigned char t=0; //t代表的是周期
void line_left();
void zhidon();
void line_right();
void right();
void left();
void back();
void line_straight()reentrant;
void delay(long int Delay_time) //延时函数
{
unsigned int m=Delay_time;
while(m–);
}
unsigned char receiveData=‘0’; //蓝牙从手机中接收到的字符‘0’
//且让receiveData初始值为‘0’是为了让小车在没有手机进行蓝牙控制时
//小车进行的循迹模式
void init() //定时器中断
{
TMOD|=0x01; //选定定时/计数器0的工作的方式
TH0=(65536-100)/256;
TR0=(65538-100)%256;
EA=1; //打开总中断;
ET0=1; //打开中断服务程序
TR0=1; //打开计数器
ENA=1;
ENB=1;
}
void correct_left() //向左校正
{
zkb1=12;
zkb2=6;
IN1=0;
IN2=1;
IN3=0;
IN4=1;
}
void correct_right() //向右校正
{
zkb1=6;
zkb2=10;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
void turn_left() //向左转
{
zkb1=10;
zkb2=16;
IN1=0;
IN2=1;
IN3=0;
IN4=1;
}
void turn_right() //向右转
{
zkb1=15;
zkb2=10;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
void straight() //直行
{
zkb1=5;
zkb2=6;
IN1=0;
IN2=1;
IN3=1;
IN4=0;
}
void line_right() //右侧有黑线时
{
zkb1=10;
zkb2=15;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
void go_straight() //直行
{
zkb1=10;
zkb2=7;
IN1=0;
IN2=1;
IN3=1;
IN4=0;
}
void line_left() //左侧有黑线时
{
zkb1=15;
zkb2=10;
IN1=0;
IN2=1;
IN3=0;
IN4=1;
}
void back() //后退
{
zkb1=7;
zkb2=10;
IN1=1;
IN2=0;
IN3=0;
IN4=1;
}
void zhidon() //制动
{
zkb1=10;
zkb2=10;
IN1=1;
IN2=1;
IN3=1;
IN4=1;
}
void right() //向右
{
zkb1=7;
zkb2=10;
IN1=0;
IN2=1;
IN3=1;
IN4=0;
}
void left() //向左
{
zkb1=10;
zkb2=7;
IN1=0;
IN2=1;
IN3=1;
IN4=0;
}
void timer0() interrupt 1
{
TH0=(65536-100)/256;
TR0=(65538-100)%256;
if(t
ENA=1;
}
else
{
ENA=0;
}
if(t=50) //t的周期是50
{
t=0;
ENA=1;
ENB=1;
}
}
void initialize() //波特率 4800
{
SCON=0x50; //串口控制工作寄存器 SM0=0 SM1=1 REN=1 方式1
TMOD=0x20; //定时/计数器的工作方式 八位自动重装 方式2
TH1=0XF3; //定时器初始值
TL1=0xF3; //定时器初始值
TR1=1; //T1运行控制位
ES=1; //串口中断打开
EA=1; //总中断打开
PCON=0X80; //波特率倍增 SMOD
}
void detect_infrared() //循迹函数(判断黑线)
{
if((right2 ==m0 )&&(right1 == m0)&&(left1 == m1)&&(left2 == m0))
{
turn_left();
}
else if((right2 ==m0 )&&(right1 == m0)&&(left1 == m0)&&(left2 == m1))
{
correct_left();
}
else if((right2 ==m0 )&&(right1 == m1)&&(left1 == m0)&&(left2 == m0))
{
turn_right();
}
else if((right2 ==m1 )&&(right1 == m0)&&(left1 == m0)&&(left2 == m0))
{
correct_right();
}
else if((right2 ==m0 )&&(right1 == m0)&&(left1 == m0)&&(left2 == m0))
{
straight();
}
else if((right2 ==m1 )&&(right1 == m1)&&(left1 == m0)&&(left2 == m0))
{
line_right();
delay(56000);}
else if((right2 ==m0 )&&(right1 == m0)&&(left1 == m1)&&(left2 == m1))
{
line_left();
delay(56000);
}
else
{
straight();
}
}
void main() //主函数
{
initialize(); //串口初始
init();
while(1)
{
if(receiveData==‘0’) //若接收到的字符是‘0’则小车进行自主循迹
{detect_infrared();
}
else //否则进行以下指令
{
if(receiveData=='1')
{go_straight();
}
else if(receiveData=='2')
{turn_right();
}
else if(receiveData=='3')
{turn_left();
}
else if(receiveData=='4')
{
right();
}
else if(receiveData=='5')
{
left();
}
else if(receiveData=='6')
{
line_right();
}
else if(receiveData=='7')
{
line_left();
}
else if(receiveData=='8')
{
zhidon();
}
else if(receiveData=='9')
{
back();
}
}
}
}
void usart() interrupt 4
{
receiveData=SBUF;
RI=0;
SBUF=receiveData;
while(!TI);
TI=0;
}