单片机寻迹小车Word下载.docx
《单片机寻迹小车Word下载.docx》由会员分享,可在线阅读,更多相关《单片机寻迹小车Word下载.docx(18页珍藏版)》请在冰点文库上搜索。
![单片机寻迹小车Word下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/12/9c015705-3577-4083-8cad-51ba4c876cae/9c015705-3577-4083-8cad-51ba4c876cae1.gif)
我们这里选择了6个反射式光电传感器。
图4表示小车在不同弯道及不同位置时的状态。
我们在调试时将对小车在不同位置情况进行编程,反复测试调试是必需的。
寻迹小车光电检测状态二极管的指示在分析、调试时有重要作用,它不仅可以帮助我们调试寻迹小车的最佳状态,而且可以指示检测是否正常。
图3寻迹小车在不同赛道位置的检测情况
如何更有效地检测赛道的弯曲程度,光电检测的前瞻性是很重要要的。
从前提高前瞻性考虑,可以将光电传感器以不同的排列方式安装。
硬件电路相同,放置方法不同,软件算法却大不相同。
图4光电检测传感器不同放置方法的比较
3.反射式光电传感器外形
寻迹小车采用反射式光电传感器,外形如下图所示。
反射式光电传感器实际由两个独立的器件发光二极管和光敏三极管组成。
从器件上可以看出发光二极管和光敏三极管的引脚。
图5反射式光电传感器外形
4.反射式光电传感器模块
上面的反射式光电传感器还是属于模拟电路,在黑白的边缘时,其输出Y1实际并不能保障输出为0.3V和5V,这对单片机控制是不利的。
为了保证控制的可靠性,在输出端加上施密特整形电路,就构成光电传感器模块。
说明:
此图是对射式光电传感器
图6反射式光电传感器模块
二、电机控制电路
1.直流电机工作特性
首先了解直流电机工作的几个名词术语:
额定工作电压、额定转速、实际转速和堵转。
假设寻迹小车的直流电机的额定电压是9V,在直流电机的电枢上加的电压一般不能超过7V,也就是说,电机的工作电压最大为9V,这时电机的转速最大,空载时达到的转速称为额定转速。
负载越大,实际转速会负载增加而减小。
对寻迹小车来说,电机的负载是一定的。
这时电机加上9V工作电压,小车的速度最大。
如果电机加上电压,负载太大,造成电机转不动,这时称电机“堵转”,电机堵转是很危险的,它会造成电机烧毁。
因此我们要防止电机堵转发生。
直流电机的速度是如何控制的呢?
如果我们改变电机电枢的工作电压,电机的速度就会随之改变。
换句话说,改变直流电机的电压就可以控制电机的速度。
图正确吗?
图7直流电机控制电压与转速的关系
2.PWM用于直流电机控制
单片机控制直流电机不是用调节直流电压大小来控制电机的,而是采用PWM(脉冲宽度调制)信号。
PWM是一个周期固定,占空比可以调节的数字信号。
脉冲宽度调制(PWM)是英文“PulseWidthModulation”的缩写,简称脉宽调制。
它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用于测量,通信,功率控制与变换等许多领域。
PWM有定宽调频法、调宽调频法、定频调宽法,常用定频调宽法。
设PWM周期为T,高电平周期为T1,低电平的周期为T2,如图8(a)所示,T=T1+T2。
PWM占空比定义为:
在一串脉冲序列中,高电平持续的时间与总时间周期之比。
可以认为:
占空比D=T1/T
D的变化范围为0≤D≤1。
当电源电压U不变的情况下,改变的平均值U取决于占空比D的大小,改变D值也就改变了输出电压的平均值,从而达到控制电动机转速的目的,实现PWM调速。
(a)PWM占空比的定义
(b)占空比较大,等效直流电压较高
(c)占空比较小,等效直流电压较低
图8PWM波形图
我们使用的电机一般为直流电机,主要用到永磁直流电机、伺服电机及步进电机三种。
直流电机的控制很简单,性能出众,直流电源也容易实现。
直流电机的驱动及控制需要电机驱动芯片进行驱动。
常用的电机驱动芯片有L298、MC33886、ML4428等。
也可以采用分立元件制作的H桥电路驱动电机。
图9电机驱动芯片L298及电路原理图
L298控制很简单,IN1、IN2、ENA控制电机A工作,IN4、IN4、ENB控制电机B工作。
如果IN1=1(5V高电平)、IN2=0(0V低电平)且使能端ENA为1时,电机A顺时针转动;
如果IN1=0、IN2=1且使能端ENA为1时,电机A逆时针转动;
如果使能端ENA=0时,无论IN1、IN2电平如何,电机A都停止转动。
电机B的道理与电机A相同,不再复述。
L298控制状态如表1所示。
表1L298控制状态
引脚
IN1
IN2
ENA
IN3
IN4
ENB
电机工作状态
控制信号
X
停止
1
顺时针转
逆时针转
L298在使用上可以分为两种方式:
线性放大驱动方式和开关驱动方式。
线性放大驱动方式时,半导体功率器件工作在线性区。
其优点是控制原理简单,输出波动小,线性好,对邻近电路干扰小。
其缺点是功率器件工作在线性区,功耗高和散热问题严重。
开关驱动方式是使半导体功能器件工作在开关状态,通过PWM来控制电机电压,从而实现电机转速的控制。
当驱动信号为高电平时,开关管导通,直流电机电枢绕组两段有电机驱动电压U,T1之后,驱动信号变为低电平,开关截止,电机电枢两端电压为0。
T2之后,驱动信号重新变为高电平,开关管的动作重复前面的过程。
电机的电枢绕组两端的电压平均值U为:
UOUT=(T1×
U)/T=D×
U
式中D为占空比。
(a)电路原理图
(b)印制电路板图
图10L298驱动电路图
L298有两路电源分别为逻辑电源和电机驱动电源J4接入逻辑电源,J6接入电机动力电源,J1、J2分别为单片机控制两个电机的输入端,J3、J5分别与两个电机的正负极相连。
ENA、ENB直接接高电平,使两个电机工作在使能状态。
由于电机是线圈式,电路加入二极管的作用就是在产生反向电流的时候进行泄流,保护驱动芯片的安全。
三、单片机STC89C51
1.STC89C51单片机硬件电路
STC89C51单片机DIP封装引脚如图11所示
STC89C51/52单片机有4个独立的8位输入/输出(I/O)接口。
(1)输入/输出
P0.0~P0.7:
P0口8位双向口线(32~39脚)
P1.0~P1.7:
P1口8位双向口线(1~8脚)
P2.0~P2.7:
P2口8位双向口线(21~28脚
P3.0~P3.7:
P3口8位双向口线(10~17脚)
图11单片机DIP封装外形
(2)控制信号
ALE:
(30脚)地址锁存控制信号。
在系统扩展时,ALE用于控制把P0口输出的低8位地址锁存起来,以实现低位地址和数据的隔离。
当单片机不使用外部总线时,此脚不用。
PSEN:
(29脚)外部程序存储器读选通信号。
在读外部ROM时,低电平有效,以实现外部ROM单元的读操作。
EA:
(31脚)访问程序存储控制信号。
当EA=1时,对ROM的读操作是内部程序存储器开始,并可延至外部程序存储器。
不需要扩展外部存储器时,将接电源VCC。
RST:
(9脚)复位信号。
当输入的复位信号延续两个机器周期以上的高电平时即为有效,用以完成单片机的复位初始化操作。
XTAL1和XTAL2:
(18、19脚)外接晶体引线端。
当使用芯片内部时钟时,此二引线端用于外接石英晶体和微调电容;
当使用外部时钟时,用于接外部时钟脉冲信号。
VSS:
(20脚)地线
VCC:
(40脚)+5V电源。
(3)P3口的第二功能
P3的第二功能涉及到串行口、外部中断、定时器、控制总线控制信号。
如表2所示。
掌握P3口的应用是学习51单片机的重要内容。
表2P3口的第二功能
(4)I/O口应用基本要点
①如果单片机内部有足够的程序存贮器空间,也不需要扩展外部存贮器和I/O接口,单片机的4个口均可作为I/O口使用。
②4个口在作为输入口使用时,均应先对其写“1”,以避免误读端口状态。
③P0口作为I/O口使用时应外接10K的上拉电阻,其它口则可不必。
④P3口的某些口线作第二功能时,剩下的口线可以单独作为I/O口线使用。
⑤I/O口作为通用输入输出功能时,注意其驱动能力。
2.单片机最小系统
单片机工作除了加5V工作电源外,要外接时钟晶体电路和复位电路。
单片机18、19脚为外接晶体电路引脚。
在XTALl和XTAL2两端跨接石英晶体,就构成了稳定的自激振荡器,时钟信号直接送入内部时钟电路。
对STC单片机晶振的频率范围为2~24MHz,一般采用12MHz。
外接晶振时,Cl和C2的值通常选择为20~30pF,Cl、C2对频率有微调作用。
图9单片机最小系统
单片机9脚RET为复位端,在开机上电时产生一个只要大于两机器周期(在晶体为12MHz时,两机器周期为2μs)的高电平即可让单片机复位。
开关S1是上电后的复位开关。
单片机接入电源、时钟电路、复位电路以后,单片机具备了工作的基本硬件工作条件,这样的单片机系统称为单片机最小系统。
单片机最小系统如图9所示。
2.STC89C51输入/输出功能
用于控制寻迹小车的光电检测信号、按键控制等信号送入单片机,称为单片机输入;
单片机控制电机速度、显示等称为单片机输出。
单片机输入/输出功能应用时,必须遵守如前所述的I/O口应用基本要点。
本文不是单片机教材,仅以寻迹小车应用进行说明。
假设光电检测信号P11~P16与单片机P1口的P1.0~P1.5连接,P2.0~P2.5与电机驱动模块L298相连,如图9、图10所示。
图10寻迹小车L298电机驱动电路
单片机I/O口在作为输入口使用时,均应先对其写“1”,再读入I/O口状态,以避免误读端口状态。
例如用汇编语言编写程序:
MOVP1,#11111111B;
对P1口写1,准备读P1口的状态
MOVA,P1;
将P1口的状态读入CPU的A累加器
P1连接的传感器信号只有先读到A中,单片机才能进行处理。
如果控制左右两个电机正转,使用单片机输出功能。
按表1可以得到控制字:
11110101B=0F5H,我们只要将0F5H送到P2口即可,程序如下:
MOVA,#0F5H
MOVP1,A
你可能已经发现,单片机I/O口输入和输出都要经过累加器A。
上面的汇编程序的理解对学习51单片机很有用。
下面我们采用C51程序编写控制电机正反转程序如下:
/*****************************************
实现电机的方向控制的宏定义
******************************************/
#include<
reg51.h>
51单片机头文件
#defineucharunsignedchar
#defineuintunsignedint
端口定义
sbits1=P1^0;
//电机正转开关
sbits2=P1^1;
//电机反转开关
sbita1=P2^0;
//P2.0与电机驱动IN1相连
sbita2=P2^1;
//P2.1与电机驱动IN2相连
sbita3=P2^2;
//P2.2与电机驱动IN3相连
sbita4=P2^3;
//P2.3与电机驱动IN4相连
sbitPWMA=P2^4;
//P2.4与电机A使能相连
sbitPWMB=P2^5;
//P2.4与电机B使能相连
正转反转函数
voidTurn_Go(void)//两电机正转
{
PWMA=1;
PWMB=1;
a1=1;
a2=0;
a3=1;
a4=0;
}
voidTurn_Back(void)//两电机反转
a1=0;
a2=1;
a3=0;
a4=1;
主函数
main()
while
(1)
{
if(s1==0)
Turn_Go();
elseif(s2==0)
Turn_Back();
}
参见L298电机驱动仿真
在淘宝网上有许多L298控制模块,如图11所示。
图11L298驱动模块
四、电源电路
小车需要+5V和7.2V~9V两种电源,寻迹小车电源电路如图12所示。
寻迹小车由7.2V~9V电池供电,从POWER端接入。
7.2V~9V电压一方面直接向L298的Vs端向电机供电,一方面通过三端稳压器2940转换成+5V,向单片机和L298的VCC端供电。
图中开关S2可以接通和切断电池供电,电容C5、C6起到滤波作用。
图12寻迹小车电源电路
reg52.h>
#definestd_speed100//标准速度
#definef_speed80//第一速度
#defines_speed25//第二速度
#definet_speed8//第三速度
#defineL_add3//补充速度
sbitl3=P1^0;
//左边最外传感器接P1.0
sbitl2=P1^1;
//左边中间传感器接P1.1
sbitl1=P1^2;
//左边内侧传感器接P1.2
sbitr1=P1^3;
//右边内侧传感器接P1.3
sbitr2=P1^4;
//右边中间传感器接P1.3
sbitr3=P1^5;
//右边最外传感器接P1.3
sbito1=P2^0;
//电机控制信号
sbito2=P2^1;
sbito3=P2^2;
sbito4=P2^3;
sbitml=P2^5;
//L298电机A驱动使能
sbitmr=P2^4;
//L298电机B驱动使能
intbeforelever=0;
//定义变量
intlever=0;
intlastlever=0;
unsignedintLPWM,RPWM;
voiddelay(unsignedintt)
inti,j;
for(i=0;
i<
t;
i++)
for(j=0;
j<
150;
j++);
voiddetece()//信号灯检测程序
lever=0;
if(l3==1)lever=-3;
if(l2==1)lever=-2;
if(l1==1)lever=-1;
if(r1==1)lever=1;
if(r2==1)lever=2;
if(r3==1)lever=3;
if(l1==1&
&
r1==1)lever=0;
if(l1==0&
l2==0&
l3==0&
r1==0&
r2==0&
r3==0)lever=10;
voidPWM(unsignedintl,unsignedintr)//PWM设置程序
if(l>
100)l=100;
定宽调频法调制为0——100范围
if(r>
100)r=100;
if(l<
0)l=0;
if(r<
0)r=0;
if(LPWM>
=l)ml=0;
//L298左电机使能信号设置使能信号与pwm同步变化,从而控制电机转速
elseml=1;
if(RPWM>
=r)mr=0;
//L298右电机使能信号
elsemr=1;
=100)LPWM=0;
//LPWM高电平≥100时置LPWM为低电平
if(RPWM>
=100)RPWM=0;
voidcontrol()//电机控制程序
switch(lever)
case-3:
PWM(t_speed+L_add,f_speed);
break;
//lever=-3最左边的传感器检测到,左轮11/100的速度右轮80/100速度既右大转
case-2:
PWM(s_speed+L_add,std_speed);
左28%右100%右中转
case-1:
PWM(f_speed+L_add,std_speed);
左83%右100%右小转
case0:
PWM(std_speed+L_add,std_speed);
case1:
PWM(std_speed+L_add,f_speed);
case2:
PWM(std_speed+L_add,s_speed);
case3:
PWM(f_speed+L_add,t_speed);
}
voidmain()
P1=0x3f;
o1=1;
o2=0;
o3=1;
o4=0;
TMOD=0x01;
TH0=(65536-1000)/256;
//TH0=(65536-x)/256x为xuS
TL0=(65536-1000)%256;
//TL0=(65536-x)%256
TR0=0;
//关T0定时器
ET0=0;
//关T0定时中断
TR0=1;
//开T0定时器
ET0=1;
EA=1;
PWM(0,0);
delay(1000);
detece();
if(lever==10&
lastlever==-3)lever=-3;
//确保进入轨道不偏离轨道
lastlever==3)lever=3;
control();
if(lastlever!
=lever)lastlever=lever;
voidtime()interrupt1//定时器中断函数
TH0=(65536-100)/256;
TL0=(65536-100)%256;
LPWM++;
//开始产生pwm波形
RPWM++;