智能壁障测速小车详解.docx
《智能壁障测速小车详解.docx》由会员分享,可在线阅读,更多相关《智能壁障测速小车详解.docx(15页珍藏版)》请在冰豆网上搜索。
智能壁障测速小车详解
一、设计方案……………………………………………………………1
1.1智能壁障小车的设计分析………………………………………………………1
1.2设计要求…………………………………………………………………………2
二、硬件电路设计………………………………………………………2
2.1单片机AT89S52简介……………………………………………………………2
2.1.1ATS89S52………………………………………………………………………2
2.1.2ATS89S52主要特性……………………………………………………………2
2.2整体硬件原理图…………………………………………………………………3
2.3传感器设计………………………………………………………………………3
2.3.1霍尔传感器……………………………………………………………………3
2.3.2红外线传感器…………………………………………………………………4
2.4液晶显示设计……………………………………………………………………5
2.5电机部分…………………………………………………………………………6
三、程序设计……………………………………………………………7
3.1程序设计内容……………………………………………………………………7
3.2C语言源程序……………………………………………………………………7
四、心得体会……………………………………………………………8
五、参考文献……………………………………………………………9
六、附录…………………………………………………………………10
一、设计方案
1.1智能壁障小车的设计分析
汽车行业的发展越来越迅速,而智能小车的相关研究也越来越多,实际生活中智能小车可以代替人类完成一些工作,因此有着得要的现实意义。
本文在玩具电动车上加装光电检测器,对小车的运行状态进行实时测量,包括行驶的速度、所处的位置等,然后利用单片机处理测量所得的数据,最终根据实际的测量结果对小车进行智能控制。
1.2设计要求
设计一个智能小车,其功能有:
1.在有障碍物的情况下能够自动壁障;2.在行驶过程中能够显示两个轮子的速度。
二、硬件电路设计
2.1单片机AT89S52简介
2.1.1AT89S52
AT89S52是美国ATMEL公司生产的低功耗,高性能CMOS8位单片机,片内含4Kb的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度,非易失性存储技术生产,兼容标准8051指令系统及引脚。
它集Flash程序存储器,既可在线编程(ISP)也可用传统方法进行编程及通8位微处理器于单片芯片中,ATMEL公司的功能强大,低价位AT89S51单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。
2.1.2AT89C52主要特性
MCS-51兼容4K字节可编程闪烁存储器寿命1000写/擦;循环数据保留时间:
10年;全静态工作:
0Hz-24Hz;三级程序存储器锁定128*8位;内部RAM32可编程I/O线两个;16位定时器/计数器,5个中断源可编程串行通道,低功耗的闲置和掉电模式,片内振荡器和时钟电路。
图1单片机
2.2整体硬件原理图
硬件部分包括传感器部分、电机部分、显示部分以及用单片机编程用到的的连接口部分。
图2硬件原理图
2.3传感器设计
2.3.1霍尔传感器
①模块说明:
1尺寸:
2.7cm*1.4mm
2主要芯片:
LM393、3144霍尔传感器
3工作电压:
直流5伏
图3霍尔传感器原理图
②模块接口说明(4线制)
1VCC外接5V电压
2GND外接GND
3DO小板数字量开关量输出接口(0和1)
图4霍尔传感器模块
③模块特点:
1具有电源指示灯和信号输出指示。
2单路信号输出。
3模块无触发,输出高电平;模块有触发,输出低电平。
根据这一特性,将霍尔传感器模块DO口接入单片机的两个外部中断。
4灵敏度可调(精调)。
5有磁场切割就有信号输出。
6电路板输出开关量,可以直接接单片机或者继电器模块,蜂鸣器模块等。
7可用于电机测速/位置检测等场合。
2.3.2红外线传感器
①模块描述
该传感器模块对环境光线适应能力强,其具有一对红外线发射与接收管,发
射管发射出一定频率的红外线,当检测方向遇到障碍物(反射面)时,红外线反
射回来被接收管接收,经过比较器电路处理之后,绿色指示灯会亮起,同时信号
输出接口输出数字信号(一个低电平信号),可通过电位器旋钮调节检测距离,
有效距离范围2~80cm,工作电压为3.3V-5V。
该传感器的探测距离可以通过电
位器调节、具有干扰小、便于装配、使用方便等特点,可以广泛应用于机器人避
障、避障小车、流水线计数及黑白线循迹等众多场合。
图5红外线传感器原理图
②模块参数说明
1当模块检测到前方障碍物信号时,电路板上绿色指示灯点亮电平,同时
OUT端口持续输出低电平信号,该模块检测距离2~80cm,检测角度35°,检测距离可以通过电位器进行调节,顺时针调电位器,检测距离增加;逆时针调电位器,检测距离减少。
2、传感器主动红外线反射探测,因此目标的反射率和形状是探测距离的关键。
其
中黑色探测距离最小,白色最大;小面积物体距离小,大面积距离大。
3、传感器模块输出端口OUT可直接与单片机IO口连接即可,也可以直接驱动一
个5V继电器;连接方式:
VCC-VCC;GND-GND;OUT-IO
4、比较器采用LM393,工作稳定;
5、可采用3-5V直流电源对模块进行供电。
当电源接通时,红色电源指示灯点亮;
6、具有3mm的螺丝孔,便于固定、安装;
7、电路板尺寸:
3.1CM*1.5CM
8、每个模块在发货已经将阈值比较电压通过电位器调节好,非特殊情况,请勿
随意调节电位器。
③模块接口说明(3线制)
1VCC外接3.3V-5V电压(可以直接与5v单片机和3.3v单片机相连)
2GND外接GND
3OUT小板数字量输出接口(0和1)
图6红外线传感器模块
2.4液晶显示设计
显示部分用的lcd1602元件,第一行显示右轮的速度,第二行显示左轮的速度。
图7Lcd1602仿真显示
2.5电机部分设计
2.5.1电机的选型
由于该次课程设计提供小车的底座(详见附图),使用的是连续旋转伺服电机。
2.5.2伺服电机的工作原理:
一个微型伺服马达是一个典型闭环反馈系统,其原理可由下图表示:
图8伺服电机工作原理图
减速齿轮组由马达驱动,其终端(输出端)带动一个线性的比例电位器作位置检测,该电位器把转角坐标转换为一比例电压反馈给控制线路板,控制线路板将其与输入的控制脉冲信号比较,产生纠正脉冲,并驱动马达正向或反向地转动,使齿轮组的输出位置与期望值相符,令纠正脉冲趋于为0,从而达到使伺服马达精确定位的目的。
2.5.3伺服电机的控制信号:
它有一个零速度点(1.5ms脉宽序列(如图9)),一个顺时针最大速度点(1.3ms脉宽序列(如图10)),和一个逆时针的最大速度点(1.7ms脉宽序列(如图11)),其中越靠近零速度点,速度越小,远离零点越大速度越大。
我们给伺服电机输入的脉冲一般是要在22ms左右,脉宽为1.3-1.7ms。
图9电机停止
图10电机顺转
图11电机逆转
注:
整个车子的图在附录中
三、程序设计
3.1程序设计内容
(1)循环扫描红外线接口,并控制左右两个电机
(2)两个外部中断计数
(3)lcd1602显示两轮的速度(单位mm/s)
3.2C语言源程序
程序及流程图见附录
四、心得体会
从开始进行设计智能壁障小车到完成实现壁障和测速功能,我找了很多资料,并应用了protel99se软件进行画图和proteus软件仿真,并运用单片机知识进行编程以完成设计要求的功能。
在途中,也遇到了好多问题,比如①:
四节电池同时驱动单片机和两个电机有点困难,故用了八节电池分别驱动;②:
电机的驱动问题,PWM波形如何获取,如果用纯粹用定时器的话,那么测速的时间就无法掌握,因为测速需要一个定时器,所以只剩下一个定时器,但是最后我就用延时程序,利用keil软件测出延时的时间(1.3-1.7ms之间),问题也就解决了;③:
开始将程序写完并下载后,发现小车会断断续续的走(走一段停一段在走一段),不是连续的走,经过多次的调时后,发现原因是因为中断的优先级问题,所以将电机驱动定时器T1设置为最高优先级,问题也就解决了。
唯一遗憾的是小车右拐没有实现,我把左拐的程序反写,发现还是不能右拐,后退,前进,左拐都能够实现,就是右拐实现不了,也用了多种方法也实现不了,想了好久还是没有想出个原因来。
毕竟自己不是学电气的,很多东西自己也是不了解的。
我已经尽了自己的最大努力,也从中学到了很多知识,获益匪浅。
特别是每次把问题解决以后,那种心情是非常开心的,当看到小车自动避障和测速以后,脸上自然露出自豪的笑容。
感谢学院给我们提供这样的实践动手机会,并通过课程设计使我们能够有机会将书本上学到的知识运用到的实际中去。
在课设过程中陈老师给了我很多的指导和帮助,并监督我及时完成了本次课程设计,在此特别感谢陈陈老师和给予我帮助的同组同学。
五、参考文献
[1]郭天祥.51单片机C语言教程——入门、提高、开发、拓展全攻略.电子工业出版社,2009.1.
[2]张迎新.单片机初级教程——单片机基础(第二版).北京航空航天大学出版社,2006.8.
六、附录
(Ⅰ)小车底座(三视图附图中有)
注:
两个轮子上各粘有六个磁钢(均匀分布)
(Ⅱ)整个小车的外形
(Ⅲ)C语言程序流程图:
(Ⅳ)程序清单
#include
#defineucharunsignedchar
#defineuintunsignedint
uchartable1[]="Right:
00.0";
uchartable2[]="Left:
00.0";
uchartable[]="0123456789";
sbitr=P0^0;//右边的红外线传感器
sbitm=P0^1;//中间的红外线传感器
sbitl=P0^2;//左边的红外线传感器
sbitl_m=P1^1;//控制左轮电机
sbitr_m=P1^0;//控制右轮电机
sbitint_0=P3^2;
sbitint_1=P3^3;
sbitlcden=P3^5;//液晶使能端
sbitlcdrs=P3^7;
sbitlcdrw=P3^6;
signedi,j;
uintnum,jz;
floatf_i,f_j,D=7.1;//i:
左轮的脉冲数P3.3外部中断1j:
右轮的脉冲数P3.2外部中断0num:
计算有多少个50msD:
轮子的直径(cm)
voiddelay(uintk)//162是1.3ms212是1.7ms
{
uintt;
for(t=k;t>0;t--);
}
voiddelayms(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)//向1602写命令
{
lcdrs=0;
P2=com;
delayms
(1);
lcden=1;
delayms
(1);
lcden=0;
}//向1602写数据
voidwrite_data(uchardate)
{
lcdrs=1;
P2=date;
delayms
(1);
lcden=1;
delayms
(1);
lcden=0;
}
voidled(ucharnum1,ucharnum2)//num1表示液晶第一行有几个数显示,num2表示液晶第二行有几个数显示
{
uchari,j;
write_com(0x80);
for(i=0;i{
write_data(table1[i]);
delayms
(1);
}
write_com(0x80+0x40);
for(j=0;j{
write_data(table2[j]);
delayms
(1);
}
}
voidinit()//初始化
{
TMOD=0x11;
TH1=(65536-20000)/256;//20ms的初值
TL1=(65536-20000)%256;
TH0=(65536-50000)/256;//50ms的初值
TL0=(65536-50000)%256;
PT1=1;
EA=1;
ET0=1;
ET1=1;
EX0=1;
EX1=1;
lcdrw=0;
lcden=0;
i=0;//i,j赋初值0
j=0;
D=D*3.14/6;
write_com(0x38);//设置16*2显示,5*7点阵,8位数据借口
write_com(0x0c);//设置开显示,不显示光标
write_com(0x06);//写一个字符后地址指针加1
write_com(0x01);//显示清0,数据指针清0
led(10,9);
TR0=1;
}
voidmain()
{
delayms(1000);
init();
while
(1)
{
if((r==1)&&(m==1)&&(l==1))jz=2;//没有障碍物直走2
elseif((r==0)&&(m==1)&&(l==1))jz=1;//右边有障碍物左拐1
elseif((r==1)&&(m==1)&&(l==0))jz=1;//左边有障碍物右拐
elseif(m==0)jz=1;//前面有障碍物左拐1
r_m=0;
l_m=0;
TR1=1;
}
}
voidt_1()interrupt3
{
TR1=0;
r_m=1;
l_m=1;
TH1=(65536-20000)/256;
TL1=(65536-20000)%256;
switch(jz)
{
case1:
delay(162);/*左拐*/
r_m=0;
delay(50);
l_m=0;
TR1=1;
break;
case2:
r_m=0;/*前进*/
delay(212);
l_m=0;
TR1=1;
break;
case3:
delay(162);
l_m=0;
delay(50);
r_m=0;
TR1=1;
break;
/*case4:
l_m=0;
delay(162);
r_m=0;
TR1=1;
break;*//*后退*/
}
}
voidl_mc()interrupt2
{
i++;
while(int_1==0);//记左轮的脉冲数
}
voidr_mc()interrupt0
{
j++;
while(int_0==0);//记右轮的脉冲数
}
voidT0_time()interrupt1
{
uintm;
TH0=(65536-50000)/256;//50ms的初值
TL0=(65536-50000)%256;
num++;
if(num>=20)
{
num=0;
f_i=i*D;
f_j=j*D;
i=f_i*10;
j=f_j*10;
m=j%100%10;//小数位
table1[9]=table[m];
m=j%100/10;//个位
table1[7]=table[m];
m=j/100;//十位
table1[6]=table[m];
m=i%100%10;
table2[8]=table[m];
m=i%100/10;
table2[6]=table[m];
m=i/100;
table2[5]=table[m];
led(10,9);
i=0;
j=0;
}
}