基于单片机的智能小车的设计.docx
《基于单片机的智能小车的设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的智能小车的设计.docx(18页珍藏版)》请在冰豆网上搜索。
基于单片机的智能小车的设计
基于单片机的智能小车的设计
题目:
智能画画小车
参赛队员:
邹蓉、洪峥
摘要:
该设计采用单片机STC89C51RC作为智能小车的检测和控制核心。
路径长度检测采用红外对管和编码盘来完成,由L298控制驱动电机正反转的快速切换,利用PWM技术控制小车的运动速度及运动方向,达到控制小车运动的路径长度和转角度数,以实现安装在小车上的画笔在画板上画出所需的图形。
关键字STC89C52单片机红外传感器L298N
第二章:
方案说明
2.1方案论证
根据题目要求,系统可以划分为四个模块:
电源模块,主控模块,电机驱动模块和光电检测模块。
(1)电源模块
方案一:
采用实验室有线电源通过稳压芯片供电,其优点是可稳定的提供5V电压,但占用资源过大。
方案二:
采用4支1.5V电池单电源供电,但6V的电压太小不能同时给单片机与与电机供电。
方案三:
采用4支1.5V电池和一支9V蓄电池组成的双电源分别给单片机与电机供电可解决方案二的问题,且能让小车完成其功能。
所以,我们选择了方案三来实现供电。
(2)主控模块
方案一:
选用一片CPLD(如EPM7128LC84-15)作为系统的核心部件,实现控制与处理的功能。
CPLD具有速度快、编程容易、资源丰富、开发周期短等优点,可利用VHDL语言进行编写开发。
但CPLD在控制上较单片机有较大的劣势。
同时,CPLD的处理速度非常快,而小车的行进速度不可能太高,那么对系统处理信息的要求也就不会太高,在这一点上,MCU就已经可以胜任了。
若采用该方案,必将在控制上遇到许许多多不必要增加的难题。
为此,我们不采用该种方案,进而提出了第二种设想。
方案二:
采用单片机作为整个系统的核心,用其控制行进中的小车,以实现其既定的性能指标。
充分分析我们的系统,其关键在于实现小车的自动控制,而在这一点上,单片机就显现出来它的优势——控制简单、方便、快捷。
这样一来,单片机就可以充分发挥其资源丰富、有较为强大的控制功能及可位寻址操作功能、价格低廉等优点。
因此,这种方案是一种较为理想的方案。
针对本设计特点——多开关量输入的复杂程序控制系统,需要擅长处理多开关量的标准单片机,而不能用精简I/O口和程序存储器的小体积单片机,D/A、A/D功能也不必选用。
根据这些分析,我们选定了P89C51RC单片机作为本设计的主控装置,51单片机具有功能强大的位操作指令,I/O口均可按位寻址,程序空间多达8K,对于本设计也绰绰有余,更可贵的是51单片机价格非常低廉。
在综合考虑了传感器、两部电机的驱动等诸多因素后,我们决定采用一片单片机,充分利用STC89C51单片机的资源。
(3)电机驱动模块
方案一:
采用继电器对电动机的开或关进行控制,通过开关的切换对小车的速度进行调整.此方案的优点是电路较为简单,缺点是继电器的响应时间慢,易损坏,寿命较短,可靠性不高。
方案二:
采用电阻网络或数字电位器调节电动机的分压,从而达到分压的目的。
但电阻网络只能实现有级调速,而数字电阻的元器件价格比较昂贵。
更主要的问题在于一般的电动机电阻很小,但电流很大,分压不仅回降低效率,而且实现很困难。
方案三:
采用功率三极管作为功率放大器的输出控制直流电机。
线性型驱动的电路结构和原理简单,加速能力强,采用由达林顿管组成的H型桥式电路(如图2.1)。
用单片机控制达林顿管使之工作在占空比可调的开关状态下,精确调整电动机转速。
这种电路由于工作在管子的饱和截止模式下,效率非常高,H型桥式电路保证了简单的实现转速和方向的控制,电子管的开关速度很快,稳定性也极强,是一种广泛采用的PWM调速技术。
现市面上有很多此种芯片,我们选用了L298N。
这种调速方式有调速特性优良、调整平滑、调速范围广、过载能力大,能承受频繁的负载冲击,还可以实现频繁的无级快速启动、制动和反转等优点。
因此决定采用使用功率三极管作为功率放大器的输出控制直流电机。
(4)光电检测模块
方案一:
应用软件中的中断和定时器来设计软件控制,但是编写这种程序复杂且精度较低,调试很困难,占用资源也较多,断电后时钟会停止运行,供电后时间显示出现错误。
方案二:
采用红外对射检测,电路简单,精度高,只要将检测到的高低电平数据读取送到单片机即可,占用资源少,供电后时间显示不会出现错误。
鉴于以上的比较分析,采用第二种方案。
2.2总体方案
概述
本设计以STC89C52单片机系统为控制中心,通过红外传感器模块中的两路传感器检测两端车轮转速进而换算为路程,传感器在接通电源后会不断的发送和接收红外线,接收到的信号经过LM339进行放大然后转换成数字信号输出,而当单片机检测到行进距离足够时调用转向程序,单片机通过改变PWM波的占空比来调整小车两侧的电机转速,从而使其两侧轮产生速度差,以实现小车的转向。
PWM:
脉冲宽度调制(PWM),简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,此处我们主要通过单片机输出PWM波同时通过调节其占空比来实现对小车的控制。
第三章:
硬件电路设计
3.1、主控电路
本模块主要是采集信号并进行分析,同时输出PWM波控制电机速度,从而控制小车前进转弯等动作。
其中,此处采用STC89C51单片机作为主控芯片,由9—12V直流电通过78M05稳压芯片后进行供电;除此之外,单片机引脚全部通过排针引出,使得此电路连接其他模块更加方便。
复位及时钟电路分别见图2和图3,单片机引脚电路见附录1
图3时钟电路
图2复位电路
3.2LM2940稳压器
LM2940是我们最常用到的稳压芯片,本设计中采用7节5号干电池进行供电,电容C2、C3对输入到LM2940前的直流电进行滤波,之后输入到LM2940,经其稳压后输出5V直流电,给单片机供电。
如图。
3.3L298N电机驱动模块
该模块采用了L298N双H桥直流电机驱动芯片,驱动电机部分VIN采用+9V直流电源供电,同时模块上安装了LM2940稳压器对vin的输入进行稳压,逻辑部分VCC采用+5V供电,小车运行时通过单片机向该模块1、2、3、4脚输入控制信息来控制小车电机的转速。
其电路如下图。
L298N内部包含4通道逻辑驱动电路。
可以方便的驱动两个直流电机,或一个两相步进电机。
输出电压最高可达50V,可以直接通过电源来调节输出电压;用单片机的IO口提供信号;而且电路简单,使用比较方便。
L298N可接受标准TTL逻辑电平信号VSS,VSS可接4.5~7V电压。
4脚VS接电源电压,VS电压范围VIH为+2.5~46V。
输出电流可达2A,可驱动电感性负载。
1脚和15脚下管的发射极分别单独引出以便接入电流采样电阻,形成电流传感信号。
L298可驱动2个电动机,OUT1,OUT2和OUT3,OUT4之间可分别接电动机。
控制逻辑见表2[8]
电机
旋转方式
控制端IN1
控制端IN2
控制端IN3
控制端IN4
输入PWM信号改变脉宽可调速
调速端A
调速端B
M1
正转
1
0
/
/
1
/
反转
0
1
/
/
1
/
停止
0
0
/
/
1
/
M2
正转
/
/
1
0
/
1
反转
/
/
0
1
/
1
停止
0
0
/
/
/
1
3.4光电检测模块
用一个红外发光二极管和一个接受红外光的二极管组成一套光电管。
当检测到物表面为黑色时,反射光很弱,接收端检测到的光线可以忽略,使接收端呈现一种状态,例如开关管截止;当被检测物表面为白色时,反射光强烈,发射端发射的红外线被接收端全部接收,使接收端呈现另一种相反的状态,例如开关管开通。
这两种相反的状态表现在电路中,就是高低电平组成的脉冲信号。
由此,我想到用一个比较器来比较两种接受到的信号,从而输出“0”“1”两种高低电平,并把两种信号传给单片机进行统计,然后利用设定算法进行计算。
LM339内部包括有四个独立的、高增益、内部频率补偿的运算放大器,适合于电源电压范围很宽的单电源使用,也适用于双电源工作模式,在推荐的工作条件下,电源电流与电源电压无关。
它的使用范围包括传感放大器、直流增益模块和其他所有可用单电源供电的使用运算放大器的场合。
RPR220是光电对管。
3.5机械部分
小车采用了两个直流电机为其提供动力,这使其具有较大动力,可以在较大的坡道上行驶;同时,小车的万向轮设计,使得小车的直线行驶性能较强,不会出现方向跑偏的现象,同时转向时的方向感较好;小车的电路部分均用铜柱及螺丝固定在底盘上,使其具有很好的稳定性;除此之外,在接线方面,各模块之间均采用杜邦线进行连接,主控板上焊接了单片机插座,这些为小车提供了充足的再开发空间。
第四章软件系统设计
4.1程序流程图
4.2程序设计方案
本系统编程部分采用C语言编写完成,应用模块化的设计方法,各子程序做为实现各部分功能和过程,通过主程序不断对子程序的调用完成PWM脉宽控制、延时以及电机转动方向控制等部分的设计。
PWM脉宽控制:
本设计中采用定时器0产生定时中断来控制P1.0与P1.1的输出从而生成PWM波。
中断程序如下:
voidtime0(void)interrupt1
{
i++;
j++;
if(i<=pro_right){en1=1;}
elseen1=0;
if(i==40){en1=~en1;i=0;}
if(j<=pro_left){en2=1;}
elseen2=0;
if(j==40){en2=~en2;j=0;}
TH0=(65536-100)/256;
TL0=(65536-100)%256;
}
②左右转向子程序:
通过改变左右PWM波的占空比,来实现电机的速度控制;当小车需要左转弯时,将控制左侧电机的PWM波占空比设置为20,右侧设置为20,左电机反转,右电机不变,当小车需要右转时则相反。
左转弯子程序:
voidturn_left(){
pro_right=20;
pro_left=20;
left1=0;
left2=1;
right1=1
right2=0
}
右转弯子程序:
voidturn_right()
{
pro_right=40;
pro_left=0;
left1=1;
left2=0;
right1=1;
right2=0;
}
第五章结束语
本系统采用MSC-51系列单片机STC89C51、L298N电机控制芯片和红外传感器来设计智能小车,实现了小车的直线行驶和90度转弯的设计功能。
不足之处在于距离的控制精度尚待提高,可采用更精准的光电码盘来完善。
参考文献:
[1]郭天祥.新概念51单片机C语言教程——入门、提高、开发、拓展全攻略[M].北京:
电子工业出版社,2009
[2]蔡美琴MCS-51系列单片机系统及其应用[M].北京:
高等教育出版社,2002
[3]冯建华,赵亮单片机应用系统设计与产品开发[M].北京:
人民邮电出版社2004
[4]童诗白,华成,模拟电子技术基础(第四版)[M].高等教育出版社,2006.5
[5]阎石.数字电子技术基础(第五版)[M].北京:
高等教育出版社,2005
[6]陈忠平,51单片机C语言程序设计经典实例[M].电子工业出版社
附录1:
总电路图
附录2:
总程序
#include
#defineucharunsignedchar
#defineuintunsignedint
ucharpro_left=35,pro_right=35,i,j;//左右占空比标志
uchara;
sbitleft1=P2^0;//左右电机
sbitleft2=P2^1;
sbitright1=P2^2;
sbitright2=P2^3;
sbiten1=P1^0;
sbiten2=P1^1;
voiddelay(uintz)//z毫秒延迟
{
uchari;
while(z--)
{for(i=0;i<121;i++);}
}
voidinit()//初始化程序
{
EX0=1;
IT0=1;
TMOD=0X01;
TH0=(65536-100)/256;
TL0=(65536-100)%256;
EA=1;
ET0=1;
TR0=1;
en1=1;
en2=1;
}
voidtime0(void)interrupt1//time0定时器,控制占空比
{
i++;
j++;
if(i<=pro_right){en1=1;}
elseen1=0;
if(i==40){en1=~en1;i=0;};
if(j<=pro_left){en2=1;}
elseen2=0;
if(j==40){en2=~en2;j=0;};
TH0=(65536-100)/256;
TL0=(65536-100)%256;
}
voidcount0()interrupt0//中断,计数
{
delay(100);
if(INT0==0)
a++;
}
voidstraight()//走直线函数
{
pro_right=20;
pro_left=20;
left1=1;
left2=0;
right1=1;
right2=0;
}
voidturn_left()//左转弯函数
{if(a<13)
{
pro_right=20;
pro_left=20;
left1=0;
left2=1;
right1=1;
right2=0;
}
else
{a=0;}
}
voidturn_right()//右转弯函数
{if(a<13)
{
pro_right=20;
pro_left=20;
left1=1;
left2=0;
right1=0;
right2=1;
}
else
{a=0;}
}
main()//主函数
{ucharkey,flag;
while
(1)
{
while(P0!
=0xFF);
{
delay(10);
while(P0!
=0xFF);
{
key=P0;
switch(key)
{
case(0xFE):
flag=1;break;//检测按键
case(0xFD):
flag=2;break;
case(0xFB):
flag=3;break;
case(0xF7):
flag=4;break;
case(0xEF):
flag=5;break;
case(0xDF):
flag=6;break;
case(0xBF):
flag=7;break;
case(0x7F):
flag=8;break;
}
}
}
init();//初始化
switch(flag)//选择程序1-8
{
case
(1):
if(a<44){straight();};break;
case
(2):
if(a<86){straight();};break;
case(3):
if(a<107){straight();};break;
case(4):
if(a<44){straight();}elsea=0;
turn_left();delay(1000);
if(a<65){straight();}elsea=0;
turn_left();delay(1000);
if(a<44){straight();}elsea=0;
turn_left();delay(1000);
if(a<47){straight();};break;
case(5):
if(a<65){straight();}elsea=0;
turn_left();delay(1000);
if(a<65){straight();}elsea=0;
turn_left();delay(1000);
if(a<65){straight();}elsea=0;
turn_left();delay(1000);
if(a<17){straight();}elsea=0;
turn_left();delay(1000);
if(a<33){straight();}elsea=0;
turn_right();delay(1000);
if(a<33){straight();}elsea=0;
turn_right();delay(1000);
if(a<33){straight();}elsea=0;
turn_left();delay(1000);
if(a<19){straight();};break;
case(6):
if(a<65){straight();}elsea=0;
turn_left();delay(1000);
if(a<65){straight();}elsea=0;
turn_left();delay(1000);
if(a<65){straight();}elsea=0;
turn_left();delay(1000);
if(a<67){straight();}elsea=0;
turn_left();delay(1000);
if(a<33){straight();}elsea=0;
turn_left();delay(1000);
if(a<67){straight();}elsea=0;
turn_left();delay(1000);
if(a<33){straight();}elsea=0;
turn_left();delay(1000);
if(a<33){straight();}elsea=0;
turn_left();delay(1000);
if(a<67){straight();};break;
case(7):
if(a<86){straight();}elsea=0;
turn_right();delay(1000);
if(a<86){straight();}elsea=0;
turn_left();delay(1000);
if(a<44){straight();}elsea=0;
turn_left();delay(1000);
if(a<44){straight();}elsea=0;
turn_left();delay(1000);
if(a<86){straight();}elsea=0;
turn_right();delay(1000);
if(a<50){straight();};break;
default:
break;
}
}
}