智能小车.docx
《智能小车.docx》由会员分享,可在线阅读,更多相关《智能小车.docx(24页珍藏版)》请在冰点文库上搜索。
智能小车
项目名称避障小车
班级
系别
专业
学生姓名
指导教师
避障小车
智能小车采用AT89C51单片机作为检测和控制的核心,实现小车智能控制,包括避障、寻光、显示、测距等功能。
避障方式采用超声波发射接收来判断。
驱动电机采用lm298电路作为驱动电路,电机控制方式为lm298直接控制。
系统采用AT89C51单片机。
实现的功能是:
从起点出发,随机运动,发现前方有障碍物就躲开,如果障碍物上有光源小车立即旋转180度后小车继续行走,在行走的过程中可以通过12864显示前方障碍物与小车的距离。
1.系统方案选择与论证
小车模型总体方案:
方案一:
按照车身长度要求,在小车后部左右两侧各安装一个普通直流电机带动的轮子,小车前部安装一个万向动轮,方便小车拐弯并起平衡支撑作用。
车身要用两块薄板制成,薄板下层放置电机驱动电路模块及电机,上面要放置超声波模块这种方案硬件比较简单,软件实现起来思路也比较清晰,在行车路程方面比较精确,计算简单,小模块简单易于实现。
但制作复杂。
方案二:
圆梦小车底座在网上有很多形式,并且价格便宜,使用方便。
所以我们使用第二种方案。
2控制器模块(单片机的选择)
方案一:
采用凌阳SPCE061A单片机实现,该单片机内部资源丰富,集成了A/D,D/A,易于数据的采集等功能,但是在此系统中只要用到少部分的资源对资源是种浪费。
方案二:
采用传统的8位AT89C51单片机作为运动物体的控制中心。
经典51单片机具有价格低廉,使用简单等特点,单片机软件编程自由度大,可用编程实现各种控制算法和逻辑控制。
并且可以实现智能小车所有的功能。
3距离测量和避障模块
方案一:
采用红外元件,红外测量距离比较近,不能精确测量距离。
红外避障:
可以实现避障,但是它只对白色敏感度强,如黑色障碍物就不能避开,因此不采用此方案。
方案二:
采用超声波测距和避障。
超声波测量距离比较远可以达到4cm——500cm,能精确测量距离。
超声波避障:
避障能力强,不受物体大小颜色限制、敏感度强且精确,因此采用此方案。
4电机类型选择
方案一:
采用步进电机,电脉冲驱动。
改变脉冲频率调速,改变相序实现正反转。
此方案可以轻松实现前进、转向等控制功能。
但两个轮子电机参数不易匹配,并且加大系统复杂程度。
方案二:
采用直流电机,采用lm298驱动电路。
此方式实现功能简单,可灵活正、反转,在原地旋转。
本系统采用方案二
5电源选择
方案一:
用4节1.5V干电池或6v充电电池,此方案供电简单,且重量轻。
方案二:
用7v的手机电池,由于设计中用到6v与5v电源,若用7V则造成电路复杂。
基于上述考虑,选择方案一。
6测光模块
为了设计简单、经济,我们直接采用普通光敏电阻,经过lm358放大,把信号直接传送给单片机,接收到的信号经过单片机处理然后控制直流电机的停转状态。
7系统各模块的最终方案
经过仔细分析和论证,我们决定系统模块的最终方案如下:
(1)控制器模块:
选择AT89C51作为小车运动的控制中心。
(3)超声波模块:
采用反射式超声波发射-接受器来调整小车测距和避障。
(5)电机驱动模块:
采用普通直流电机,双驱动四接口方式。
(6)12864显示模块:
车与障碍物的距离动态显示和有无光源显示。
(7)电源模块:
直接采用电池组。
(8)测光模块:
直接采用普通光敏电阻。
8系统的硬件设计与实现
8.1主要单元电路的电路图和说明
8.2直流电机PWM调速控制
利用单片机延时改变直流电机电枢上电压的“占空比”来改变平均电压的大小,从而控制电动机的转速,改变小车左右轮电机的速度,从而实现小车的左右转功能。
8.3电机驱动原理电路
如图1所示,使用最小系统板上六个接口M11、M12、M13、M21、M22、M23来实现对小车上电机的控制。
当M12、M22输入为低电平,M13、M23输入为高电平时,驱动电机正转。
当M12、M22输入为高电平,M13、M23输入为低电平时,驱动电机反转。
M12、M22、M13、M23都为高电平时电机停止,。
M12、M22、M13、M23不能同时为低电平。
8个二极管可以起到保护的作用。
将控制部分与电动机驱动部分直接连接。
最小系统板的四个控制端口M12、M22、M13、M23分别接左电机A口、B口、右电机A口、B口。
只要通过软件编程设定四个控制端口M12、M22、M13、M23的不同编码,就可得到电动车的前进,后退等不同的运行状态。
图1电机驱动电路原理图
8.4测光电路
(如图2所示)
图2测光电路
8.5整体电路模块
(如图3所示)
图3整体电路模块
8.5整体电路模块PCB图
(如图4所示)
图4整体电路模块PCB图
9在制作过程遇到什么问题:
在制作小车过程中我们遇到了很多问题,板子都做了三块才成功实现所有功能。
第一块板子,做的过程中我们遇到了很常见的问题,在调试时,我们把12864与小车都加上,然后把程序烧进去,可是总烧不进去,经过一段时间的检查原来是我们使用测量转速电路中的lm358引脚与单片机下载接口重合了,去掉lm358后烧制程序就没有问题了。
程序一烧进去,小车立马就动了,但是液晶显示器显示的是乱码。
经过反复的检查,我们发现是一个轮子的测量转速电路对整个电路都造成了干扰,导致液晶工作不正常,经过多次调试,我们把电路进行了改进,并加上了串头调试,让其可以直接与电脑通信,改进完整之后做第二块板子,做完第二块板子之后又开始调试,吸取了前一次的教训之后,我们下载程序,液晶显示都可以正常工作了,现在关键来调试超声波模块与单片机通信,经过很长一段时间的调试超声波模块工作总是不正常,它可以接收到单片机给它的信号但是单片机不能接收到返回信号,然后我们用电脑串口与单片机通信,通过接收与发送,串口软件得到的数据总是与正确结果有很大差别,最后我们用示波器测试单片机的rxd与txd,发现txd有不规则的方波输出,rxd则没有输入波形,然后有检查了超声波模块的rxd与txd,rxd没有输入,txd有方波,我们对这样的测试结果很不满意,然后开始对max232进行检查,没有发现问题,经过很长时间的调试都没有结果,板子都被我们折腾的面目全非了,于是我们使用以前从网上购买的单片机进行调试,结果让人满意,因为小车液晶串口通信,超声波通信,寻光通信都一一正常工作了,实现所有功能后,开始了第三板子的制作,已购买单片机为基础,再加上超声波模块,寻光模块制作好第三块板子后,再一次进行调试,在调试的过程中又出现了一些问题,超声波模块与单片机通信不正常,但是其他功能都正常工作了。
然后我们检查超声波通信的电路,与在购买的单片机上能正常工作的电路作对比,可认真检查没有任何差别,就在此时我们突然想到以前老师说过的单片机用rxd与txd通信时波特率要求是要一样的,我们马上对比一下现在做的板子上的晶振与购买的板子上的晶振比较,发现晶振果然是不相同,购买板子上的是11.0592Mhz用的是12Mhz,马上换上新的晶振再把程序烧进单片机,然后调试,发现我们要的效果总算是全出来了,我们终于成功地做出了寻光避障小车。
10实物图:
图(1-1)
图(1-2)
11总结
在软件部分,对智能车控制程序的仿真与调试,整个系统的方案是可行,但是在硬件部分,超声波模块的设计有待改进,由于时间的限制,我们没有重新设计,而是在原来的超声波模块上进行改造,把寻光加在上面,这样造成小车在整体外观上的不完美。
在本设计中,亮点之一体现在寻光、测距和避障部分,超声波传感器结合舵机可以在0到270度范围测量,实现小车的寻光,测距和避障。
经过此项目的经验教训,以后在做项目时不要按部就班,不能操之过急,首先要把电路原理搞透彻,再把设计流程、设计算法认真落实到纸上,经过团队讨论得出最佳方案。
再开始制作。
这样才能减少硬件上的错误、经济上的损失和精神上的打击。
只有吸取教训和总结经验我们的团队和所做的项目才能不断进步,不断提高。
12小车程序
#include
#include"intrins.h"
#defineucharunsignedchar
#defineuintunsignedint
#definecommand0
#definedate1
sbitRS=P0^5;
sbitRW=P0^6;
sbitEN=P0^7;
sbitM11=P1^0;
sbitM12=P1^1;
sbitM13=P1^2;
sbitM21=P1^3;
sbitM22=P1^4;
sbitM23=P0^2;
sbithong=P0^0;
uinttemp=0,temp3;//用来记录测量距离,当返回无效时显示上次的数据
bitflag=0;
ucharflag1=0;
bitflag2=0;
ucharsend[4]={0x22,0x01,0x00,0x23};
ucharsend1[13]={0x03,0x0a,0x11,0x18,0x1f,0x26,0x2d,0x26,0x1f,0x18,0x11,0x0a,0x03};
//uintligth[13]={0,0,0,0,0,0,0,0,0,0,0,0,0};
ucharcount;
uchart;
uchardistant[4];//测距离
uchars[6];
uchartemp1,temp2;
bitflag3=0;
bitflag4=0;
bitflag5=0;
ucharc=0;
/************************************************************************************
查忙函数RS=0;RW=1;wait=0闲;wait!
=0忙
************************************************************************************/
/*voidbusy()
{
ucharwait;
RS=0;
RW=1;
EN=1;
P2=0xff;
while
(1)
{
wait=P2;
wait&=0x80;
if(wait==0)break;
}
EN=0;
}*/
/******************************************************************
延时
*******************************************************************/
voiddelay(uintt)
{
uchartt;
for(t;t>0;t--)
for(tt=110;tt>0;tt--);
}
/************************************************************************************
写指令函数i=date为写数据,command为写命令
RW=0;E下降沿锁存数据
************************************************************************************/
voidwritelcd(i,uchardat)
{
//busy();
RW=0;
RS=i;
EN=1;
P2=dat;
_nop_();
_nop_();
EN=0;
delay(5);
}
/************************************************************************************
初始化液晶屏
0:
字库1:
绘图
************************************************************************************/
voidlcdinit(bita)
{
if(a==1)
{
writelcd(command,0x01);//清屏
writelcd(command,0x34);//扩展指令
writelcd(command,0x32);//功能设置---8BIT控制界面,绘图显示ON
writelcd(command,0x36);//功能设置---8BIT控制界面,扩充指令集
}
else
{
delay(10);
writelcd(command,0x30);//功能设置---8BIT控制界面,基本指令集
delay(5);
writelcd(command,0x30);
delay(5);
writelcd(command,0x0e);
delay(5);
writelcd(command,0x14);
delay(5);
writelcd(command,0x01);//清除屏幕显示,将DDRAM的地址计数器归零*/
delay(10);
writelcd(command,0x06);
delay(5);
}
}
voidlcdword(uchar*str)
{
while(*str>0)
{
writelcd(date,*str);
str++;
delay(20);
}
}
/********************************************************************/
voiddisplay(uintx)
{
{
s[0]=x/1000+'0';
s[1]=(x/100)%10+'0';
s[2]=(x/10)%10+'0';
s[3]=x%10+'0';
s[4]='C';
s[5]='M';
s[6]='\0';
writelcd(command,0x84);
lcdword(s);
}
}
/*******************************************/
voidsending(ucharsending[4])
{uchari;
sending[3]=sending[0]+sending[1]+sending[2];
for(i=0;i<4;i++)
{
SBUF=sending[i];
while(!
TI);
TI=0;
}
}
voidreceive()
{
uchari,n=100;
for(i=0;i<4;i++)
{
while(RI==0);//等待串行中断
distant[i]=SBUF;
RI=0;//清TI,必须软件清除
while(--n);//延时
}
flag=1;
}
/******************************************************************
判断是否为最近的光源
*****************************************************************
ucharpaduan(uintligtha[])
{
uinta=500;
uchari=0;
for(i=0;i<13;i++)
{
if(ligtha[i]{
a=ligtha[i];
t=i;
}
}
return(t);
}
voidadjust(ucharx)
{
if(flag2==1)
{
flag2=0;
switch(x)
{
case0,12:
M22=0;//右边轮子反转,往右转
M23=1;
M13=0;
M12=1;
delay(1500);
M23=0;
M22=1;
break;
case1,11:
M22=0;//右边轮子反转,往右转
M23=1;
M13=0;
M12=1;
delay(1100);
M23=0;
M22=1;
break;
case2,10:
M22=0;//右边轮子反转,往右转
M23=1;
M13=0;
M12=1;
delay(650);
M23=0;
M22=1;
break;
case4,8:
M22=1;//左边轮子反转,往左转,
M23=0;
M13=1;
M12=0;
delay(600);
M13=0;
M12=1;
break;
case5,7:
M22=1;//左边轮子反转,往左转,
M23=0;
M13=1;
M12=0;
delay(1100);
M13=0;
M12=1;
break;
case6:
M22=1;//左边轮子反转,往左转,
M23=0;
M13=1;
M12=0;
delay(1200);
M13=0;
M12=1;
break;
default:
break;
}
}
}*/
/********************************************************************/
voidmain()
{
TMOD=0X21;
SM0=0;//
SM1=1;
REN=1;
EA=1;
TR1=1;//波特率发生器
TH1=0XFD;
TL1=0XFD;
M11=1;
M12=1;
M13=0;
M21=1;
M22=1;
M23=0;
lcdinit(0);
writelcd(command,0x80);
lcdword("障碍物");
while
(1)
{
for(c=0;c<13;c++)
{
sending(send);
while(flag3==0)
{
receive();
if(flag==1)//测试距离完成
{
flag=0;
if((distant[3]==distant[1]+distant[2]+distant[0])&&(!
(distant[1]==0xff&&distant==0xff)))//检验
{
temp1=distant[1];
temp2=distant[2];
}
temp3=(temp1&0x0f)+(temp1>>4)*16+(temp2&0x0f)+(temp2>>4)*16;//数据处理
if(temp3<8)
{
if(hong==1)
{
delay(25);
if(hong==1)
{
flag2=1;
M13=1;
M23=1;
delay(800);
for(count=0;count<13;count++)
{
sending(send);
receive();
if((distant[3]==distant[1]+distant[2]+distant[0])&&(!
(distant[1]==0xff&&distant==0xff)))//检验
{
temp1=distant[1];
temp2=distant[2];
}
ligth[count]=(temp1&0x0f)+(temp1>>4)*16+(temp2&0x0f)+(temp2>>4)*16;//数据处理
delay(300);
}
adjust(paduan(ligth));
flag1=1;
writelcd(command,0x99);
lcdword("寻找到光源");
}
}
}
if(flag1==1&&temp3==2)
{
flag1=0;
while
(1)
{
M13=1;
M23=1;
}
}
if(temp3<10)
{
if(((c<=3&&c>=0)||c>=10)&&flag1!
=1)//超声波偏向右边
{
if(flag4==1)
{
M22=0;//两个轮子反转,
M23=1;
M13=1;
M12=0;
delay(80);
M22=1;//左边轮子反转,往左转
M23=0;
M13=1;
M12=0;
delay(200);
M13=0;
M12=1;
flag4=0;
}
flag4=1;
}
}
if(temp3<15)
{
if((c>=4&&c<=9)&