1、 DIY达人赛 基于 STC89C52 单片机智能寻迹小车 实 验 报 告 参赛队伍: 队员: 2014年4月 一、引言 我们所处的这个时代是信息革命的时代,各种新技术、新思想层出不穷,纵 观世界范围内智能汽车技术的发展,每一次新的进步无不是受新技术新思想的推 动。 随着汽车工业的迅速发展,传统的汽车的发展逐渐趋于饱和。伴随着电子技 术和嵌入式技术的迅猛发
2、展,这使得汽车日渐走向智能化。智能汽车由原先的驾 驶更加简单更加安全更加舒适,逐渐的向智能驾驶系统方向发展。智能驾驶系统 相当于智能机器人,能代替人驾驶汽车。它主要是通过安装在前后保险杠及两侧 的红外线摄像机,对汽车前后左右一定区 域进行不停地扫描和监视。计算机、 电子地图和光化学传感器等对红外线摄像 机传来的信号进行分析计算,并根据 道路交通信息管理系统传来的交通信息,代替人的大脑发出指令,指挥执行系统 操作汽车。 1、来源 汽车的智能化是 21 世纪汽车产业的核心竞争力之一。 汽车的智能化是以迅猛发展的汽车电子为背景,涵盖了控制、模式识别、传 感技术、电子、电气、计算机、机械等多个学科
3、交叉的科技。 2、智能汽车国外发展情况 从 20 世纪 70 年代开始,美国、英国、德国等发达国家开始进行无人驾驶汽 车的研究,目前在可行性和实用化方面都取得了突破性的进展。目前日本、欧美已有企业取得实用化成果。与国外相比,国内在智能车辆方 面的研究起步较晚,规模较小,开展这方面研究工作的单位主要是一些大学和研究所,如国防科技大学、清华大学、吉林大学、北京理工大学、长安大学、沈阳 自动化所等。 我国从 20 世纪 80 年代开始进行无人驾驶汽车的研究,国防科技大学在 1992 年成功研制出我国第一辆真正意义上的无人驾驶汽车。先后研制出四代无人驾驶汽车。第四代全自主无人驾驶汽车于 2000
4、年 6 月在长沙市绕城高速公路上进行 了全自主无人驾驶试验,试验最高时速达到 75.6Km/h。 3、我们的小车 我们做的是基于 STC89C52单片机开发,主要是研究 3 轮小车的路径识别及其 遥控运动。 二、智能寻际小车基本原理 1、红外寻迹原理 探测路面黑线的基本原理:光线照射到路面并反射,由于黑线和白纸对光的 反射系数不同,可以根据接收到的反射光强弱来判断是否是黑线。利用这个原理, 可以控制小车行走的路迹。 这里的循迹是指小车在白色地板上循黑线行走,通常采取的方法是红外探测法。 红外探测法,即利用红外线在不同颜色的物体表面具有不同的反
5、射性质的特点,在小车行驶过程中不断地向地面发射红外光,当红外光遇到白色纸质地板时发生漫反射,反射光被装在小车上的接收管接收;如果遇到黑线则红外光被吸收, 小车上的接收管接收不到红外光。处理器就根据是否收到反射回来的红外光为依 据来确定黑线的位置和小车的行走路线。红外探测器探测距离有限,一般最大不应超过 3cm。 2、驱动原理:利用L298N构成电机驱动电路。 2.1 L298N 的恒压恒流桥式 2A 驱动芯片 L298N引脚介绍: #1和15和8引脚直接接地; #4管脚VS接2.5到46的电压,它是用来驱动电机的。 #9引脚是用来接4.5到7V的电压
6、的,它是用来驱动L298芯片的,L298需要从外部接两个电压,一个给电机,一个给芯片。 #6和11引脚是使能端,一个使能端控制一个电机,至于控制哪个取决自己。可以理解为总开关,只有都是高电平的时候两个电机才能工作。 #5,7,10,12是298的信号输入端,和单片机的IO口连接。2,3,13,14是输出端。 #输入5和7控制输出2和3,输入的10,12控制输出的13,14. 1;L298N是SGS公司产品,内部包含4通道逻辑驱动电路,是一种二相和四相电机的专用驱动器,即内含二个H桥的高电压大电流双全桥式驱动器,接收标准TTL逻辑电平信号,可驱动46V,2A以下的电机。
7、 2;OUT1,OUT2,和OUT3,OUT4直接分别接2个电动机。TN1,TN2,TN3,TN4引脚从单片机接输入控制电平,控制电机的正反转,ENA,ENB接控制使能端,控制电机的停转。 3;对于电机的调速,我们采用PWM调速的方法。其原理就是开关管在一个周期内的导通时间为t,周期为T。VCC是电源电压。电机的转速与电机两端的电压成正比,而电机两端的电压与控制波形的占空比成正比,因此电机的速度与占空比成比例。在硬件电路的连接上,我们将单片机的P2.0~P2.3口分别连接到298的IN1~IN4上,通过改变P2.0~P2.3上的高低电平变化以控制小车的前进方向,通过改变P2.0~
8、P2.3口上的高低电压的占空比以控制电机的转速。 4;PWM配合桥式驱动电路L298N,实现直流电机调速,非常简单,且调速范围大。另外我们特别在直流电机的电驱两端并联一个磁片电容104,以稳定电机的电压不致对单片机造成干扰,实际效果不错,省掉了通过光耦隔离TPL521实现单片机输出信号与电机驱动信号隔离 2.2驱动板电路原理: 该驱动板需要7.2电源供电,但L298的逻辑参考电平为典型的TTL电平。用了一个L1117稳压芯片是为了提供稳定的5V输出电压和逻辑参考电压。D9,D10,D11和D12是发光二极管,指示运动方向,与它们连接的电阻是限流电阻。R5,R8是下拉电
9、阻,让ENB和ENB要么是高电平,要么是低电平,避免电平混乱,提高对输入信号的抗干扰能力。输出端都接有0.1uf电容,加上二极管平衡电路。都是为了保护L298N,电机是感性负载,当给电机突然通电和断电,因为电流的瞬变,电机两端会产生瞬时高电压和大电流。如果没有保护措施,L298会被损害。 3 智能小车舵机控制原理 利用舵机灵活控制超声波探头 1800°旋转,可以实现小车的全方位避障。 什么是舵机 在机器人机电控制系统中,舵机控制效果是性能的重要影响因素。舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得单片机系统非常容易与之接口。舵机是
10、一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。 舵机工作原理 控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有 一个基准电路,产生周期为 20ms,宽度为 1.5ms 的基准信号,将获得的直流偏 置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机 驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器 旋转,使得电压差为 0,电机停止转动。 舵机的控制 舵机的控制一般需要一个 20ms 左右的时基脉冲,该脉冲的高电平部分一 般为 0.5ms~2.5ms 范围内的角度控制脉冲部分。
11、以 180 度角度伺服为例,那么对 应 的控制关系是这样的: 0.5ms--------------0 度; 1.0ms------------45 度; 1.5ms------------90 度; 2.0ms-----------135 度; 2.5ms-----------180 度; 4. 智能小车避障基本原理 小车避障是利用超声波测距,并根据测出离障碍物不同距离而做出不同反应。 超声波测距模块简介 检测距离:5CM-5M 分辨率:5MM 数字电平信号,可直接接单片机,无需任
12、何辅助电路,也无需单片机产生任何信号辅助,距离和模块输出信号脉冲长度成正比。 尺寸:43.5*20.5 毫米 高度:13.8 毫米 2.5.2 . 超声波测距原理 你只需要提供一个短期的 10uS 脉冲触发信号。该模块内部将发出 8 个 40kHz 周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号是一个脉冲的宽度 成正比的距离对象。可通过发射信号到收到的回响信号时间间隔可以计算得到距式:uS/58= 厘米或者 uS/148=英寸。建议测量周期为 60ms 以上,以防止发射信号对回响信号的影响. 5. 智能小车液晶显示原理 加入液晶显示一方面是为了弥补数
13、码管显示的局限性,其次是为了显示小车的运动状 态,离前方障碍物距离,循迹状态,是否遇到黑线,后退,前进还是转 向,作为一个控制平台,实现小车的灵活控制。 液晶显示原理 液晶显示其实就是对屏幕的每个点的扫描,带字库的液晶内部自带控制芯片,直接对它操作就可以显示出汉子字符,需要读写命令和数据,才能达到对液晶控制器的操作。 6. 避障模块电路设计 小车避障模块由超声波和舵机两部分组成,超声波测量距离障碍物的距离, 舵机来控制超声波探头的 180°旋转,从而达到全方位的避障控制。 7.电源 我们用的是六节干电池,用LM2940s降压。原理图如下 8.红外通信原理
14、通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用电路芯片来进行控制操作。 遥控器在按键按下后,周期性地发出同一种 32 位二进制码,周期约为 108ms。 当一个键按下超过 36ms,振荡器使芯片激活,将发射一组 108ms 的编码脉冲,这 108ms 发射代码由一 个起始码(9ms),一个结果码(4.5ms),低 8 位地址码(9ms~18ms),高 8 位地址码(9ms~18ms),8 位数 据码(9ms~18ms)和这 8 位数据的反码(9ms~18ms)组成。 接收器及解码 一体化红外线接收器是一种集红外线接收和放大于一体,不需要任何外接元件,就能完成从红外
15、线接收到输出与TTL电平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输。 VS1838B 三、材料准备 1.小车底盘,电机。我们从淘宝网上买的车模,他们直接组装好的。 2.四路红外探测系统。 3.超声波探测模块。 4.舵机、液晶 5.STC89C52,L298N,LM2940S,VS1838B,IN5819。瓷片电容104 四、实验过程 i. 我们先做了单片机STC89C52最小系统。以及稳压电路。 ii. 我们用L298N以及IN5819,104电容照前边原理图搭
16、建了驱动电路。
iii. 第三阶段做红外探测,用的是LM339,红外发射、接收二极管,好多次都失败了,最后我们就买了四路红外探测系统。调试时发现还不太好用,就换掉了滑动变阻器。
iv. 第四阶段我们对小车进行组装,加上了液晶显示器,超声波模块,舵机(带动超声波探头),红外一体化接收头。
v. 最后阶段对小车进行总体调试。
五、程序
1. 一些定义
#include
17、ar //宏定义 #define uint unsigned int sbit out1 = P2^2;//电机驱动输出控制管脚配置 sbit out2 = P2^3; sbit out3 = P2^0; sbit out4 = P2^1; sbit ena=P3^7; sbit enb=P3^6; sbit SPK=P3^5; sbit in1 = P0^1;//循迹模块的信号输入管脚配置 sbit in2 = P0^2; sbit in3 = P0^3; sbit in4 = P0^4; sbit RS = P2^4; //定义端口 sbit RW =
18、P2^5; sbit EN = P2^6; sbit pwm=P0^0; sbit ECHO=P3^3; sbit TRIG= P3^4; extern unsigned char Y0;//外部链接变量 #define RS_CLR RS=0 #define RS_SET RS=1 #define RW_CLR RW=0 #define RW_SET RW=1 #define EN_CLR EN=0 #define EN_SET EN=1 #define DataPort P1 long S=0; 2. 驱动程序 void qian
19、jin()//使小车向前行驶 {ena=enb=1; out2=out4=1; } void zuozhuan()//控制小车做轻微左转动作 { ena=enb=1; out1=0; out2=out3=out4=1; } void youzhuan()//控制小车做轻微右转? { ena=enb=1; out1=out2=out4=1; out3=0;} void zuozhuan1()//控制小车做左转动作 { ena=enb=1; out1=out4=0; out2=out3=1; } void youzhuan1()/
20、/控制小车做右转动作 { ena=enb=1; out1=out4=1; out2=out3=0; } void houtui()//控制小车可以使小车倒退行驶 { ena=enb=1; out1=out3=1; out2=out4=0; } void tingzhi () //使小车停止当前所有动? { ena=enb=1; out1=out2=out3=out4=1; } void TIM2Inital(void) //用定时器2 { RCAP2H = (65536-100)/256;//晶振12M 60ms
21、 16bit 自动重载
RCAP2L = (65536-100)%256;
ET2=1; //打开定时器中断
EA=1; //打开总中断
}
void TIM2(void) interrupt 5 using 1//定时器2中断 输出不同PWM信号
{TF2=0;
count++; //对小车调速
if(count 22、unt%50;
}
3. 液晶显示函数
bit LCD_Check_Busy(void) //判忙
{
DataPort= 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}
void LCD_Write_Com(uchar com) //命令
{
while(LCD_Check_Busy()); //忙则等待
RS_CLR;
RW_CLR;
EN_SE 23、T;
DataPort= com;
_nop_();
EN_CLR;
}
void LCD_Write_Data(uchar Data) //写数据
{
while(LCD_Check_Busy()); //忙则等待
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
}
void LCD_Clear(void) //清屏
{
LCD_Write_Com(0x01);
delay(5);
}
void L 24、CD_Write_String(uchar x,uchar y,uchar *s)/******写字符串*****/
{
if (y == 0)
{
LCD_Write_Com(0x80 + x); //表示第一行
}
else
{
LCD_Write_Com(0xC0 + x); //表示第二行
}
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
25、
}
void LCD_Write_Char(uchar x,uchar y,uchar Data) /******写单个字符**/
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
void LCD_Init(void) //初始化
{
LCD_Write_ 26、Com(0x38); /*显示模式设置*/
delay(7);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
delay(7);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
4.超声波检测
unsigned int time=0;
bit flag =0;
void Conut(vo 27、id)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=time*1.7/100; //算出来是CM 12M晶振
}
void StartModule()
{
TRIG=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_( 28、); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
TRIG=0;
StartModule();
while(!ECHO); //当ECHO为零时等待
TR0=1; //开启计数
while(ECHO); //当ECHO为1计数并等待
TR0=0;
Conut();
}
void disp(void) //液晶显示障碍距离
{
LCD_Write_Ch 29、ar(8,1,'0'+S%1000/100);
LCD_Write_Char(9,1,'0'+S%1000%100/10);
LCD_Write_Char(10,1,'0'+S%1000%10 %10);
}
5.避障程序
void bizhang()
{
uchar a;
StartModule();
delay(5);
if(S<13)
{delay(10);
if(S<13)
{
TR2=0;delay(2);tingzhi();delay(3);
LCD_Cle 30、ar();//清屏
delay(20);
LCD_Write_String(5,0,"Barrier");delay(5);
for(a=0;a<200;a++) //蜂鸣器报警
{
DelayUs2x(200);
SPK=!SPK;
}
SPK=0;//防止一直给喇叭通电造成损坏
for(a=0;a<200;a++)
{
delay(1);
}
delay(2);
youzhu 31、an();delay(600);
}
TR1=1; //开PWM/*******舵机转动****
shu1=2; //45度角
delay(500);
Conut();
zuo=S;
shu1=4; //135度角
delay(500);
Conut();
you=S;
shu1=3; //90度角,
if(zuo>you) //判断左右转
{ zuoz 32、huan();delay(400);}
else
{ youzhuan();delay(400); }
TR1=0; //关PWM
}
void init_pwm() //定时器1控制舵机带动超声波模块摇头
{
TMOD|=0X10;
TH1=0XFE;
TL1=0X33;
ET1=0;
EA=1;
}
void duoji() interrupt 3 定时器1中断
{
TH1=0XFE;
TL1=0X33;
if(count1 33、 pwm=1;
else
pwm=0;
count1++;
count1=count1%40;
}
6.循迹程序
void xunji()
{ if(in1==1&&in2==0&&in3==0&&in4==0){delay(1);TR2=0;zuozhuan();}
else if(in1==0&&in2==1&&in3==0&&in4==0){delay(1);TR2=0;youzhuan();}
else if(in1==0&&in2==0&&in3==0&&in4==1){delay(1);TR2=0;youzhuan1();}
els 34、e if(in3==1&&in1==0&&in2==0&&in4==0){delay(1);TR2=0;zuozhuan1();}
else if (in1==0&&in2==0&&in3==0&&in4==0){delay(1);TR2=1; qianjin();}
else if (in1==1&&in2==1&&in3==1&&in4==1){delay(1); TR2=0; tingzhi();}
}
7.红外通信
sbit IRIN = P3^2;//红外接收器数据线
unsigned char Y0=2;//
unsigned char IRCOM[7];/ 35、/暂存数组
void IRdelay(unsigned char x) //x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
void IRInit()
{
IE |= 0x81; //允许总中断中断,使能 INT0 外部中断
TCON |= 0x01; //触发方式为脉冲负边沿触发
IRIN=1; //I/O口初 36、始
IRdelay(1);
}
void IR_IN(void) interrupt 0
{
unsigned char j,k,N=0;
EX0 = 0;
IRdelay(15);
if (IRIN==1)
{ EX0 =1;
return;
}
//确认IR信号出现
while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
{IRdelay(1);}
for (j=0;j<4;j++) 37、//收集四组数据
{
for (k=0;k<8;k++) //每组数据有8位
{
while (IRIN) //等 IR 变为低电平
{IRdelay(1);}
while (!IRIN) //等 IR 变为高电平
{IRdelay(1);}
while (IRIN) //计算IR高电平时长
{
IRdelay(1);
38、 N++;
if (N>=30)
{ EX0=1;
return;} //0.14ms计数过长自动离开。
} //高电平计数完毕
IRCOM[j]=IRCOM[j] >> 1; //判断是0
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //判断是1 39、
N=0;
}
}
if (IRCOM[2]!=~IRCOM[3])//判断是否正确 与最后一个补码字节比较
{ EX0=1;
return; }
switch(IRCOM[2])
{
case 0x0C: Y0=1; break;
case 0x18: Y0=2; break;
case 0x5E: Y0=3; break;
case 0x08: Y0=4; break;
case 0x1C: Y0=5; br 40、eak;
case 0x5A: Y0=6; break;
case 0x42: Y0=7; break;
case 0x52: Y0=8; break;
case 0x4A: Y0=9; break;
case 0x16: Y0=0; break;
}
EX0 = 1;
}
8.主函数
void main()
{
uchar v;
TMOD |= 0x01; //设T0为方式1,GATE=1
TH0=0;
TL0=0;
TR0=1;
shu=26;Y0=5;v=3;
41、
init_pwm();
TIM2Inital();
delay(200);
IRInit();
delay(10);
LCD_Init();
LCD_Clear();//清屏
delay(20);
LCD_Write_String(5,0,"shandian");
LCD_Write_String(2,1,"Xunji Xiaoche");
delay(100);
delay(2000);
while(1)
{
delay(10);
switch (Y0)
42、 {
case 2:{TR2=0;delay(5);LCD_Clear();//清屏
delay(20);
while(Y0==2)
{
delay(5);
LCD_Write_String(1,0,"Xunji Bizhang");
LCD_Write_String(2,1,"dengji ");
LCD_Write_Char(9,1,'0'+v);
xunji();delay(3);bizhang();
}
break; }
43、
case 1:{
shu+=5;Y0=2;if(shu>36){shu=36;v=1;}v--;if(v<1)v=1;
LCD_Write_String(3,0,"tiaosu");
delay(3);
LCD_Write_String(2,1,"dengji ");
LCD_Write_Char(9,1,'0'+v);
delay(100);
break;}
case 3:{
shu-=5;Y0=2;if(shu<1){shu=1;v=8;}v++; 44、if(v>9)v=9;
LCD_Write_String(3,0,"tiaosu");
LCD_Write_String(2,1,"dengji ");
LCD_Write_Char(9,1,'0'+v);
delay(100);
break;}
case 8:{TR2=0;delay(5);houtui();LCD_Clear();//清屏
delay(20);
while(Y0==8)
{
LCD_Write_String(3,0 45、"back");
delay(80);
}
break;}
case 5:{TR2=0;delay(5);LCD_Clear();//清屏
delay(20);
while(Y0==5)
{
tingzhi();
LCD_Write_String(3,0,"stop");
delay(80);
}
break;}
case 6:{TR2=0;youzhuan();
LCD_Clear();//清屏
46、 delay(20);
LCD_Write_String(3,0,">>right>>");
delay(300);
Y0=2;break;}
case 4:{
TR2=0;zuozhuan();
LCD_Clear();//清屏
delay(20);
LCD_Write_String(3,0,"< 47、r();//清屏
delay(20);
while(Y0==7)
{
delay(2); xunji(); delay(20);
LCD_Write_String(3,0,"xunji");
}
}
}
case 0:{
TR2=0;delay(3);tingzhi();LCD_Clear();//清屏
delay(20);
while(Y0==0)
{
StartModule();
48、 while(!ECHO); //当ECHO为零时等待
TR0=1; //开启计数
while(ECHO); //当ECHO为1计数并等待
TR0=0; //关闭计数
Conut();
LCD_Write_String(1,0,"distance");delay(100);
disp();delay(100);
LCD_Write_String(13,1,"CM ");
delay(200);
}break;
49、
} } }
六、实验过程总结
1、实验过程
从一开始最基础的循迹开始,传感器的信号检测与小车的反应,实现准确循迹,到遥控的信号接收控制,再到超声波距离探测避障,液晶的显示,每一个功能的实现与加强,包含有软件和硬件的调试,最终调试成功。
2,影像因素
外部因素:
主要有环境光线、赛道材质等因素。或者黑白区分不清晰,就很难识别路 线,从而对后续的控制过程造成很大影响。
内部因素:
(1) 重量因素
有整车质量的增加,对系统动力性有较大影响。由于我的车装上了液晶屏,舵机,电池,使小车质量比较大,很大程 50、度上影响了小车的灵敏度,同时也增加了电机驱动的负荷。因此,除了智能车工作必须的电路之外,应尽可能减少车重。即使是 必备部件,可应该采用轻量化的设计。
(2)传感器的影响
刚开始的时候,我的传感器装的比较高,这样就不能很好的感应到路线,以 至于出现乱跑的现象。其次传感器两者之间的距离,如果可以的话,尽量使用四 处或更多的传感接收,避免小车未来得及做出反应就已经冲出轨迹,回不来的现象,从而实现可靠循迹,如果在以后的设计中需要的话,可以采用激光传感器进行探测,这样就会更精准的寻迹。
(3)负荷较重的影响
我们的小车只有一块电源板的驱动,没有光电隔离,在通电的瞬间会产生较 大的脉






