红外遥控小车,可以使用红外遥控在一定范围内操控小车前进、后退、左转、右转,还可以控制小车上的各种外设…
红外遥控小车的实现主要靠的是红外信号的传递,小车接收到红外信号后经过解码会得到具体的数值,小车再依据相应的数值来执行相对应的操作。
遥控小车主要有俩个模块:
- 红外接收模块
- 电机驱动模块
红外接收模块
小车上安有红外接收装置,红外接收装置负责将接收到红外遥控器的信号进行解码,小车依据相应的命令进行操作,有关于红外遥控的相关操作以及如何解码博主在之前的博客中有详细介绍,链接:红外通信
利用中断来接收红外信号,接收到信号后在中断函数中处理,下面的是中断的配置函数(初始化):
sbit IR=P3^2;
/* 配置中断 */
void init() //初始化
{
IT0=0;
EX0=1;
EA=1;
IR=1; //相当于打开外部中断0 此处意义为红外接收器打开
}
接收到中断(红外信号)后就进入中断函数中解码信号:
void hhh() interrupt 0 //执行中断:进行读取信号 最后产生键值
{
uint i,j,k;
dy1(700);
if(IR==0)
{
k=1000;
while(IR==0&&(k>0)) //通过此while来实现计时
{
dy1(1);
k--;
}
if(IR==1)
{
k=500;
while(IR==1&&(k>0)) //检测初始高电平
{
dy1(1);
k--;
}
for(i=0;i<4;i++) //开始读取用户码和操作码和操作反码
{
for(j=0;j<8;j++)
{
if(IR==0)
{
k=70;
while(IR==0&&(k>0))
{
k--;
dy1(1);
}
}
if(IR==1)
{
time=0;
k=500;
while(IR==1&&k>0)
{
dy1(10);
time++;
k--;
}
if(time>30) return ;
irdata[i]>>=1; //移位运算,空出最高为为下一次采集做准备
if(time>=8) //高电平---或运算0x80给最高位(j位)赋1
irdata[i]|=0x80;
time=0;
}
}
}
}
if(irdata[2]!=~irdata[3])
return;
}
switch(irdata[2])
{
case 0x16:jz=0;break;
case 0x0c:jz=1;break;
case 0x18:jz=2;break;
case 0x5e:jz=3;break;
case 0x08:jz=4;break;
case 0x1c:jz=5;break;
case 0x5a:jz=6;break;
case 0x42:jz=7;break;
case 0x52:jz=8;break;
case 0x4a:jz=9;break;
case 0x45:jz=10;break;
default:break;
}
jy=jz;
}
jy是定义的全局变量,用来返回红外信号的解码值,程序就是依靠这个全局变量来控制小车的。有关代码的具体讲解博主已经在之前的红外通信文章中讲过了,此处不再累赘叙述。
电机模块
剩下的就是电机驱动了,有关电机模块的相关内容在另一篇博客中有详细叙述,链接:电机
此处的不同就是使用了switch语句,根据不同的红外信号执行相应的操作了,代码如下:
void dy(uint x) //一组循环约为0.1秒
{
uint i,j;
for(i=0;i<x;i++)
for(j=11400;j>0;j--)
;
}
void car_advance(uint x)
{
left_en=1;
right_en=1;
left_advance=1;
left_back=0;
right_advance=1;
right_back=0;
dy(x);
}
void car_back(uint x)
{
left_en=1;
right_en=1;
left_back=1;
left_advance=0;
right_back=1;
right_advance=0;
dy(x);
}
void car_left(uint x) //为什么左转时只有right_back=0 其余的都为1?
{
left_en=0;
right_en=1;
left_advance=1;
left_back=1;
right_advance=1;
right_back=0;
dy(x);
}
void car_right(uint x)
{
left_en=1;
right_en=0;
left_advance=1;
left_back=0;
right_advance=0;
right_back=0;
dy(x);
}
void car_stop(uint x)
{
left_en=0;
right_en=0;
dy(x);
}
void main()
{
init();
while(1)
{
while(jy==jz)
{
switch(jz)
{
case 2:car_advance(3);break;
case 8:car_back(3);break;
case 4:car_left(3);break;
case 6:car_right(3);break;
case 5:car_stop(3);break;
}
jy--;
}
}
}