基于51单片机的无线遥控小车.docx
《基于51单片机的无线遥控小车.docx》由会员分享,可在线阅读,更多相关《基于51单片机的无线遥控小车.docx(40页珍藏版)》请在冰豆网上搜索。
![基于51单片机的无线遥控小车.docx](https://file1.bdocx.com/fileroot1/2023-5/24/d66c0e57-7ebe-44b1-b756-0793a9f2fb35/d66c0e57-7ebe-44b1-b756-0793a9f2fb351.gif)
基于51单片机的无线遥控小车
摘要
智能小车利用单片机STC10F08XE作为控制核心,使用红外线发射和接收器件、接近反射式光电感应器件、编码解码芯片和无线收发模块,实现智能小车的红外探测避障以及循迹功能,遥控小车的运动轨迹,用单片机输入/输出接口控制伺服电机方向、速度和运行时间,模块化结构保证了小车成为一个可靠整体,软件采用C语言编程,完成小车所要实现的功能。
关键词:
单片机STC10F08XE红外避障循迹遥控伺服电机
第一章:
智能小车总体设计结构及硬件模块设计
1.1总体设计结构
1.2智能小车硬件模块
第二章:
智能小车各模块电路设计
2.1红外避障模块
2.1.1检测原理
2.1.2红外检测原理图
2.1.3测试红外发射探测器
2.1.4红外避障程序
2.2循迹模块
2.2.1循迹原理
2.2.2循迹原理图
2.2.3小车的循迹程序
2.2.4红外避障及循迹程序流程图
2.2.5红外避障及循迹程序程序代码
2.3无线遥控模块
2.3.1无线遥控原理
2.3.2.PT2262/2272编码解码集成电路
2.3.3T10A发射模块
2.3.4XY-R04A接收模块
2.3.5无线遥控原理图
2.3.6无线遥控控制程序
第一章:
智能小车总体设计结构及硬件模块设计
1.1总体设计结构
智能小车采用STC单片机集中控制和分散模块化设计。
智能小车硬件由STC单片机开发板,红外检测模块组、轨迹检测模块以及无线遥控模块组成,智能小车采用左右两个伺服电机,高电平持续的时间控制电机运动转速。
智能车前下端4组检测灯对黑线的反馈信号,通过单片机控制伺服电机的转动。
前端的两组红外检测灯对障碍物进行检测,通过单片机P2口的低四位对遥控信号进行检测。
小车的机械结构设计:
为了保证小车能够进行循迹,同时避免外界光的干扰,我们将道路检测电路板放在小车底盘的前端,红外避障模块放在小车的前部,无线接收模块放在小车的尾部,单片机控制板放在小车的正上方保持小车的平衡性,小车的主动轮为前端两个,从动轮为后面一个,电池放在两个主动轮之间,这样的整体设计既可以保持重心尽量在一条竖直线上又方便电源的开关,使小车转弯时的转动惯量减小,增强其稳定性。
1.2智能小车硬件模块
智能小车主要机构——从侧面观察各板的排列。
各个模块附图如下:
红外避障模块
红外循迹模块
遥控发射端
无线遥控接收端
第二章:
智能小车各模块电路设计
电路的设计包括三个模块:
红外避障模块,红外循迹模块,无线遥控模块
2.1红外避障模块
2.1.1检测原理
红外线二极管发射红外光,如果机器人前面有障碍物,红外线从物体反射回来,相当于机器人眼睛的红外检测(接收)器,检测到反射回的红外光线,并发出信号来表明检测到从物体反射回红外线。
51单片机基于这个传感器的输入控制伺服电机。
红外线(IR)接收/检测器有内置的光滤波器,除了需要检测的980nm波长的红外线外,它几乎不允许其它光通过。
红外检测器还有一个电子滤波器,它只允许大约38.5kHz的电信号通过。
换句话说,检测器只接收每秒闪烁38,500次的红外光。
这就防止了普通光源象太阳光和室内光对IR的干涉。
太阳光是直流干涉(0Hz)源,而室内光依赖于所在区域的主电源,闪烁频率接近100或120Hz。
由于120Hz在电子滤波器的38.5kHz通带频率之外,它完全被IR探测器忽略。
一组红外光电传感器包括有一个发射管和一个接收管。
当发射管照射到障碍物时,大部分红外光都会返回给接收管,接收管输出为低电平;反之,当红外发射管前方无障碍物时,光线几乎没有被返回,那么接收管就不会接收到足够反射回来的光线,接收管输出高电平。
输出的高低电平经IO口接入STC中,再通过程序的控制,使得小车作出相应的动作。
2.1.2红外检测原理图
元件清单:
(1)两个1938(红外探测器)
(2)两个EL-1L1(红外LED)
(3)四个470Ω电阻
(4)两个9013三极管
说明:
因为STC的IO驱动能力较弱,这里我们加入三极管使其工作在开关状态来增强驱动能力。
本任务中用
到的是NPN型三极管9013,当单片机的IO口输出高电平时,三极管导通,IRLED可发出红外光;反之,当IO口输出低电平时,三极管截止,IRLED不能发射红外光。
2.1.3红外发射探测器应用
应用说明
让每个IRLED探测器组工作的关键是发送1毫秒频率为38.5kHz的红外信号,然后立刻将IR探测器的输出存储到一个变量中。
可以给P1_3输出的信号高电平13微秒,低电平为13微秒,总周期为26微秒,即频率约为38.5kHz。
当没有红外信号返回时,探测器的输出状态为高。
当它探测到被物体反射的38500Hz红外信号时,它的输出为低。
因红外信号发送的持续时间为1毫秒,因此IR探测器的输出如果处于低,其持续状态也不会超过1毫秒,因此发送完信号后必须立即将IR探测器的输出存储到变量中。
这些存储的值即可表示前方是否有障碍物。
由此,可以实现智能小车的红外避障功能。
电路测试程序如下:
#include
voiddelay_nus(unsignedinti)//延时,单片机为STC10F08XE
{
i=i*10/12;
while(--i);
}
voidHardware_delay_1ms(void)
{
TMOD&=0xF0;
TMOD|=0x01;//T0--16位定时器器模
TH0=0xFC;
TL0=0x18;//64536
TF0=0;//清除定时器溢出标志
TR0=1;//启动定时器
while(TF0==0);//等待计数完成
TR0=0;//停止定时器
}
voiddelay_nms(intn)
{
intj;
for(j=n;j>0;j--)
Hardware_delay_1ms();
}
intP3_5state(void)
{
return(P3&0x20)?
1:
0;//返回P1_2的状态
}
intmain(void)
{
intcounter;
intirDetectLeft;
uart_Init();//串口初始化
printf("ProgramRunning!
\n");
while
(1)
{
for(counter=0;counter<38;counter++)
{
P2_3=1;//红外发射约38.5kHz的红外光
delay_nus(13);
P2_3=0;
delay_nus(13);
}
irDetectLeft=P3_5state();//将返回的状态给irDetectLeft
printf("irDetectLeft=%d\n",irDetectLeft);
delay_nms(100);
}
}
说明:
●保持机器人与串口线的连接;
●在红外检测电路前放一个物体,比如手或一张纸,距离左侧IR组大约2到3厘米;
●当放一个物体在IR组前时,串口调试助手会显示“irDetecfLeft=0”,将物体移开时,它会显示“irDetectLeft=1”;
●调整红外检测器的角度,尽量使其与地面垂直;
测试的结果如下图示:
测试结果
2.1.4红外避障程序
#include
#defineLeftIRP1_2//左边红外接收连接到P1_2
#defineRightIRP3_5//右边红外接收连接到P3_5
#defineLeftLaunchP1_3//左边红外发射连接到P1_3
#defineRightLaunchP3_6//右边红外发射连接到P3_6
voiddelay_nus(unsignedinti)
{
i=i*10/12;
while(--i);
}
voidHardware_delay_1ms(void)
{
TMOD&=0xF0;
TMOD|=0x01;//T0——16位定时器器模
TH0=0xFC;
TL0=0x18;//64536
TF0=0;//清除定时器溢出标志
TR0=1;//启动定时器
while(TF0==0);//等待计数完成
TR0=0;//停止定时器
}
voiddelay_nms(intn)//延时ms
{
intj;
for(j=n;j>0;j--)
Hardware_delay_1ms();
}
voidIRLaunch(unsignedcharIR)
{
intcounter;
if(IR=='L')//左边发射
for(counter=0;counter<38;counter++)
{
LeftLaunch=1;
delay_nus(13);
LeftLaunch=0;
delay_nus(13);
}
if(IR=='R')//右边发射
for(counter=0;counter<38;counter++)
{
RightLaunch=1;
delay_nus(13);
RightLaunch=0;
delay_nus(13);
}
}
voidForward(void)//向前行走子程序
{
P1_1=1;
delay_nus(1700);
P1_1=0;
P1_0=1;
delay_nus(1300);
P1_0=0;
delay_nms(20);
}
voidLeft_Turn(void)//左转子程序
{
inti;
for(i=1;i<=23;i++)
{
P1_1=1;
delay_nus(1300);
P1_1=0;
P1_0=1;
delay_nus(1300);
P1_0=0;
delay_nms(20);
}
}
voidRight_Turn(void)//右转子程序
{
inti;
for(i=1;i<=23;i++)
{
P1_1=1;
delay_nus(1700);
P1_1=0;
P1_0=1;
delay_nus(1700);
P1_0=0;
delay_nms(20);
}
}
voidBackward(void)//向后行走子程序
{
inti;
for(i=1;i<=65;i++)
{
P1_1=1;
delay_nus(1300);
P1_1=0;
P1_0=1;
delay_nus(1700);
P1_0=0;
delay_nms(20);
}
}
intmain(void)
{
intirDetectLeft,irDetectRight;
uart_Init();
printf("ProgramRunning!
\n");
while
(1)
{
IRLaunch('R');//右边发射
irDetectRight=RightIR;//右边接收
IRLaunch('L');//左边发射
irDetectLeft=LeftIR;//左边接收
if((irDetectLeft==0)&&(irDetectRight==0))//同时接到红外线
{
Backward();
Left_Turn();
Left_Turn();
}
elseif(irDetectLeft==0)//只有左边接收到红外线
{
Backward();
Right_Turn();
}
elseif(irDetectRight==0)//只有右边接收到红外线
{
Backward();
Left_Turn();
}
else
Forward();
}
}
2.2红外循迹模块
2.2.1循迹原理
接近反射式光电感应器件RPR220由一个红外线发射二极管和一个光电二极管组成,可以发射并检测到反射回的光线。
由于不同颜色的物体对光的反射率不同,当RPR220对准黑色物体时,黑色对光线反射率低,光电二极管接收到的反射光很少,不能导通,输出高电平;反之,当RPR220对准白色物体时,输出低电平。
故而可以利用RPR220区分出黑色跑道与白色跑道边缘,STC单片机可基于返回的信号控制伺服电机,从而控制小车的行进。
2.2.2循迹原理图
元件清单
(1)四个RPR220
(2)100Ω、2K、10K电阻各四个
(3)四个10K滑动变阻器
(4)LM339芯片
说明:
●安装时需要注意将焊有RPR220的电路板安装到小车的底部,并将RPR220对准地面,增强反射光的强度,同时可遮挡外界光;
●可将RPR220用纸壳或别的物体包起来,防止外界光的干扰;
●将ENTER与单片机的数据输入口相连,以将信息返回给单片机;
●接收管集电极输出接入比较器339正极,比较器负极则为滑动变阻器的输出,将滑动变阻器的电位调节到合适的大小,当正极高于负极时,比较器输出5V高电平,否则为0V低电平。
比较器输出则接入STC,单片机通过返回的信息判断小车是否处于跑道区域内并做出相应的反应。
2.2.3小车的循迹程序
#include
#defineLD1P1_2;//左左检测灯
#defineLD2P1_3;//中左检测灯
#defineRD1P3_5;//中右检测灯
#defineRD2P3_6;//右右检测灯
voiddelay_nus(unsignedinti)
{
i=i*10/12;
while(--i);
}
voidHardware_delay_1ms(void)
{
TMOD&=0xF0;
TMOD|=0x01;//T0——16位定时器器模
TH0=0xFC;
TL0=0x18;//64536
TF0=0;//清除定时器溢出标志
TR0=1;//启动定时器
while(TF0==0);//等待计数完成
TR0=0;//停止定时器
}
voiddelay_nms(intn)
{
intj;
for(j=n;j>0;j--)
Hardware_delay_1ms();
}
voidForward(void)//向前行走子程序
{
P1_1=1;
delay_nus(1440);
P1_1=0;
P1_0=1;
delay_nus(1400);
P1_0=0;
delay_nms(20);
}
voidLeft_Turn(void)//左转子程序
{
inti;
for(i=1;i<=15;i++)
{
P1_1=1;
delay_nus(1420);
P1_1=0;
P1_0=1;
delay_nus(1400);
P1_0=0;
delay_nms(20);
}
}
voidRight_Turn(void)//右转子程序
{
inti;
for(i=1;i<=15;i++)
{
P1_1=1;
delay_nus(1440);
P1_1=0;
P1_0=1;
delay_nus(1420);
P1_0=0;
delay_nms(20);
}
}
voidBackward(void)//向后行走子程序
{
inti;
for(i=1;i<=65;i++)
{
P1_1=1;
delay_nus(1400);
P1_1=0;
P1_0=1;
delay_nus(1440);
P1_0=0;
delay_nms(20);
}
}
intmain()
{
intL1,L2,R1,R2;
uart_Init();
printf("ProgramRunning!
\n");
while
(1)
{
L1=LD1;
L2=LD2;
R1=RD1;
R2=RD2;
if((L1==1)&&(R2==0))
//左灯检测到黑色右灯检测到白色左转
{
Left_Turn();
}
elseif((L1==0)&&(R2==1))
//左灯检测到白色右灯检测到黑色右转
{
Right_Turn();
}
elseif((L1==0)&&(L2==0)&&(R1==0)&&(R2==0))
//四个灯都检测到白色后退
{
Backward();
}
elseif((L1==1)&&(L2==1)&&(R1==1)&&(R2==1))
//四个灯都检测到黑色后退
{
Backward();
}
else//前进
{
Forward();
}
}
}
2.2.4避障及循迹程序流程图
将小红外避障模块和循迹模块结合起来,通过软件编程,可使智能小车实现以下功能:
当红外检测器检测到障碍物时,小车停止行进;当小车前方没有障碍物时,小车按照指定的跑道轨迹行进。
以下是程序流程图:
2.2.5外避障及循迹程序程序代码
#include
sbitLD1=P1^2;//左左检测灯
sbitLD2=P1^3;//中左检测灯
sbitRD1=P1^4;//中右检测灯
sbitRD2=P1^5;//右右检测灯
sbitLeftIR=P3^5;//左边红外接收连接到P3_5
sbitRightIR=P3^6;//右边红外接收连接到P3_6
sbitLeftLaunch=P2^3;//左边红外发射连接到P2_3
sbitRightLaunch=P2^4;//右边红外发射连接到P2_4
voiddelay12us(void)//延时12us,误差-0.064236111111us
{
unsignedchara,b;
for(b=9;b>0;b--)
for(a=2;a>0;a--);
}
voiddelay_nus(unsignedinti)//延时,单片机为STC10F08XE
{
i=i*10/12;
while(--i);
}
voidHardware_delay_1ms(void)
{
TMOD&=0xF0;
TMOD|=0x01;//T0——16位定时器器模
TH0=0xFC;
TL0=0x18;//64536
TF0=0;//清除定时器溢出标志
TR0=1;//启动定时器
while(TF0==0);//等待计数完成
TR0=0;//停止定时器
}
voiddelay_nms(intn)
{
intj;
for(j=n;j>0;j--)
Hardware_delay_1ms();
}
voidIRLaunch(unsignedcharIR)
{
intcounter;
if(IR=='L')//左边发射
for(counter=0;counter<38;counter++)
{
LeftLaunch=1;
delay12us();
LeftLaunch=0;
delay12us();
}
if(IR=='R')//右边发射
for(counter=0;counter<38;counter++)
{
RightLaunch=1;
delay12us();
RightLaunch=0;
delay12us();
}
}
voidForward(void)//向前行走子程序
{
P1_1=1;
delay_nus(1440);
P1_1=0;
P1_0=1;
delay_nus(1400);
P1_0=0;
delay_nms(20);
}
voidLeft_Turn(void)//左转子程序
{
inti;
for(i=1;i<=15;i++)
{
P1_1=1;
delay_nus(1420);
P1_1=0;
P1_0=1;
delay_nus(1400);
P1_0=0;
delay_nms(20);
}
}
voidRight_Turn(void)//右转子程序
{
inti;
for(i=1;i<=15;i++)
{
P1_1=1;
delay_nus(1440);
P1_1=0;
P1_0=1;
delay_nus(1420);
P1_0=0;
delay_nms(20);
}
}
voidBackward(void)//向后行走子程序
{
inti;
for(i=1;i<=65;i++)
{
P1_1=1;
delay_nus(1400);
P1_1=0;
P1_0=1;
delay_nus(1440);
P1_0=0;
delay_nms(20);
}
}
voidStop(void)//停止子程序
{
P1_1=0;
P1_0=0;
}
intmain()
{
intL1,L2,R1,R2;
intirDetectLeft,irDetectRight;
uart_Init();
printf("ProgramRunning!
\n");
while
(1)
{
IRLaunch('R');//右边发射
irDetectRight=RightIR;//右边接收
IRLaunch('L');//左边发射
irDetectLeft=LeftIR;//左边接收
L1=LD1;
L2=LD2;
R1=RD1;
R2=RD2;
if((irDetectLeft==0)||(irDetectRight==0))
//检测到障碍物停止
{
Stop();
}
elseif((L1==1)&&(R2==0))
//左左灯检测到黑色右右灯检测到白色左转
{
Left_Turn();
}
elseif((L1==0)&&(R2==1))
//左左灯检测到白色右右灯检测到黑色右转
{
Right_Turn();
}