基于单片机的自动往返小车
摘要
本设计以一片单片机STC89C52作为核心来控制自动往返小车,加以控制芯片L298N 和单片机联合控制小车的前进与后退。路面的黑带检测使用反射式红外传感器,通过STC89C52对输入的信号进行处理,以动态显示的形式通过一个四位的数码管显示即时里程,另外一个四位数码管动态显示小车行驶时间。以红外传感器对路面黑线检测用,行驶距离使用霍尔元件进行检测。
关键词:光电检测霍尔检测动态显示L298N控制电动机
小组成员:李亚昊、陈国翠、成晓斌、丁玉娇
1.电机驱动调速模块
采用L298N来控制电机的正转和反转来实现小车的前进和后退。加上单片机的程序PWM,实现整车的加速与减速,精确小车的速度。
2.路面黑带检测模块
黑带检测的原理是:红外光线照射到路面并反射,由于黑带和白纸的系数不同,可根据接的红外线的强弱判断是否到达黑带。
反射式的红外发射—接收器。由于采用红外管代替普通可见光管,可以降低环境干扰。
3.电源选择
双电源供电,将电动机驱动电源与单片机以及周边电路电源完全隔离,这样做虽然不如单电源方便灵活,但可以将电动机驱动所造成的干扰彻底消除,提高了系统的稳定性。
4.控制单元模块
用单片机控制
用光电检测不同的信号,并经单片机对其处理,传送给L298信号,使其控制电机的正转和反转,配合PWM程序控制,来实现加速减速和刹车。通过单片机内部定数器/计数器进行定时、
2. STC89C52单片机基本系统
此系统以89C52为核心,每检测到一个黑带由光电检测部分产生一个的脉冲,使单片机产生一个外部中断1,定义检测黑带数的变量加1,同时车轮每转一圈,霍尔元件输出一个脉冲,是安单片机产生一个外部中断0,定义圈数的变量加1.通过P1.0和P1.1控制L298来控制电机的正转与反转及刹车。当P1.0输出低电平,P1.1输出高电平时,电机正转,相反则电机反转,当P1.0和P1.1都是低电平时,使电动机被短路,提高了刹车效率,基本杜绝了由于制动惯性造成的小车的前冲现象。通过P0口进行两
个数码管的位选,P2口进行段码输出,其中一个数码管显示行驶时间,另外一个数码管显示行驶路程。
如图所示:
3. L298N电动机驱动模块部分
该电路采用电动机驱动芯片L298来控制电动机的正转与反转,加以第二路电机电源保证了电动机启动时有足够的电流。在试验中控制电压为单片机输出的高低电平直接控制。
具体电路图连接如下:
4. 电源部分
由于电动机工作电流大,需要选用内阻小,供电电流强,质量轻,可反复使用的经济型电池,我们选用可充电电池组。为使单片机工作稳定,避免电动机开关机和其转动时对其电源的影响,在此用两个电池组和稳压块7805分别为89C52和电动机驱动显示部分分别进行供电。保证小车工作和显示的稳定性。
5.软件设计部分
单片机控制电路主要由一片STC89C52组成,通过P3口控制小车正转与反转,刹车,加速减速,通过两个四联数码管控制显示时间和里程以及小车行驶的时间。其中P0口进行位选,P2口进行显示段码输出。
该系统采用上电复位加上手动复位联合复位系统进行初始化,单片机通过P1.0,P1.1输出脉冲控制电机正转反转以及刹车,当P1.0,P1.1分别输出01是电动机正转,输出10时电动机反转,输出00时电动机两边短路,小车立即刹车。
流程图如下:
(1)外部中断0
车轮美转一次,霍尔元件产生一个脉冲P3.3,通过下降沿触发外部中断0,并且在每进行一次外部中断记录圈数的变量加1.
(2)外中断1
通过下降沿的方式触发外中断1,,p1.1=1,小车的电动机由于短路刹车,当检测到第十二条黑带时,小车再次刹车同时关掉所有中断
(3)定时器中断0
使用定时器T0产生5ms 定时中断,每次执行该中断前要先给定时器0赋初值,定时器中断每执行一次,变量加1。当i=200时,即每当计时1秒时,时间变量t 加1,速度等于一秒转的圈数和小车车轮的周长相乘。
(4
1要赋初值。
(5
四联数码管按位不断循环亮点,当小车行驶时动态显示时间和路程,小车停止时显示小车行驶
过程中的时间和路程。
6.安装与调试
自动小车为玩具遥控小汽车的改装品,在改装的过程中最重要的是考虑设计光电检测管的
位置,检测黑带的光电管放在车体的中央,用遮光管将其以一定反射角度压到跑道上。路程检
测用槽型光耦,放在小车的从动轮上。轮子的周长约为21.6厘米,在轮子上用了一个霍尔元件,
每转一圈一个脉冲。在组装前对每一个单元电路进行测试,以保证外部硬件电路的无误,有利
于最后的统调。调整是以点到线,最后到整体调试的方法。在调整的过程中我们发现了许多问
题,如响应中断的次数的调整等。并且为了小车碰到墙壁不至于停车,我们在小车的四角上都
加上了导向轮,导向轮用随身听的压带轮制作即可。
北京西站列车停运
7.附录元器件及程序如下:
基本元器件列表
40一个STC89C52单片机
2个四位共阳数码管
一个L298N芯片
一个霍尔元件和小磁钢片
一路循迹模块
晶振(12M)及30pf电容
开关
二手沃尔沃s60
电阻10k 100欧姆1k 20k可调
程序:
#include<reg52.h> //包含头文件
#define uint unsigned int //宏常量定义
#define uchar unsigned char //宏常量定义
sbit dianji1=P1^0; //P1_0设置为电机控制一
sbit dianji2=P1^1; //P1_1设置为电机控制二
sbit hdjc=P3^2; //P3_2设置为黑带检测位
uchar code duma[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f}; //段编码
uchar code dianduma[]={
0xbf,0x86,0xdb,0xcf,
0xe6,0xed,0xfd,0x87,
0xff,0xef}; //带小数点段编码
uchar code wema[]={
0x01,0x02,0x04,0x08,
0x10,0x20,0x40,0x80,
0x00,0xff}; //位编码
uchar num,ge,shi,bai,qian; //定义几个字符型变量
uint miao,lc,heidai=0; //定义几个整形变量
long int qs;  //定义一个长整形变量用来记录小车所转的圈数
void fenwei(uint); //声明一个分位函数用来把要显示的数分位
void shuma(uchar,uchar);  //声明一个数码上显示函数用来在数码管上显示数据void shumadian(uchar,uchar); //声明另一个数码显示函数用来显示带小数点的数据void miaoxianshi(uint);  //声明一个显示时间的函数
void lcxs(uint); //声明一个显示路程的函数
void djkz(); //声明一个电机控制函数
void delay(uchar); //声明一个延时函数
void delay10s(); //声明另一个延时函数用来延时十秒钟
void fenwei(uint x) //把需要在数码管上显示的数据分位
{
ktm
g e=x%10;
s hi=(x%100)/10;
b ai=(x%1000)/100;套牌
q ian=x/1000;
}
void shuma(uchar x,uchar y) //将需要显示的数据显示在数码管上
{
P0=wema[8];
P2=duma[x];
P0=wema[y];
d elay(5);
}
void shumadian(uchar x,uchar y) //将需要显示的数据显示在数码管上
{
P0=wema[8];
P2=dianduma[x];
P0=wema[y];
d elay(5);
}
void miaoxianshi(uint x) //将定时器0输出的时间显示在数码管上
奔驰威霆房车{
f enwei(x);
s huma(ge,3);
s huma(shi,2);
s humadian(bai,1);
s huma(qian,0);
}
void lcxs(uint z) //将外部中断1输出的路程显示在数码
{
f enwei(z);
s huma(ge,7);
s huma(shi,6);