智能小车循迹避障红外遥控C语言知识学习代码Word下载.docx
《智能小车循迹避障红外遥控C语言知识学习代码Word下载.docx》由会员分享,可在线阅读,更多相关《智能小车循迹避障红外遥控C语言知识学习代码Word下载.docx(18页珍藏版)》请在冰豆网上搜索。
//红外扫描标志位
uchartime_1=0,time_2=0;
//定时器1中断全局变量time_2控制PWM脉冲计数time_1控制转弯延时计数也做延时一次0.005s
uchartime,timeH,timeL,state=0;
//超声波测量缓冲变量state为超声波状态检测控制全局变量
uintcount=0;
//1602显示计数
/**************************/
unsignedcharIRCOM[7];
//红外接收头接收数据缓存IRCOM[2]存放的为数据
unsignedcharNumber,distance[4],date_data[8]={0,0,0,0,0,0,0,0};
//红外接收缓存变量
/***********/
voidIRdelay(charx);
//x*0.14MS红外头专用delay
voidrun();
voidback();
voidstop();
voidleft_90();
voidleft_180();
voidright_90();
voiddelay(uintdat);
//
voidinit_test();
voiddelay_100ms(uintms);
voiddisplay(uchartemp);
//超声波显示驱动
voidbizhang_test();
voidxunji_test();
voidhongwai_test();
voidDelay10ms(void);
voidinit_test()//定时器01外部中断01延时初始化
{
TMOD=0x11;
//设置定时器01工作方式116位初值定时器
TH1=0Xfe;
//装入初值定时一次为0.0005s2000hz
TL1=0x0c;
TF0=0;
//定时器0方式1计数溢出标志
TF1=0;
//定时器1方式1计数溢出标志
ET0=1;
//允许定时器0中断溢出
ET1=1;
//允许定时器1中断溢出
EA=1;
//开总中断
if(state_total==1)//为超声波模块时初始化
TRIG=0;
//发射引脚低电平
ECHO=0;
//接收引脚低电平
EX0=0;
//关闭外部中断
IT0=1;
//由高电平变低电平,触发外部中断0
}
if(state_total==2)//红外遥控初始化
{IT1=1;
//外部中断1为负跳变触发
EX1=1;
//允许外部中断1
TRIG=1;
//3.3为高电平I/O口初始化
}
delay(60);
//等待硬件操作
}
voidmain()
{uinti;
delay(50);
init_test();
TR1=1;
//开启定时器1
LCD1602_Init();
while(state_2==0)
{
if(KEY1==0)//检测按键s1是否按下
{
Delay10ms();
//消除抖动
if(KEY1==0)
{
state_total=0;
//总状态定义0为自动循迹模块1为自动避障模块2为红外遥控
while((i<
30)&
&
(KEY1==0))//检测按键是否松开
{
Delay10ms();
i++;
}
i=0;
}
}
if(TRIG==0)//检测按键s2是否按下
if(TRIG==0)
{
state_total=1;
//总状态定义0为自动循迹模块1为自动避障模块2为红外遥控
(TRIG==0))//检测按键是否松开
if(KEY2==0)//检测按键s3是否按下
if(KEY2==0)
state_total=2;
(KEY2==0))//检测按键是否松开
//等待硬件操作50us
TR1=0;
//关闭定时器1
if(state_total==1)
//SPEED=90;
//自动循迹速度控制高电平持续次数占空比为10的低电平
bizhang_test();
if(state_total==0)
//SPEED=98;
//自动循迹速度控制高电平持续次数占空比为40的低电平
xunji_test();
if(state_total==2)
//SPEED=98;
hongwai_test();
}
voidinit0_suspend(void)interrupt0//3为定时器1的中断号1定时器0的中断号0外部中断12外部中断04串口中断
timeH=TH0;
//记录高电平次数
timeL=TL0;
state=1;
//标志状态为1,表示已接收到返回信号
EX0=0;
//关闭外部中断0
voidtime0_suspend0(void)interrupt1//3为定时器1的中断号1定时器0的中断号0外部中断12外部中断04串口中断
if(state_total==1)//自动避障初值装入
{TH0=0X00;
//装入初值
TL0=0x00;
if(state_total==0)//自动循迹初值装入
{TH0=0Xec;
//装入初值定时一次0.005s200hz
TL0=0x78;
time_1++;
//控制转弯延时计数
voidIR_IN(void)interrupt2
{
unsignedcharj,k,N=0;
EX1=0;
IRdelay(5);
if(TRIG==1)
{EX1=1;
return;
//确认IR信号出现
while(!
TRIG)//等IR变为高电平,跳过9ms的前导低电平信号。
{IRdelay
(1);
for(j=0;
j<
4;
j++)//收集四组数据
for(k=0;
k<
8;
k++)//每组数据有8位
while(TRIG)//等IR变为低电平,跳过4.5ms的前导高电平信号。
TRIG)//等IR变为高电平
while(TRIG)//计算IR高电平时长
IRdelay
(1);
N++;
if(N>
=30)
{EX1=1;
return;
}//0.14ms计数过长自动离开。
}//高电平计数完毕
IRCOM[j]=IRCOM[j]>
>
1;
//数据最高位补“0”
if(N>
=8){IRCOM[j]=IRCOM[j]|0x80;
}//数据最高位补“1”
N=0;
}//endfork
}//endforj
if(IRCOM[2]!
=~IRCOM[3])//判断数据码与数据反码是否正确真确返回
{EX1=1;
EX1=1;
voidtime1_suspend1(void)interrupt3//3为定时器1的中断号1定时器0的中断号0外部中断12外部中断04串口中断
TH1=0Xec;
//装入初值定时一次为0.0005s2000hz
TL1=0x78;
time_2++;
//控制PWM脉冲计数
if(state_total!
=3)//判断进入按键是否按下进入状态1避障或者0循迹
state_2=1;
//退出按键判断
/*if(time_2>
100)
time_2=0;
elseif(time_2<
=SPEED)
PWM_g;
//频率为2000hz的占空比为高电平的方波
else
{PWM_l;
//为低电平
}*/
voidIRdelay(unsignedcharx)//x*0.14MS用于红外遥控
unsignedchari;
while(x--)
for(i=0;
i<
13;
i++){}
voidDelay10ms(void)//用于按键检测误差
unsignedchara,b,c;
for(c=1;
c>
0;
c--)
for(b=38;
b>
b--)
for(a=130;
a>
a--);
voiddelay(uintdat)//延时函数用于初始化
uinti;
for(i=dat;
i>
i--)
_nop_();
voiddelay_100ms(uintms)//延时函数用于超声波
uinti,j;
for(i=ms;
for(j=200;
j>
j--)
//小车前进
voidrun(void)
{
PWM=0X56;
//小车后退
voidback(void)
PWM=0XA9;
TR1=1;
while(time_2<
=100);
//延时0.2s
//小车停止
voidstop(void)
PWM=0X00;
//小车左转180
voidleft_180()
//PWM=0X59;
//左两轮反转,右两轮正转
PWM=0X50;
//右两轮正转
=150);
//小车左转90
voidleft_90(void)
PWM=0X59;
//PWM=0X50;
TR0=1;
time_1=0;
while(time_1<
=20);
TR0=0;
//小车左转120
voidleft_120(void)
//PWM=0X50;
while(time_1<
=60);
//延时0.4s
//小车右转90
voidright_90(void)
PWM=0XA6;
//左两轮正转右两轮反转
//PWM=0X06;
//左两轮正转
TR0=1;
//小车右转120
voidright_120(void)
//PWM=0X06;
/************************************
自动避障模块
************************************/
voiddisplay(uchartemp)//判断障碍距离小车的距离,左转180,前进,峰呤器报警1602显示
{uintge,shi,bai,i;
if((temp<
=20)&
(temp>
2))//小于15厘米小车后退再左转
back();
left_180();
if(count>
=20)
{bai=temp/100;
//1602显示数据
date_data[5]=bai;
shi=(temp%100)/10;
date_data[6]=shi;
ge=temp%100%10;
date_data[7]=ge;
for(i=0;
i<
i++)
LCD1602_WriteCom(0x80+i);
LCD1602_WriteData(date_data[i]+48);
count=0;
voidbizhang_test()
{inti,j=0;
uchardistance_dat;
{
LCD1602_WriteData(ENCHAR_PuZh7[i]);
while
(1)
run();
EA=0;
//关总中断
TRIG=1;
//发射20us脉冲信号
delay(30);
TRIG=0;
while(ECHO==0);
//等待接收信号
state=0;
//标志清零
EA=1;
//开总中断
EX0=1;
//打开外部中断0P3.2外部中断0引脚此时为高电平
TH0=0x00;
//定时器0初值
TL0=0x00;
TF0=0;
//定时器0方式1计数溢出标志
//定时器0方式1启动定时器1
while(state!
=1);
EX0=0;
//关闭外部中断0
TR0=0;
//关闭定时器0中断
//定时器1方式1计数溢出标志
if(state==1)//检测到障碍物计算离障碍物的距离
time=(timeH*4.352+timeL*0.017);
//设定超声波的速度为340m/s定时计数一次1us
distance_dat=time;
else//未检测到障碍物无返回信号
distance_dat=0;
distance[j]=distance_dat;
j++;
if(j==3)
{if(distance[0]>
distance[1])
{}
else
distance[0]=distance[1];
if(distance[0]>
distance[2])
{}
else
distance[0]=distance[2];
if(distance[0]>
distance[3])
distance[0]=distance[3];
distance_dat=distance[0];
j=0;
display(distance_dat);
}
count++;
voidxunji_test()
{inti;
LCD1602_WriteCom(0x80+i);
LCD1602_WriteData(ENCHAR_PuZh6[i]);
while
(1)
//delay(10);
state_1=HW;
DAT=state_1&
(0x0f);
//判断低4位的状态每隔5ms检测一次
switch(DAT)
{
case0x00:
run();
break;
case0x01:
right_120();
case0x02:
right_90();
case0x04:
left_90();
break;
case0x06:
case0x03:
case0x08:
left_120();
case0x0c:
left_120();
default:
voidhongwai_test()
{inti;
for(i=0;
LCD1602_WriteData(ENCHAR_PuZh8[i]);
//TR1=1;
Number=IRCOM[2];
switch(Number)
case0x18:
PWM=0X56;
//前进
for(i=0;
LCD1602_WriteData(ENCHAR_PuZh1[i]);
case0x08:
PWM=0X50;
//右两轮正转左转
for(i=0;
LCD1602_WriteData(ENCHAR_PuZh4[i]);
case0x1c:
PWM=0X00;
LCD1602_WriteData(ENCHAR_PuZh3[i]);
break;
case0x5a:
PWM=0X06;
//左两轮正转右转
LCD1602_WriteData(ENCHAR_PuZh5[i]);
case0x52:
PWM=0XA9;
//后退
LCD1602_WriteData(ENCHAR_PuZh2[i]);
default:
break;
}//display(IRCOM[2]);