智能小车论文
智能寻黑线小车
许永读、张清洪、郑掌
[摘要]:本
以AT89S52作为小车检测和控制的核心,以实现自动控制功能。通过三个红外光电传感器对坦克小车运动方向进行检测,使其沿着引导线前进,运用直流电机调速技术,完成对小车运动速度和运动方向的控制,同时还利用红外对管实现对运动距离的测量,并用静态显示电路显示小车的运动路程、时间和金属个数。基于一些完备而可行的硬件设计,使用了切实可用的软件算法,实现小车的自动控制。
[关键词]:红外寻迹、金属传感器、电机驱动电路、壁障传感器
一、 硬件部分
的选择与论证:
根据题目的要求可以分为一下几个模块
电机驱动
红外循迹电
单路 壁障传感器 片
金属传感器 机
寻光电路
数码管显示
AT89C52的资料
1
2
L298N:
L298N是ST公司生产的一种高电压、大电流电机驱动芯片。该芯片采用15
;输出电流大,瞬间脚封装。主要特点是:工作电压高,最高工作电压可达46V
峰值电流可达3A,持续工作电流为2A;内含两个H桥的高电压大电流全桥式驱动器,可以用来驱动直流电动机和步进电动机、继电器线圈等感性负载;采用
逻辑电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止器件工作有一个逻辑电源输入端,使内部逻辑电路部分在低电压下工作;可以外接检测电阻,将变化量反馈给控制电路。使用L298N芯片驱动电机,该芯片可以驱动两个二相电机,也可以驱动一个四相电机,可以直接通过电源来调节输出电压;并可以直接用单片机的I/O口提供信号;而且电路简单,使用比较方便。
L298N的工作原理
3
电机驱动部分
图中IN1~IN4是单片机的输入端,OUT1~OUT4是L298N的输入端。将enableA、enableB接高电平+5V,使L298N的四个输出端正常工作。
7805稳压
图中220uF的电容是起电流的缓冲作用的,33uF和104是起滤波作用的。
LM324
LM324系列器件为价格便宜的带有真差动输入的四运算放大器。 1.短路保护输出 2.真差动输入级
3.可单电源工作:3V-32V
4
4.低偏置电流:最大100nA
5.每封装含四个运算放大器。
6.具有内部补偿的功能。
7.共模范围扩展到负电源
8.行业标准的引脚排列
9.输入端具有静电保护功能
寻迹部分
反射式传感器TCRT5000: TCRT5000传感器的工作原理与一般的红外传感器一样,一传一感。TCRT5000具有一个红外发射管和一个红外接收管。当发射管的红外信号经反射被接收管接收后,接收管的电阻会发生变化,在电路上一般以电压的变化形式体现出来,而经过ADC转换或LM324等电路整形后得到处理后的输出结果。电阻的变化起取于接收管所接收的红外信号强度,常
现在反射面的颜色和反射面接收管的距离两方面。它的工作电压是DC3V,5.5V,推荐工作电压
5
为5V。
采用红外一体化传感器。此方案可以降低可见光的干扰,灵敏度高,同时其尺寸小、质量轻、价格也低廉。外围电路简单,安装起来方便,电源要求不高,用它作为近距离传感器是最理想的。
TCRT5000
寻光部分
光敏电阻:光敏电阻的工作原理是基于内光电效应。为了增加灵敏度,两电极常做成梳状。构成光敏电阻的材料有金属的硫化物、硒化物、碲化物等半导体。半导体的导电能力取决于半导体导带内载流子数目的多少。当光敏电阻受到光照时,价带中的电子吸收光子能量后跃迁到导带,成为自由电子,同时产生空穴,电子—空穴对的出现使电阻率变小。光照愈强,光生电子—空穴对就越多,阻值
6
就愈低。当光敏电阻两端加上电压后,流过光敏电阻的电流随光照增大而增大。入射光消失,电子-空穴对逐渐复合,电阻也逐渐恢复原值,电流也逐渐减小。由于光敏电阻比较实惠,又满足设计的要求。故循光采用光敏电阻实现。
在有光照的时候,R5的阻值会变小,因而V就会变大;在没光照的时候,R5的阻值会变大,因而V就会变小。通过调10K电位器(104)来使比较器能够正常辨别出光敏电阻有没有接收到光。
避障部分
红外避障传感器使用说明:
7
避障传感器的接线电路图:
图中J1接传感器的输出端,J2接+5V电源,J3接入单片机的I/O口。
金属探测部分
金属探测传感器:
图中蓝线接地,棕线接电源的正极,黑线接入单片机的I/O口。
二、 软件设计
程序流程图:
8
开始
初始化I/O
初始化定时器1、3
定时器1“5路
寻迹、寻光” 检测金属块
否
否
是否有寻到黑线或光 是否有测到金属
& 金属=4,
是 否 是 &
小车停5定时器3定时器3小车开
秒 停止 开始计时 始前进
5秒到
小车继续前进,定时器继续计时
是否检测到障碍
否 物 是
左转弯,直走,右转弯
5路同时测到光
小车停,定时器停
显示时间
结束
三、测试
9
该车经调试后,各个模块都运行正常,寻迹、寻光、金属检测、避障等模块都能够实现功能。
四、
通过这次课题的设计,让我们又得到了一次锻炼,动手能力得到了提高,同时也发现了自己的一些不足,学习就是要理论联系实际,在学习了理论之后就应该把它应用到实际中才能够提升自己,同时程序的设计也是一个主要部分,如何对数据巧妙的处理,如何使结构化更加的清晰,这些都是在实践当中要考虑到的。最后调试也是一个很重要的过程,必须对整个系统很了解,将整体分成部分来调试将会变得更加简单,以上是这次课题最大的收获。
五、附录
298驱动电路原理图:
10
298驱动电路PCB图:
光检测电路原理图:
11
光检测电路PCB图:
红外寻迹电路原理图:
12
红外寻迹电路PCB图:
器件清单:
电机驱动模块:
电容:33uF、220uF、104
电阻:330
二极管:4007*9
LED灯
7805
L298N
光检测模块:
电容:10uF、104
电阻:100K*10
电位器:104*5
LM324*2
光敏电阻*5
寻迹电路模块:
电容:10uF、104
电阻:1K*5、47K*5、330*5
电位器:103*5
LED灯*5
LM324*2
TCRT5000*5
避障电路模块:
电阻:10K*2
三极管:9012
13
小车的实物相片:
小车正面图
避障传感器与电路图
14
金属探测传感器
小车俯视图
小车侧面图
15
小车整体图
小车程序:
#include
16
#define uint unsigned int #define uchar unsigned char sbit P10=P1^0;//循迹传感器最左有测得信号 低电平有效 sbit P11=P1^1;//循迹传感器次左有测得信号
sbit P12=P1^2;//循迹传感器中有测得信号
sbit P13=P1^3;//循迹传感器次右有测得信号
sbit P14=P1^4;//循迹传感器最右有测得信号
sbit P24=P2^4;//单片机输出到L298N控制电机左后退 sbit P25=P2^5;//单片机输出到L298N控制电机左前进 sbit P26=P2^6;//单片机输出到L298N控制电机右后退 sbit P27=P2^7;//单片机输出到L298N控制电机右前进 sbit P20=P2^0;//数码管位选
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
sbit P30=P3^0;//寻光传感器最左有测到信号 低电平有效 sbit P31=P3^1;//寻光传感器次左有测到信号
sbit P32=P3^2;//寻光传感器中有测到信号
sbit P33=P3^3;//寻光传感器次右有测到信号
sbit P34=P3^4;//寻光传感器最右有测到信号
sbit P17=P1^7;//金属传感器
sbit P16=P1^6;//壁障传感器
sbit P15=P1^5;//LED
sbit P37=P3^7;//蜂鸣器
uchar a[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
uchar b[4]={0xff,0xff,0xff,0xff},c[4];
uint tt,shi,fen,miao,m,l,u,nn,temp3=1,kop;
uchar
i=0,j=0,k,temp,temp1,flag,flag1,flag2=1,shu2=0,flag3=0,flag4=0,flag5=
0;ll,pp=50,temp2,shu,flag6=0,flag7=0;
void delayms(uint bb)
{
uchar vv;
while(bb--)
{
for(vv=0;vv<125;vv++);
}
}
void init()
{
TMOD=0x11;
TH0=(65536-1000)/256;//1ms
TL0=(65536-1000)%256;
TH1=(65536-5000)/256;//50ms
17
TL1=(65536-5000)%256;
EA=1;
ET0=1;
TR0=1;
ET1=1;
TR1=1; }
void zuo()//左走
{
P23=1;
P24=1;
P25=1;
P26=0; }
void you()//右走 {
P23=1;
P24=0;
P25=1;
P26=1; }
void zhi()//直走 {
P23=1;
P24=0;
P25=1;
P26=0; }
void ting()//停止 {
P23=1;
P24=1;
P25=1;
P26=1; }
void main() {
init();
P3=0x0ff;
P15=1; //LED亮
P37=1; //蜂鸣器响
while(1)
{
18
if((P17==0)&&(flag5==0))
{
delayms(1);
if((P17==0)&&(flag5==0))
//{
//while((P17==1)&&(flag5==0))
{shu2=shu2+1;//测到金属计数加1
flag2=1;
flag5=1;
P15=0; //LED亮
P37=0; //蜂鸣器响
delayms(100);
ting();//zhi();
delayms(100);
flag5=0;
P15=1; //LED
//蜂鸣器 P37=1;
if(shu2==4)
{
ting(); P37=0;
delayms(600);
P37=1;
zhi();
}
} }//}
if((kop>4)&&(temp3==1))
{ kop=4;
flag5=1;//置高
flag3=1;
temp3=0;
}
if((P17==0)&&(flag3==1))
{
flag5=1;
flag4=1;//跳入执行
flag2=0;
flag3=0;
shu2=shu2+1;
temp3=0;
}
if(flag4==1)
{
19
while(pp--)
{
flag2=0;
flag3=0;
ting();
delayms(5);
P15=0;
P37=0;
delayms(5);
P15=1;
P37=1;
delayms(5);
}
zhi();
delayms(10);
flag4=0;
flag2=1;
flag=1;
flag3=0;
flag1=1;
flag6=1;//直走
}
if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1)&&(P34==1))//没有寻
到光事时
{
if((flag6==1)&&(P16==1))//没有黑线且没有障碍物
{
zhi();//直走
}
if((P16==0)&&(flag7==0))
{
you();
delayms(10);
flag7=flag7+1;
if(flag7>1)
{flag7=0;}
}
if((P16==0)&&(flag7==1))
{
zuo();
delayms(900);
zhi();
delayms(1000);
you();
20
delayms(900);
zhi();
}
}
if((P10==0)||(P11==0)||(P12==0)||(P13==0)||(P14==0))
{
flag=1;
}
if((P30==0)||(P31==0)||(P32==0)||(P33==0)||(P34==0))
{
flag1=1;flag=0;
}
}
}
void time0() interrupt 1 { TH0=(65536-1000)/256;//1ms
TL0=(65536-1000)%256;
if((flag==1)&&(flag2==1))
{
flag3=0;
flag5=0;
temp=(P1|0xe0);//停僻高三位
switch(temp)
{ case 0xf7:i=1;zuo();break;
case 0xef:i=2;zuo();break;
case 0xe7:i=3;zuo();break;
case 0xe3:i=4;zuo();break;
case 0xf3:i=5;zuo();break;
case 0xfe:j=1;you();break;
case 0xfc:j=2;you();break;
case 0xf8:j=3;you();break;
case 0xf9:j=4;you();break;
case 0xfd:j=5;you();break;
case 0xfb:k=1;zhi();break;
case 0xf1:k=2;zhi();break;
case 0xe0:ting();break;
/*case 0xff:if(i==1||i==2||i==3||i==4||i==5){i=0;zuo();}
if(j==1||j==2||j==3||j==4||j==5){j=0;you();}
if(k==1||k==2){k=0;zhi();}break;*/
default : break;
}}
if((flag1==1)&&(flag2==1))
{ flag3=1;
21
temp1=(P3|0xe0);
switch(temp1)
{
case 0xf7:m=1;you();break;
case 0xef:m=2;you();break;
case 0xe7:m=3;you();break;
case 0xe3:m=4;you();break;
case 0xf3:m=5;you();break;
case 0xfe:l=1;zuo();break;
case 0xfc:l=2;zuo();break;
case 0xf8:l=3;zuo();break;
case 0xf9:l=4;zuo();break;
case 0xfd:l=5;zuo();break;
case 0xfb:u=1;zhi();break;
case 0xf1:u=2;zhi();break;
case 0xe0:ting();break;
case 0xff:if(m==1||m==2||m==3||m==4||m==5){m=0;zuo();}
if(l==1||l==2||l==3||l==4||l==5){l=0;you();}
if(u==1||u==2){u=0;zhi();}break;
default : break;
}
}
}
void time1() interrupt 3 {
TH1=(65536-500)/256;//50ms
TL1=(65536-500)%256;
nn++;
if((P26==0)||(P24==0)||(flag4==1))
{
tt++;
if(tt==2000)
{
tt=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
}
}
}
22
c[2]=a[miao%10];
c[1]=a[miao/10];
c[0]=a[fen%10];
c[3]=a[shu2];
switch(nn%4)
{
case 0 : P0=c[0];P20=0;P21=1;P22=1;P23=1;break;
case 1 : P0=c[1];P20=1;P21=0;P22=1;P23=1;break;
case 2 : P0=c[2];P20=1;P21=1;P22=0;P23=1;break;
case 3 : P0=c[3];P20=1;P21=1;P22=1;P23=0;break;
default : break;
}
if(((P17==0)&&(flag5==0))||((P17==0)&&(flag3==1)))
{
kop=kop+1;
c[4]=a[kop];
}
}
23