标题:
蓝牙循迹小车源程序
[打印本页]
作者:
liujie1997
时间:
2017-12-26 19:32
标题:
蓝牙循迹小车源程序
单片机源程序如下:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit in1=P1^0;
sbit in2=P1^1;
sbit in3=P1^2;
sbit in4=P1^3;
sbit ENA=P1^4;
sbit ENB=P1^5;
sbit led=P2^3;
uchar count_flag=0; //当第1个字符接收完成后,置count_flag=1
uchar recv_flag=0; //当3个字符全部接收完成后,置recv_flag=1,否则recv_flag=0
uchar count_data=0; //接收到的3个字符在数组中的下标,0、1、2
uchar buffer_data[3]=0; //存放接收到的3个字符,buffer_data[count_data]为数组中的一个字符
uint pwm_data=0; //PWM方波的计数变量
uint left_pwm=0; //表征左边电机的占空比
uint right_pwm=0; //表征右边电机的占空比
uint PWM_CYCLE=210; //PWM方波的周期
uint temp=0; //保存P3口输入的循线信息
uint flag=0;
uint flagxun=0; //flagxun=0,蓝牙状态;flagxun=1,循线状态
/************************毫秒延时函数**********************************************/
void delay(uint x)
{
uint m,n;
for(m=0;m<x;m++)
for(n=0;n<15;n++);
}
/**************************端口初始化函数******************************************/
void com_init()
{
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
}
/**************************电机初始化函数******************************************/
void dian_init()
{
in1=1;
in2=0;
in3=1;
in4=0;
ENA=0;
ENB=0;
}
/**************************定时器初始化函数******************************************/
void timer_init(void)
{
TMOD=0x22; //T1为方式2,T0为方式2
TL1=0xfd; //11.0592M晶振,波特率为9600
TH1=0xfd;
TL0=0;
TH0=156; //计数100次溢出,即每隔100us进入T0中断
SCON=0x50;
PCON=0x00;
TR1=1;
ES=1;
EA=1;
ET0=1;
TR0=1;
}
/**************************驱动轮方向与速度控制函数******************************************/
void forward1(uint x) //左轮前进
{
in1=1;
in2=0;
left_pwm=x;
}
void forward2(uint x) //右轮前进
{
in3=1;
in4=0;
right_pwm=x;
}
void back1(uint x) //左轮后退
{
in1=0;
in2=1;
left_pwm=x;
}
void back2(uint x) //右轮后退
{
in3=0;
in4=1;
right_pwm=x;
}
/**************************高速向前******************************************/
void bforw() //高速向前
{
in1=1;
in2=0;
in3=1;
in4=0;
left_pwm=140;
right_pwm=140;
}
void mforw() //中速向前
{
in1=1;
in2=0;
in3=1;
in4=0;
flag=0;
while((temp==0)&&(8000-flag))
{
left_pwm=105;
right_pwm=105;
flag++;
delay(10);
}
bforw();
flag=0;
}
void sforw() //保持原来方向,低速向前测黑线
{
left_pwm=35;
right_pwm=35;
}
void sright() //微调路径,尽量减小小车左右摆动
{
in1=1;
in2=0;
in3=1;
in4=0;
flag=0;
while(temp==64)
{
left_pwm=80-2*flag;//可调试
right_pwm=28-7*flag;//可调试
delay(30);
flag++;
if(flag>=4)flag=4;
}
flag=0;
}
void sleft()
{
in1=1;
in2=0;
in3=1;
in4=0;
flag=0;
while(temp==32)
{
right_pwm=80-2*flag;//可调试
left_pwm=28-7*flag;//可调试
delay(30);
flag++;
if(flag>=4)flag=4;
}
flag=0;
}
void mright() //二次调节,减小左右摆动
{
in1=1;
in2=0;
in3=1;
in4=0;
flag=0;
while(temp==192)
{
left_pwm=100-4*flag;//可调试
right_pwm=50-3*flag;//可调试
delay(2);
flag++;
if(flag>=10)flag=10;
}
flag=0;
}
void mleft()
{
in1=1;
in2=0;
in3=1;
in4=0;
flag=0;
while(temp==48)
{
right_pwm=100-4*flag;//可调试
left_pwm=50-3*flag;//可调试
delay(2);
flag++;
if(flag>=10)flag=10;
}
flag=0;
}
void bright() //后退,防止小车脱离赛道
{
flag=0;
in3=0;
in4=1;
while(temp==128)
{
flag++;
if(flag<16)
{
left_pwm=60+1*flag;//可调试
right_pwm=0;//可调试
delay(6);
}
if(flag>=16)
{
left_pwm=35+(flag-17)^2;//可调试
right_pwm=3*(flag-15);//可调试
delay(10);
}
if(flag>=25)flag=25;
}
flag=0;
}
void bleft()
{
flag=0;
in1=0;
in2=1;
while(temp==16)
{
flag++;
if(flag<16)
{
right_pwm=60+1*flag;//可调试
left_pwm=0;//可调试
delay(6);
}
if(flag>=16)
{
right_pwm=35+(flag-17)^2;//可调试
left_pwm=3*(flag-15);//可调试
delay(10);
}
if(flag>=25)flag=25;
}
flag=0;
}
void expe() //接收到未知数据,保持原来方向
{
left_pwm=110;
right_pwm=110;
}
void stop() //停止
{
left_pwm=0;
right_pwm=0;
}
/**************************手机APP遥控函数*****************************************/
void bluetooth(void)
{
switch(buffer_data[2])
{
case 'A': forward1(80);forward2(80);break; //按下APP前进键
case 'B': back1(80);back2(80);break; //按下APP后退键
case 'C': back1(50);forward2(50);break; //按下APP左转键
case 'D': forward1(50);back2(50);break; //按下APP右转键
case 'F': forward1(0);forward2(0);break; //松手
case '1': flagxun=~flagxun;break; //按下1,进入循线状态
default : ;
}
}
/**************************循线函数*****************************************/
void xunji(void)
{
P3=0xff;
temp=P3;
temp=temp&0xf0;
P0=temp;
switch(temp) //左1 左2 右3 右4
{
case 0:mforw();break; //全都没检测到黑线,中速前进
case 16:bleft();break; //左1检测到黑线,高速左转
case 32:sleft();break; //左2检测到黑线,低速左转
case 64:sright();break; //右3检测到黑线,低速右转
case 128:bright();break; //右4检测到黑线,高速右转
case 96:sforw();break; //左2、右3检测到黑线,低速前进
case 48:mleft();break; //左1、左2检测到黑线,中速左转
case 192:mright();break; //右3、右4检测到黑线,中速右转
case 240:stop();break; //全都检测到黑线,停止
default :expe();break; //接收到未知数据,保持原来方向前进
}
}
/*************************主函数***************************************************/
void main(void)
{
com_init(); //四组IO口初始化
dian_init(); //电机初始化
timer_init(); //定时器初始化
led=0;
flagxun=0;
while(!flagxun)
{
if(recv_flag==1) //recv_flag==1表明3个字符全部接收完毕
{
recv_flag=0; //清空3个字符全部接收完毕标记位
bluetooth(); //手机APP遥控函数
}
while(flagxun)
xunji();
}
}
/**************************串口中断服务函数****************************************/
void Serial(void) interrupt 4 //中断接收3个字符
{
uchar temp_data; //temp_data用来存放接收到的字符
RI=0;
temp_data=SBUF;
if(temp_data=='O'&&(count_data==0)) //接收第一个字符串
{
buffer_data[count_data]=temp_data;
count_flag=1; //count_flag=1表示已经接收到第1个字符
}
else
{
if(count_flag==1) //开始接收第2、3个字符
{
count_data++;
buffer_data[count_data]=temp_data;
if(count_data>=2) //count_data=2,表明已经接收3个字符
{ //此时表明3个字符已接收完毕,开始执行遥控程序
count_data=0;
count_flag=0; //清空标记位
recv_flag=1 ; //数据接收完毕标记位
}
}
}
}
/*************************定时器中断函数*******************************************/
void Timer0(void) interrupt 1
{
pwm_data++;
if(pwm_data>PWM_CYCLE)
pwm_data=0;
if(pwm_data<=left_pwm)
ENA=1;
else
ENA=0;
if(pwm_data<=right_pwm)
ENB=1;
else
ENB=0;
P3=0xff;
temp=P3;
temp=temp&0xf0;
P0=temp;
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1