智能遥控小车论文.docx
- 文档编号:6915738
- 上传时间:2023-01-12
- 格式:DOCX
- 页数:21
- 大小:506.36KB
智能遥控小车论文.docx
《智能遥控小车论文.docx》由会员分享,可在线阅读,更多相关《智能遥控小车论文.docx(21页珍藏版)》请在冰豆网上搜索。
智能遥控小车论文
电子设计竞赛论文
所在院系:
通信与信息工程学院
题目:
遥控小车
作者:
华伟锋朱志刚张凡
摘要4
第一章方案设计与论证
1.1主控系统4
1.2电机驱动模块4
1.3测距系统5
1.4LCD显示模块6
1.5电源模块7
第二章软件设计
2.1总体设计7
2.2主板设计框图8
第三章程序设计
(1)
主程序9
(2)
液晶程序9
(3)
超声波程11
(4)
红外程序13
(5)
温度模块15
结束
参考文献
实物图
摘 要:
利用遥控器对小车进行遥控,并以STC89C52单片机为控制芯片控制电动小汽车的速度及转向,从而实现运动的功能,用超声波进行测距,无线传输数据,用12864来显示。
其中小车驱动由L298N驱动电路完成,速度由单片机输出的PWM波控制。
关键词:
遥控小车;STC89C52单片机;L298N;超声波,12864,
第一章方案设计与论证
根据要求,确定如下方案:
在现有玩具电动车的基础上,加装光电检测器,实现对电动车的速度、位置、运行状况的实时测量,并将测量数据传送至单片机进行处理,然后由单片机根据所检测的各种数据实现对电动车的智能控制。
这种方案能实现对电动车的运动状态进行实时控制,控制灵活、可靠,精度高,可满足对系统的各项要求。
1.1主控系统
采用单片机作为整个系统的核心,用其控制行进中的小车,的性能指标。
其关键在于实现小车的自动控制,而在这一点上,单片机就显现出来它的优势——控制简单、方便、快捷。
这样一来,单片机就可以充分发挥其资源丰富、有较为强大的控制功能及可位寻址操作功能、价格低廉等优点。
因此,这种方案是一种较为理想的方案。
针对本设计特点——多开关量输入的复杂程序控制系统,不能用精简I/O口和程序存储器的小体积单片机,D/A、A/D功能也不必选用。
根据这些分析,我选定了STC89C52单片机作为本设计的主控装置,51单片机具有功能强大的位操作指令,I/O口均可按位寻址,程序空间多达8K,对于本设计也绰绰有余,更可贵的是51单片机价格非常低廉。
在综合考虑了NRF24l01、四部电机的驱动等诸多因素后,我们决定采用一片单片机,充分利用STC89C52单片机的资源。
1.2电机驱动模块
我选用了L298N(如图2.2)。
这种调速方式有调速特性优良、调整平滑、调速范围广、过载能力大,能承受频繁的负载冲击,还可以实现频繁的无级快速启动、制动和反转等优点。
因此决定采用使用功率三极管作为功率放大器的输出控制直流电机。
1.3测距模块
US-100超声波测距模块,在此模式下只需要在TX管脚输入0X55(波特率9600),系统便可发出8个40KHZ的超声波脉冲,然后检测回波信号。
当检测到回波信号后,然后根据当前温度对测距结果进行校正,将校正后的结果通过Echo/RX管脚输出。
输出的距离值共两个字节,第一个字节是距离的高8位(H),第二个字节为距离的低8位(L),单位为毫米。
即距离值为(H*256+L)mm。
1.4LCD显示模块
采用12864来显示无线模块接收的信息。
1.5电源模块
用蓄电池通过稳压芯片供电,其优点是可稳定的提供12V电压,然后经过L7805降压到稳定的5V。
给单片机供电,通过遥控的控制小车的前进与后退,从单片机上输出的5V给液晶等供电,显示距离和温度。
第二章软件设计
总体设计
智能小车采用四轮驱动,共用2个驱动板来驱动,通过遥控的控制小车进行基本的前进,后退,向左,向右,在前进的时候通过超声波的数据收集和DS18B20的温度数据收集,显示在12864液晶屏上,对于步进电机的控制,则需要遥控的控制,对其向左收集数据和向右收集数据。
2.1总体设计
主流程图
2.2主板设计框图
第三章程序设计
(1)主程序
#include
#include
typedefunsignedintuint;
typedefunsignedcharuchar;
#include"12864.h"
#include"chaoshengbo.h"
#include"ds.h"
#include"hongwai.h"
//#include"bujin.h"
voidmain()
{
init_12864();
TMOD=0x11;//使用定时器T0的模式1定时器T0的模式1
EA=1;//开启总中断
ET1=1;//定时器T1中断允许
TH1=0;
TL1=0;
EX0=1;//开外中断0
EX1=1;//开外部中断1
IT1=0;//电平触发
ET0=1;//定时器T0中断允许
TR0=0;while
(1)
{
display_CHAO();
display_ds(Get_Temperature());
}
}
(2)液晶程序
sbitRS=P3^0;//用作并口模式寄存器选择时:
高为数据,低位指令;用作串口片选信号时高为有效,低位失效
sbitRW=P3^4;//用作并口模式时:
高为读,低为写;串口时为串口数据线
sbitE=P3^5;//并口时为读写起始脚,也可作串口连续输入
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=20;y>0;y--);
}
voidbusy()
{
RS=0;//用作并口,高为数据,低为指令;
RW=1;//用作并口,高为读,低为写;
E=1;//使能有效
while((P2&0x80)==0x80);//在基本指令中,读取显示RAM数据。
其中D7为忙标志位BF,当BF为1时表示忙
E=0;
}
voidwrite_data(uchardate)
{
busy();//先检测是否为非忙
RS=1;//RS高为写数据
RW=0;//RW低为写数据
E=1;
P2=date;//把写的数据给P2口
delay(40);//延时让把数据读入
E=0;
}
voidwrite_com(ucharcom)
{
busy();//先检测是否为非忙
RS=0;//RS为低写指令
RW=0;//RW为低为写数据
E=1;
P2=com;//把写的指令给P2口
delay(40);
E=0;
}
voidinit_12864()
{
delay(1000);
RW=0;//低为写
write_com(0x30);//功能设定1:
八位2:
基本指令集(没有顺序)
write_com(0x0c);//开显示(无游标、不反白)
write_com(0x01);//清除显示,并且设定地址指针为00H
write_com(0x06);//指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位
}
voidstr(uchar*p)
{while(*p>0)
{write_data(*p);
p++;
delay(20);
}
}
(3)超声波程序
sbitRX=P3^6;
sbitTX=P3^7;
sbitpause=P3^3;
unsignedlongS=0;
bitflag=0;
uinttime=0;
voidConut(void)
{
time=TH1*256+TL1;
TH1=0;
TL1=0;
S=(time*1.7)/100;
write_com(0x80);
str("此刻距离:
");
if((S>=700)||flag==1)
{
flag=0;
write_com(0x80+5);
str("_.__");
}
elseif(S<20)
{
pause=0;
}
else
{
write_com(0x80+5);write_data(0x30+S%1000/100);
str(".");//写小数write_data(0x30+S%1000%100/10);//数字显示函数write_data(0x30+S%1000%100%10);
str("M");
}
}
voidds1()interrupt3//中断溢出标志
{
flag=1;
RX=0;
}
voidStart()
{
TX=1;//800MS启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
voiddisplay_CHAO()
{
uinti;
Start();//启动模块
for(i=7500;i>0;i--)
{
if(RX==1)
{
TR1=1;//开启计数
while(RX);//当RX为1计数并等待
TR1=0;//关闭计数
Conut();//计算
}
}
}
voidInt1(void)interrupt2
{
pause=1;//关闭外中断1
P0=0x00;
write_com(0x01);
write_com(0x80);
str("太近危险!
");//
}
(4)红外程序
sbitIR=P3^2;//将IR位定义为P3.2引脚
sbitzhishideng=P1^0;//指示灯
unsignedinti=500;
unsignedchara[4];//储存用户码、用户反码
unsignedintLowTime,HighTime;//储存高、低电平的宽度
ucharcodetable[]={0x09,0x0c,0x06,0x03};//步进电机转动位码
uinti;
voiddelay_z(ucharz)//步进电机延时
{
ucharx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voiddeal_1()//步进电机正转
{
intj=30;、
while(j--)
for(i=0;i<4;i++)
{
P1=table[i];
delay_z(50);
}
}
voiddeal_2()//步进电机反转
{
intj;
j=30;
while(j--)
for(i=0;i<4;i++)
{
P1=table[3-i];
delay_z(50);
}
}
voidzhishi()//指示灯函数
{
unsignedchari=200,j=125;
zhishideng=0;
while(i--)
while(j--);
zhishideng=1;
}
bitDeCode(void)//单片机解码函数
{
unsignedchari,j;
unsignedchartemp;//储存解码出的数据
for(i=0;i<4;i++)//连续读取4个用户码和键数据码
{
for(j=0;j<8;j++)//每个码有8位数字{
temp=temp>>1;//temp中的各数据位右移一位,因为先读出的是高位TH0=0;//定时器清0
TL0=0;//定时器清0
TR0=1;//开启定时器T0
while(IR==0);//如果是低电平就等待,低电平计时
TR0=0;//关闭定时器T0LowTime=TH0*256+TL0;//保存低电平宽度
TH0=0;//定时器清0
TL0=0;//定时器清0
TR0=1;//开启定时器T0
while(IR==1);//如果是高电平就等待
TR0=0;//关闭定时器T0HighTime=TH0*256+TL0;//保存高电平宽度if((LowTime<460)||(LowTime>660))return0;//如果低电平长度不在合理范围,则认为出错,停止解码if((HighTime>460)&&(HighTime<660))temp=temp&0x7f;//如果高电平时间在560微秒左右,则该位是0if((HighTime>1500)&&(HighTime<1900))temp=temp|0x80;//如果高电平时间在1680微秒左右,则该位是1
}
a[i]=temp;//将解码出的字节值储存在a[i]
}
if(a[2]==~a[3])return1;//验证键数据码和其反码是否相等,一般情况下不必验证用户码
else{return0;}
}
voidInt0(void)interrupt1
{
EX0=0;/关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号
TH0=0;//定时器T0的高8位清0
TL0=0;//定时器T0的低8位清0
TR0=1;//开启定时器T0
while(IR==0);//如果是低电平就等待,给引导码低电平计时
TR0=0;//关闭定时器T0
LowTime=TH0*256+TL0;//保存低电平时间
TH0=0;//定时器T0的高8位清0
TL0=0;//定时器T0的低8位清0
TR0=1;//开启定时器T0
while(IR==1);//如果是高电平就等待,给引导码高电平计时
TR0=0;//关闭定时器T0
HighTime=TH0*256+TL0;/保存引导码的高电平长度if((LowTime>8500)&&(LowTime<9500)&&(HighTime>4200)&&(HighTime<4800))//如果是引导码,就开始解码,否则放弃。
{
if(DeCode()==1)//执行遥控解码功能
{
if(a[2]==0x43){P0=0x00;}//如果按下停
if(a[2]==0x45){P0=0x69;}//如果按下左
if(a[2]==0x46){P0=0x96;}//如果按下右
if(a[2]==0x47){P0=0xaa;}//如果按下前进
if(a[2]==0x40){P0=0x55;}//如果按下后退
if(a[2]==0x16){deal_1();}//如果按下
if(a[2]==0x19){deal_2();}//如果按下后退x
if(a[2]==0x0d){P1=0X00;}//如果按下后退x
}
zhishi();//指示灯闪烁,表示正确解析红外信号并进行相关操作,且有适当延时
}
EX0=1;//开启外中断EX0
}
(5)温度模块
/*
温度模块DQ=P3^1;液晶第二行显示
*/
sbitDQ=P3^1;
uinttemp;
voiddelay_ds(unsignedchari)
{
while(--i);
}
voidInit_Ds18b20(void)
{
DQ=1;
delay_ds
(1);
DQ=0;//单片机拉低总线
delay_ds(250);
DQ=1;//释放总线,即拉高了总线
delay_ds(100);//确保能让DS18B20发出存在脉冲。
}
ucharRead_One_Byte(void)//读取一个字节的数据
//读数据时,数据以字节的最低有效位先从总线移出
{
uchari=0;
uchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//将总线拉低,要在1us之后释放总线
//单片机要在此下降沿后的15us内读数据才会
_nop_();//至少维持了1us,表示读时序开始
dat>>=1;//让从总线读到的位数据,依次从高位移动到低
DQ=1;//释放总线,此后DS18B20会控制总线,
delay_ds
(1);//延时7us,此处参照推荐的读时序图
if(DQ)//控制器进行采样
{
dat|=0x80;//若总线为1,即DQ为1,那就把dat的最高位置1;
}
delay_ds(10);//此延时不能少,确保读时序的长度60us。
}
return(dat);
}
voidWrite_One_Byte(uchardat)
{
uchari=0;
for(i=8;i>0;i--)
{
DQ=0;//拉低总线
_nop_();//至少维持了1us,表示写时序开始
DQ=dat&0x01;//从字节的最低位开始传输
//指令dat的最低位赋予给总线,
delay_ds(10);//必须让写时序持续至少60us
DQ=1;//写完后,必须释放总线,
dat>>=1;
delay_ds
(1);
}
}
uintGet_Temperature()//获取温度getthetemperature
{
uchara,b;
floattt;
Init_Ds18b20();//初始化
Write_One_Byte(0xcc);//忽略ROM指令
Write_One_Byte(0x44);//温度转换指令
Init_Ds18b20();//初始化
Write_One_Byte(0xcc);//忽略ROM指令
Write_One_Byte(0xbe);//读暂存器指令
a=Read_One_Byte();
b=Read_One_Byte();
temp=b;
temp<<=8;
temp=temp|a;
tt=temp*0.0625;
temp=tt*100+0.5;
returntemp;
}
voiddisplay_ds(uinttemp)
{
write_com(0x90);//定义写的开始
str("此刻温度:
");
write_data(0x30+temp/1000);
write_data(0x30+temp%1000/100);
str(".");//温度write_data(0x30+temp%100/10);
write_data(0x30+temp%10);
str("C");//定义单位
}
第四章参考文献
1、《C语言程序设计》--张磊出版社:
高等教育出版社
2、《C语言编程宝典》,作者:
王大刚
3、《C语言最新编程技巧200例》作者:
鲁沐浴,电子工业出版社,1997,1
4、《C语言程序设计实用技巧与程序实例》作者:
梁 翎,李爱齐,上海科普出版社,1996,5
5、《TurboC程序设计技巧与应用实例》作者:
陈国章,天津科学技术出版社,
6、《C高级实用程序设计》作者:
王士元,清华大学出版社,1996,6
7、《C:
TheCompleteReference》
8、《ProgramminginC-ATutorial》
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 智能 遥控 小车 论文