自动追光自动避障智能小车的源代码.docx
《自动追光自动避障智能小车的源代码.docx》由会员分享,可在线阅读,更多相关《自动追光自动避障智能小车的源代码.docx(32页珍藏版)》请在冰豆网上搜索。
自动追光自动避障智能小车的源代码
#include
#include
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
//停车
#definestop();{IN31=0;IN32=0;IN33=0;IN34=0;}
//后退
#defineback();{IN31=0;IN32=1;IN33=0;IN34=1;}
//前进
#definego();{IN31=1;IN32=0;IN33=1;IN34=0;}
//右轮前进实现左转
#defineleft_g();{IN31=0;IN32=0;IN33=1;IN34=0;}
//左轮前进实现右转
#defineright_g();{IN31=1;IN32=0;IN33=0;IN34=0;}
//左轮后退实现左转
#defineleft_b();{IN31=0;IN32=1;IN33=0;IN34=0;}
//右轮后退实现右转
#defineright_b();{IN31=0;IN32=0;IN33=0;IN34=1;}
sfrT2MOD=0xc9;
sbitP00=P0^0;//置0
sbitP01=P0^1;//置1
sbitP02=P0^2;//为1时正向追光,为0时逆向追光
sbitP03=P0^3;//为1时追自然光
sbitIN21=P0^4;//步进电机2输入端IN1,控制太阳能电池板
sbitIN22=P0^5;//步进电机2输入端IN2
sbitIN23=P0^6;//步进电机2输入端IN3
sbitIN24=P0^7;//步进电机2输入端IN4
sbitcs1=P1^0;//车头AD1片选
sbitcs2=P1^1;//车头AD2片选
sbitcs3=P1^2;//太阳能电池面板AD1片选
sbitcs4=P1^3;//太阳能电池面板AD1片选
sbitD0=P1^4;//检验码
sbitD1=P1^4;//电压值
sbitclk=P1^5;//AD时钟
sbitD10=P1^6;//检验码
sbitD11=P1^6;
sbitclk1=P1^7;//AD时钟
sbitIN31=P2^0;//直流电机输入端IN1
sbitIN32=P2^1;//直流电机输入端IN2
sbitIN33=P2^2;//直流电机输入端IN3
sbitIN34=P2^3;//直流电机输入端IN4
sbitleftTX=P2^4;//左超声波发射端
sbitMiddleTX=P2^5;//右超声波发射端
sbitrightTX=P2^6;//中间超声波发射端
sbitRX=P3^2;//超声波接收端口(外部中断0)
sbitleftControl=P3^4;//左侧超声波允许接收控制端
sbitMiddleControl=P3^5;//中间超声波允许接收控制端
sbitrightControl=P3^6;//右侧超声波允许接收控制端
charcodetaiyannengzheng[]={0x10,0x20,0x40,0x80};//太阳能电池板正转码
charcodetaiyannengfan[]={0x80,0x40,0x20,0x10};//太阳能电池板反转码
ucharch=0x03;//设置AD0832通道
ucharTX,a1,a2,a3,a4;//用于寄存4个AD转化值,a1,a2为车头两个AD值,a3,a4为太阳能充电板两个AD值
ucharnumber1=0;//用于计数500ms,太阳能板对光一次
uchardetector_busy=0;//超声波正在检测标志位
ucharbarrier_flag=0;//低三位用于表示是否有障碍物;第三位表示左侧探测器探测结果,第二位表示中间探测器探测结果,最低位表示右侧探测器探测结果;1-有,0-无
uchardetector=4;//4-左侧探测器,2-中间探测器,1-右侧探测器
uchardetector_inv=0xFB;//4-左侧探测器,2-中间探测器,1-右侧探测器
ucharObstacle_detection=1;//检测障碍物标志位,为1时,允许检测障碍
ucharObstacle_delay=0;//计时器3蔽障过程前进时间记录
ucharObstacle_control=0;//计时器3蔽障控制计时开始,结束
ucharallow_follow=1;//为1时,允许计时追光
ucharfollowstep=15;//为20时追光
ucharfollow=1;//为1时,允许小车追光
uchartime_0_count=1;//为0时为超声波1ms计时,为1时为超声波50ms定时检测计时
/***************延时子函数1us*******************/
voiddelay1us(uintt)
{
while(t--);
}
/***************延时子函数1ms*******************/
voiddelay1ms(uintz)
{
uchary;
while(z--)
{
for(y=0;y<120;y++);
}
}
/***************车头AD读数*******************/
ucharAD0832_1()//车头感光模块
{
uchardata_f,i,data_f1,i1,k;
/************读取车头第一个AD值**************/
D1=1;
cs1=1;
cs2=1;
cs3=1;
cs4=1;
_nop_();
_nop_();
_nop_();
cs1=0;
D1=1;//芯片使能之前的初始化。
第一个下降沿
clk=1;
_nop_();
_nop_();
_nop_();
clk=0;//确定通道模式、第2个下降沿
_nop_();
_nop_();
_nop_();
clk=1;
D1=1;//设定通道初始化
_nop_();
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
_nop_();
clk=1;
D1=1;//设定通道初始化.第3个下降沿
_nop_();
_nop_();
_nop_();
clk=0;//AD转化的初始化完成。
for(i=0;i<8;i++)//得到一个正常排序的8位数据
{
clk=1;
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
data_f<<=1;
data_f|=D0;
}
cs1=1;
a1=data_f;//将第一个AD值存储在a1中
/************读取车头第二个AD值**************/
D1=1;
cs1=1;
cs2=1;
cs3=1;
cs4=1;
_nop_();
_nop_();
_nop_();
cs2=0;
D1=1;//芯片使能之前的初始化。
第一个下降沿
clk=1;
_nop_();
_nop_();
_nop_();
clk=0;//确定通道模式、第2个下降沿
_nop_();
_nop_();
_nop_();
clk=1;
D1=1;//设定通道初始化
_nop_();
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
_nop_();
clk=1;
D1=1;//设定通道初始化.第3个下降沿
_nop_();
_nop_();
_nop_();
clk=0;//AD转化的初始化完成。
for(i1=0;i1<8;i1++)//得到一个正常排序的8位数据
{
clk=1;
_nop_();
_nop_();
clk=0;
_nop_();
_nop_();
data_f1<<=1;
data_f1|=D0;
}
cs2=1;
a2=data_f1;//将第二个AD值存储在a2中
k=abs(a1-a2);
returnk;
}
/***************太阳能充电板AD读数*******************/
ucharAD0832_2(void)//太阳能充电板感光模块
{
uchardata_f,i,data_f1,i1,k1;
/************读取太阳能电池板第一个AD值**************/
D11=1;
cs1=1;
cs2=1;
cs3=1;
cs4=1;
_nop_();
_nop_();
_nop_();
cs3=0;
D11=1;//芯片使能之前的初始化。
第一个下降沿
clk1=1;
_nop_();
_nop_();
_nop_();
clk1=0;//确定通道模式、第2个下降沿
_nop_();
_nop_();
_nop_();
clk1=1;
D11=1;//设定通道初始化
_nop_();
_nop_();
_nop_();
clk1=0;
_nop_();
_nop_();
_nop_();
clk1=1;
D11=1;//设定通道初始化.第3个下降沿
_nop_();
_nop_();
_nop_();
clk1=0;//AD转化的初始化完成。
for(i=0;i<8;i++)//得到一个正常排序的8位数据
{
clk1=1;
_nop_();
_nop_();
clk1=0;
_nop_();
data_f<<=1;
data_f|=D10;
}
cs3=1;
a3=data_f;//将第一个AD值存储在a1中
/************读取太阳能电池板第二个AD值**************/
D11=1;
cs1=1;
cs2=1;
cs3=1;
cs4=1;
_nop_();
_nop_();
_nop_();
cs4=0;
D11=1;//芯片使能之前的初始化。
第一个下降沿
clk1=1;
_nop_();
_nop_();
_nop_();
clk1=0;//确定通道模式、第2个下降沿
_nop_();
_nop_();
_nop_();
clk1=1;
D11=1;//设定通道初始化
_nop_();
_nop_();
_nop_();
clk1=0;
_nop_();
_nop_();
_nop_();
clk1=1;
D11=1;//设定通道初始化.第3个下降沿
_nop_();
_nop_();
_nop_();
clk1=0;//AD转化的初始化完成。
for(i1=0;i1<8;i1++)//得到一个正常排序的8位数据
{
clk1=1;
_nop_();
_nop_();
clk1=0;
_nop_();
_nop_();
data_f1<<=1;
data_f1|=D10;
}
cs4=1;
a4=data_f1;//将第二个AD值存储在a2中
k1=abs(a4-a3);
returnk1;
}
//*********从左向右检测,检测10cm之内的障碍物*************//
voidbarrier_detection(void)
{
uchari;
barrier_flag=0;
detector=4;
time_0_count=0;//定时器0工作在15cm障碍物检测
while(detector)
{
EX0=0;//关外部中断
IE0=0;//清除外部中断0标志位
TR0=0;//关闭定时器0
TH0=0xfc;
TL0=0x18;
leftTX=1;
MiddleTX=1;
rightTX=1;
switch(detector)
{
case4:
leftControl=1;MiddleControl=0;rightControl=0;
for(i=0;i<16;i++)
{
leftTX=!
leftTX;
}
break;//左侧超声波发波
case2:
leftControl=0;MiddleControl=1;rightControl=0;
for(i=0;i<16;i++)
{
MiddleTX=!
MiddleTX;
}
break;//中间超声波发波
case1:
leftControl=0;MiddleControl=0;rightControl=1;
for(i=0;i<16;i++)
{
rightTX=!
rightTX;
}
break;//右侧超声波发波
default:
break;
}
TR0=1;//定时器0开始计时
detector_busy=1;//超声波正在检测中....
_nop_();
_nop_();
_nop_();
IE0=0;//清除外部中断0标志位
EX0=1;//开外部中断;
while(detector_busy);//等待超声波检测障碍物完成
detector>>=1;
delay1ms(10);
}
EX0=0;//关闭外部中断
TR0=0;//关闭定时器1
TH0=0x3c;
TL0=0xb0;
time_0_count=1;//定时器0工作在定时50ms障碍物检测
TR0=1;//打开计数器1,65MS检测障碍
leftControl=0;
MiddleControl=0;
rightControl=0;
}
/*************太阳能面板步进电机左转n度*********************/
voidleft2(ucharStep3)
{
uchari;
while(Step3)
{
for(i=0;i<4;i++)
{
P0=taiyannengzheng[i];
delay1us(350);
}
Step3--;
}
}
/*************太阳能面板步进电机右转n度*********************/
voidright2(ucharStep4)
{
uchari;
while(Step4)
{
for(i=0;i<4;i++)
{
P0=taiyannengfan[i];
delay1us(350);
}
Step4--;
}
}
/*******************小车追光****************/
voidzhuiguang()
{
uchark;
k=AD0832_1();
if((P02==0)&&(P03==0))//追白炽灯
{
if((a1>210)&&(a2>210))
{
left_g();
delay1ms(300);
}
else
{
while(k>2)
{
if(a1>a2)
{
right_g();
delay1ms(10);
go();
}
if(a1{
left_g();
delay1ms(10);
go();
}
k=AD0832_1();
}
}
}
if((P02==0)&&(P03==1))//逆白炽灯
{
if((a1<210)&&(a2<210))
{
left_g();
delay1ms(300);
}
else
{
while(k>3)
{
if(a1{
right_g();
delay1ms(10);
go();
}
if(a1>a2)
{
left_g();
delay1ms(10);
go();
}
k=AD0832_1();
}
}
}
if((P02==1)&&(P03==0))//追白炽灯
{
if((a1>210)&&(a2>210))
{
left_g();
delay1ms(300);
}
else
{
while(k>2)
{
if(a1>a2)
{
right_g();
delay1ms(10);
go();
barrier_detection();//检测障碍物情况函数
}
if(a1{
left_g();
delay1ms(10);
go();
barrier_detection();//检测障碍物情况函数
}
k=AD0832_1();
}
}
}
}
/*******************太阳能板对光****************/
voidduiguang()
{
uchark1;
uintstep;
k1=AD0832_2();
if(k1>3)
{
if(a3>a4)
{
if(k1>20)
{
right2(8);
}
else
{
right2(4);
}
}
if(a3{
if(k1>20)
{
left2(8);
}
else
{
left2
(2);
}
}
}
}
/************************小车避障程序*************************/
//标志值障碍物避障方案
//barrier_flag=0x00无无
//barrier_flag=0x04左侧barrier_left()
//barrier_flag=0x06偏左barrier_left_centre()
//barrier_flag=0x07正中barrier_centre_slope()
//barrier_flag=0x02正中barrier_centre()
//barrier_flag=0x03偏右barrier_right_centre()
//barrier_flag=0x01右侧barrier_right()
//这里实现相应的6个转弯子函数
voidbarrier_left()
{
right_g();//转60度
Obstacle_control=1;//定时器2开始600ms延时计时
while(Obstacle_delay<8)//定时器2结束600ms延时计时
{
duiguang();
}
Obstacle_control=0;//定时器2禁止延时计时
Obstacle_delay=0;//置0供下次计时使用
stop();
barrier_detection();//检测障碍物情况函数
if(barrier_flag==0)
{
go();//前进20cm
Obstacle_control=1;//定时器2开始300ms延时计时
while(Obstacle_delay<6)//定时器2结束300ms延时计时
{
duiguang();
}
Obstacle_control=0;//定时器2禁止延时计时
Obstacle_delay=0;//置0供下次计时使用
stop();
barrier_detection();//检测障碍物情况函数
}
if(barrier_flag==0)
{
left_g();//转60度
Obstacle_control=1;//定时器2开始950ms延时计时
while(Obstacle_delay<12)//定时器2结束950ms延时计时
{
duiguang();
}
Obstacle_control=0;//定时器2禁止延时计时
Obstacle_delay=0;//置0供下次计时使用
stop();
}
}
voidbarrier_right()
{
left_g();//转60度
Obstacle_control=1;//定时器2开始700ms延时计时
while(Obstacle_delay<10)//定时器2结束700ms延时计时
{
duiguang();
}
Obstacle_control=0;//定时器2禁止延时计时
Obstacle_delay=0;//置0供下次计时使用
stop();
barrier_detection();//检测障碍物情况函数
if(barrier_flag==0)
{
go();//前进20cm
Obstacle_control=1;//定时器2开始300ms延时计时
while(Obstacle_delay<6)//定时器2结束300ms延时计时
{
duiguang();
}
Obstacle_control=0;//定时器2禁止延时计时
Obstacle_delay=0;//置0供下次计时使用