标题:电磁感应智能电动车
摘要:本系统以AVR单片机MEGAl6为核心器件,实现对驱动电路的控制,使电动小车自动行驶。利用电磁原理,在车模前上方水平方向固定两个相距为L的电感,通过比较两个电感中产生的感应电动势大小即可判断小车相对于导线的位置,进而做出调整,引导小车大致循线行驶。用PWM技术控制小车的直流电动机转动,完成小车位置、速度、时间等的控制。利用干簧管来检测跑道的起始和终点位置从而完成小车的起步及停车。
系统总体设计:
AVR单片机MEGAl6(该芯片能够不
需要外围晶振和复位电路而独立工作,非常适合智能寻迹车模的要求。)为核心,由单片机模块、路径识别模块、直流电机驱动模块、舵机驱动模块等组成,如下
图所示。 基于电磁感应的智能寻迹车模系统以
直流电动机为车辆的驱动装置,转向电动机用于控制车辆行驶方向。智能寻迹车模利用电磁感应在跑道上自主寻迹前进,转向。
单片机模块(控制模块):
寻迹车模采用AVR内核的ATMEGAl6。该芯片能够不需要外围晶振和复位电路而独立工作,非常适合智能寻迹车模的要求。
路径识别模块:
本方案就是在车模前上方水平方向固定两个相距为L的电感。左边的线圈的坐标为(x,h,z),右边的线圈的位置(x-L,h,z)。由于磁场分布是以z轴为中心的同心圆,所以在计算磁场强度的时候我们仅仅考虑坐标(x,y)。由于线圈的轴线是水平的,所以感应电动势反映了磁场的水平分量。
计算感应电动势:
图 1 线圈中感应电动势与它距导线水平位置x 的函数
如果只使用一个线圈,感应电动势E 是位置x
的偶函数,只能够反映到
水平位置的绝对值x 的大小,无法分辨左右。为此,我们可以使用相距长度为L 的两个感应线圈,计算两个线圈感应电动势的差值:
对于直导线,当装有小车的中轴线对称的两个线圈的小车沿其直线行驶,即两个线圈的位置关于导线对称时,则两个线圈中感应出来的电动势大小应相同、且方向亦相同。若小车偏离直导线,即两个线圈关于导线不对称时,则通过两个线圈的磁通量是不一样的。这时,距离导线较近的线圈中感应出的电动势应大于距离导线较远的那个线圈中的。根据这两个不对称的信号的差值,即可调整小车的方向,引导其沿直线行驶。
对于弧形导线,即路径的转弯处,由于弧线两侧的磁力线密度不同,则当载有线圈的小车行驶至此处时,两边的线圈感应出的电动势是不同的。具体的就是,弧线内侧线圈的感应电动势大于弧线外侧线圈的,据此信号可以引导小车拐弯。
另外,当小车驶离导线偏远致使两个线圈处于导线的一侧时,两个线圈中感应电动势也是不平衡的。距离导线较近的线圈中感应出的电动势大于距离导线较远的线圈。由此,可以引导小车重新回到导线上。
由于磁感线的闭合性和方向性,通过两线圈的磁通量的变化方向具有一致性,即产生的感应电动势方向相同,所以由以上分析,比较两个线圈中产生的感应电动势大小即可判断小车相对于导线的位置,进而做出调整,引导小车大致循线行驶。
驱动模块:
简易智能小车有两个电动机。其中一个小电动机控制前轮转向,给电动机加正反向电压,实现前轮的左右转向;另一电动机控制后轮驱动力。控制转向电动机需要较小的驱动力,经过实验,选L293作为驱动芯片;由于后轮驱动功率较大,所以选用L298N,经过实验发现小车行使过程中负载较大,导致L298N发热较大,故给芯片添加散热片以保护芯片正常工作。为了优化控制性能,采用PWM脉宽调速,并利用数模转换芯片产生
模拟电压,控制555生成占空比可调的脉冲从而控制L293B与L298N进行脉宽调速。
具体设计方案:
本设计使用一普通玩具小车作为车模, 采用P W M 信号驱动, 当PWM信号脉宽处于(1ms,1.5ms)区间时舵机控制小车向左行驶,脉宽处于 (1.5ms,2ms)时小车向右行驶,脉宽约为1.5ms时小车沿直线行驶。本方案使用两个10mH的电感置于车模头部作为确定小车位置的传感器。然后,设计了一个模拟电路,采集、调理、放大由电感得到的电动势信号。具体电路如图2所示。
该电路采用电压并联负反馈电路,电感信号从PL进入。考虑到单独电感感应出的电动势很小,本设计使用电感和电容谐振放大感应电动势。由于使用的是10mH的电感,导线中电流频率为20kHz,因此使用6.3nF的电容。这样在电容上得到的电压将会比较大,便于三极管进行放大。整个电路的具体放大倍数需要根据实际负载进行计算。本设计的小车控制电路如图3所示。
首先,把由两个电感得到的感应电动势经调理、放大后得到的电压输出u1和u2送入由运放组成的减法器中进行减法运算,
然后再经由运放组成的电压跟随
器送给下一级电路。经过分析,这一级电路的输出大致可由下式进行计算:
后一级电路由两个555定时器组成,其中下方的555构成一个占空比非常接近于1的脉冲发生器,作为上方555的触发脉冲。因为此触发脉冲的低电平信号非常窄,所以能很好的保证上方555构成的单稳态电路正常运行。该脉冲信号频率为:
上方的555定时器构成一个单稳型压控振荡器,它的脉宽受输入V1的控制,输出即PWM信号。当V1较大时,即两个电感线圈中的感应电动势相差较大时,亦即小车偏离导线向左行驶时,则脉宽较大,舵机将控制小车向右行驶;当V1适中时,接近,即小车沿导线行驶时,则脉宽接近1.5ms,小车按直线行驶;当V1较小时,即小车偏离导线向右行驶时,则脉宽较小,舵机将控制小车向左行驶。从而,控制小车大致循着导线行驶。另外,改变构成减法器的电阻的值,可以调整小车反应的灵敏度,进而防止出现小车以导线为中轴线左右摇摆的现象。
补充说明:跑道上的起始位置及终点位置用干簧管来检测。
程序设计流程图:
第二篇:20xx全国电子设计大赛报告终极版(智能小车)
20xx年全国大学生电子设计竞赛
智能小车(C题)
【本科组】
20xx年9月3日
智能小车
摘 要:本文以两个STC89C52单片机为核心设计了两辆智能小车,单片机产生周期性脉冲信号,控制全桥驱动芯片L298N驱动直流电机实现小车的转速和转向;LM339电压比较器及红外对管组成的电路进行路面黑带检测,实现小车在轨道内正常行驶;光电开关用于保持两车在超车区前的距离。
关键字:STC89C52;L298N;LM339;光电开关
Abstract:In this paper, the two STC89C52 single-chip microcomputer is the intelligent design a car, microcontroller produce periodic pulse signal, control the whole bridge L298N drive dc motor drive chip to realize the speed of the car and steering; LM339 voltage comparator and infrared to the composition of the circuit testing, realize the black line in the normal track car driving; Photoelectric switch used to keep the car in front of the distance of the overtaking area
Key word: STC89C52; L298N;LM339; photoelectric switches
1
目 录
一、 系统方案···················································3
1、方案论证与比较·············································3
2、总体方案描述···············································4
二、 理论分析与计算············································5
1、信号检测与控制··············································5
2、节能分析····················································5
三、 单元电路的设计············································5
1、电机驱动电路设计············································5
2、黑带检测电路设计············································6
3、其它功能电路设计···········································7
四、 软件及算法分析·············································7
五、 系统测试····················································8
参考文献·························································8
2
一、系统方案
1、方案论证与比较
(1)车间距离测量
根据题目要求,超车区前乙车始终在甲车之后,在如何保持两车距离的问题上我们有以下两种方案。
方案一:超声波测距方案。由于超声波指向性强,消耗缓慢,在介质中传播的距离较远,经常用于距离的测量,且其测量精度高,不易受干扰。但此方案并不能满足设计要求,而且成本高、硬件电路较为复杂,故不采用此方案。
方案二:采用集成式光电开关RPR220检测车间距离。它是利用被检测物对光束的吸收或反射,由同步回路选通电路,从而检测物体的状态。物体不限于金属,所有能反射光线的物体均可被检测。光电开关将输入电流在发射器上转换为光信号射出,接收器再根据接收到的物体反射光线的强弱对目标物体进行探测。
考虑到作品设计遵循精简及节能的原则,我们采用方便易行的方案二。
(2)电机驱动的选择 方案一:采用电机驱动芯片ULN2003。ULN2003 的每一对达林顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS 电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据。
ULN2003工作电压高,工作电流大,灌电流可达500mA,并且能够在关态时承受50V 的电压,输出还可以在高负载电流时并行运行。
方案二:采用集成式全桥驱动芯片L298N。集成驱动芯片L298N内部包含4通道逻辑驱动电路,可以方便的驱动两个直流电机,或一个两相步进电机;L298N可接受标准TTL逻辑电平信号VSS,VSS可接4.5~7 V电压;4脚VS接电源电压,VS电压范围VIH为+2.5~46 V,输出电流可高达2.5 A,可容易驱动电感性负
载。
相比较而言,ULN2003只能控制电机单向转动,而L298N可以实现双向转动,也就是说它有更强的驱动能力。而且L298N有过电流保护功能,当出现电机卡死时,可以保护电路和电机。所以选择方案二。
3
(3)黑带检测模块
方案一:采用发光二极管与光敏电阻。利用光敏电阻的阻值变化来控制信号。由于环境中光线的存在,一旦光线条件改变很可能造成误判和漏判;虽然采取超高亮发光管可以降低一定的干扰,但这又将增加额外的电量损耗。
方案二:采用反射式的集成红外对管。红外对管只对红外线具有较高灵敏度,从而避免了外界光线的干扰;跑道两侧黑带能够吸收红外线,而白色跑道能够反射红外线,从而检测到跑道黑带。
光敏电阻的易干扰性和红外对管的对光线单一灵敏行决定方案二具有较好控制作用,所以选择方案二来进行黑带的检测。
2、总体方案描述
(1)系统结构框图
图1-1 主控系统结构框图
(2)总体思路
由系统结构框图可知,每个系统主要由4个模块组成:单片机最小系统、电机驱动、黑带检测、测距。单片机最小系统为两辆小车的控制核心。按键按下,单片机控制电机驱动小车直线行驶,同时红外对管开始检测黑带,检测到转弯标志线小车延时拐弯,进入超车区之前始终保持一车跟随甲车的状态,两车之间的状态保持由光电开关控制,进入超车区后,甲车减速行驶,乙车走锯齿波路线进入超车区并超过甲车最先到达终点。
小车在运行中,每个传感器的功能可变,通过对黑带标志线来计数判断是否到达功能变更区,若到达则改变传感器检测功能。
4
二、理论分析与计算
1、信号检测与控制
小车的直线行走跟转向主要通过红外探头检测路面信号的检测。小车左右分布多个红外对管,用于跑道两边黑带和各标志线的检测,从而达到正常行驶的功能,两辆小车在进入超车区之前的车间距控制由光控开关决定,由单片机组成的最小系统是整个电路的控制核心。
2、节能分析
在小车电路的设计中,为了减少分立元件的使用量和各模块的电量消耗,我们尽可能选择集成度高、反应灵敏的器件。比如在设计车距控制模块时就避免了超声波检测,选择以光电开关调节探测距离来控制车间距离,充分的达到了节能和题目的要求。
三、单元电路设计
1、电机驱动电路
电机的驱动使用专业集成式全桥驱动芯片L298N。L298N内部包含4通道逻辑驱动电路,可以方便的驱动两个直流电机,或一个两相步进电机。L298N可接受标准TTL逻辑电平信号VSS,VSS可接4.5~7 V电压,4脚VS接电源电压,VS电压范围VIH为+2.5~46 V,输出电流可达2.5 A,L298N的 OUT1,OUT2
和OUT3,OUT4之间可分别接电机。我们选用两通道来驱动小车的电机,通过调节占空比控制电机转速。
在L298N的4脚使能信号有效(逻辑电平1)时,当5脚和7脚的电平为10时,电机B1正转;当5脚和7脚的电平为01时,电机B1反转;当5脚和7脚的电平为00或11时,电机B1不工作。B2与B1控制原理相同。小车电机驱动电路的原理图如下:
5
2、黑带检测电路
图1-2 电机驱动模块原理图 使小车稳定的行使在预想的路线上,下面给出了其核心原理图。
对管探测不同的路线,提供不同意义的信号。各个电路独立的检测黑带,从而道专用电压比较器LM339与RPR220组成探测黑带的检测电路,不同位置的红外采用集成式的红外对管RPR220对跑道黑带进行检测。主要利用集成式四通图1-3 黑带检测原理图
6
3、其他功能电路
为达到两车同时启动的目的,避免了使用手动开关造成的误差,利用PT2272无线收发模块让甲甲车控制乙车,使两车同时启动。
四、软件及算法分析
本系统软件设计部分基于STC89C52单片机平台,主要完成小车弯道标志线检测、甲车减速、乙车成功超速的功能。软件主要流程图如下:
甲车行驶流程图
乙车行驶流程图
图1-4 软件系统流程图
7
五、系统测试
根据比赛要求,经多次调试,小车达到如下功能:
(1)甲车和乙车分别从起点标志线开始,在行车道各正常行驶了一圈。
(2)甲、乙两车由指定位置同时起动,乙车通过超车标志线后在超车区内实现
超车的功能,并先于甲车到达终点标志线,即第一圈实现乙车超过甲车。
(3)甲、乙两车在完成(2)时的行驶时间测试如下:
表1:小车行驶时间测量表
参考文献
[1] 童诗白,华程英.模拟电子技术基础(第四版)[M].北京:高等教育出版社,2009.
[2] 阎石.数字电子技术基础(第五版)[M].北京:高等教育出版社,2009.
[3] 黄智伟,王彦,陈文光等.全国大学生电子设计竞赛训练教程[M].北京:电子工业出版社,2007.
[4] 高吉祥,唐朝京.全国大学生电子设计竞赛培训系列教程(电子仪器仪表设计)[M].北京:电子工业出版社,2007.
[5]郭天祥.新概念51单片机C语言教程.入门、提高、开发[M].北京:电子工业出版社,2009.
8
1、电路原理图
附录
图2-2 黑带检测电路图 图2-1 最小系统原理图
9
图2-3 电机驱动电路图
2、程序
(1)超车乙: #include<stc89c51.h> #define uchar unsigned char #define uint unsigned int uchar a; uint line; bit flag=0;
/***定义电机控制位***/ sbit enlift=P2^3; sbit enright=P2^2; sbit lift1=P2^4; sbit lift2=P2^5; sbit right1=P2^0; sbit right2=P2^1;
/****定义PWM控制位******/ bit speedflag=1; uint speedcount=3;
uint speedtemp2;
/***定义传感器状态位****/ sbit cglift1=P1^0; sbit cglift2=P3^2; sbit cgright2=P1^2; sbit cgright1=P1^1; sbit sf=P1^4; bit fl=1; void delay(uint x) { }
void former()
uint y; for(x;x>0;x--) for(y=110;y>0;y--);
10
{ lift1=0; lift2=1; right1=1; right2=0;
}
void back() { lift1=1; lift2=0; right1=0; right2=1;
}
void turnlift() { lift1=1; lift2=0; right1=1; right2=0;
}
void turnright() { lift1=0; lift2=1; right1=0; right2=1;
} void stop() {
enlift=0;
enright=0; lift1=1; lift2=1; right1=1; right2=1;
}
void init() {
speedtemp2=6;
TMOD=0X21; TH1=0XFD; TL1=0XFD; TR1=1;
TH0=(65536-1000)/256; TL0=(65536-1000)%256; TR0=1; ET0=1;
SM0=0;
SM1=1; REN=1;
EA=1; EX0=1; IT0=1;
}
void main() {
11
init(); enlift=1; enright=1;
while((line==0)||(line==1)) { former(); if(cglift1==0)
turnright();
else if(cgright1==0) turnlift();
}
while(line==2) { flag=0; former();
delay(1000);
turnlift();
delay(400);
while((line==2)&&(flag==0)&&(cgright1==1)) { former();
} flag=1;
while((line==2)&&(flag==1))
{
if((cgright1==0)&&(cgright2==0)
) { turnlift();
}
else
if((cgright1==1)&&(cgright2==1))
{ turnright();
}
else
if((cgright1==0)&&(cgright2==1)) { former();
}
}
} while(line==3)
{ flag=0; former();
delay(1000); turnlift();
delay(500);
while((line==3)&&(flag==0)&&(cgright1==1))
{
12
former(); }
flag=1;
while((line==3)&&(flag==1)) {
if((cgright1==0)&&(cgright2==0)
) { turnlift();
}
else
if((cgright1==1)&&(cgright2==1)) { turnright();
}
else
if((cgright1==0)&&(cgright2==1)) { former();
}
}
}
while(line==4) { speedtemp2=6; flag=0; former();
delay(600);
turnlift(); delay(300); former();
while(cgright1!=0); turnlift();
delay(650);
former();
speedtemp2=5; // 超车加速 delay(2000); while(cglift1!=0) former();
while(cgright2 && cgright1
&& sf) { if(cglift1==0)
turnright();
else
if((cglift1==1)&&(cglift2==1))
former();
} turnlift(); delay(600);
former(); delay(1200); while(cgright2!=0);
speedtemp2=6; while(cglift1!=0)
{
13
if((cgright1==0)&&(cgright2==0)
) { turnlift();
}
else if((cgright1==1)&&(cgright2==1)) { turnright();
}
else if((cgright1==0)&&(cgright2==1)) { former();
}
else if((sf==0)&&(cgright1==0)&&(cgright2==0))
break;
} back(); delay(500); turnlift(); delay(500); former();
while(cgright1!=0); while(1)
{
if((cgright1==0)&&(cgright2==0)
)
{ turnlift();
}
else
if((cgright1==1)&&(cgright2==1)) { turnright();
}
else
if((cgright1==0)&&(cgright2==1)) { former();
}
if(cglift1==0) break;
} stop(); while(1);
}
}
void tim() interrupt 1 { TH0=(65536-1000)/256; TL0=(65536-1000)%256; speedcount--;
if(speedcount==0)
14
{ if(speedflag==1) { enlift=0; enright=0;
speedcount=speedtemp2; speedflag=0;
} else { enlift=1; enright=1; speedcount=3; speedflag=1; }
}
}
void int0() interrupt 0 { EX0=0; line++; enlift=1; enright=1; former(); delay(40); EX0=1; if(line==4) EX0=0; } }
}
}
void int0() interrupt 0 { EX0=0; line++; enlift=1; enright=1; former(); delay(80); EX0=1;
}
15
(2)环绕车甲程序: #include<stc89c51.h> #define uchar unsigned char #define uint unsigned int uchar a; uint line; bit flag=0;
/***定义电机控制位****/ sbit enlift=P2^2; sbit enright=P2^3; sbit lift1=P2^0; sbit lift2=P2^1; sbit right1=P2^4; sbit right2=P2^5;
/****定义PWM控制位******/ bit speedflag=1; uint speedcount=3; uint speedtemp2;
/***定义传感器状态位****/ sbit cglift1=P1^0; sbit cglift2=P3^2; sbit cgright1=P1^2; sbit cgright2=P1^3; bit fl=1;
void delay(uint x) { uint y; for(x;x>0;x--)
for(y=110;y>0;y--);
}
void former() { lift1=0; lift2=1; right1=1; right2=0;
}
void back() { lift1=1; lift2=0; right1=0; right2=1; }
void turnlift() { lift1=1; lift2=0; right1=1; right2=0; }
void turnright() { lift1=0; lift2=1; right1=0; right2=1; } void stop()
16
{ enlift=0; enright=0; lift1=1; lift2=1; right1=1; right2=1;
} void init() { speedtemp2=1; TMOD=0X21; TH1=0XFD; TL1=0XFD; TR1=1;
TH0=(65536-1000)/256; TL0=(65536-1000)%256; TR0=1; ET0=1;
SM0=0; SM1=1; REN=1;
EA=1; ES=1;
EX0=1;
IT0=1;
}
void main() { uint x; init(); enlift=1; enright=1;
while((line==0)||(line==1)) {
former(); if(cglift1==0)
turnright();
else if(cgright1==0) turnlift();
}
while(line==2) { flag=0; former();
delay(1000);
turnlift();
delay(200);
while((line==2)&&(flag==0)&&(
cgright1==1)) {
former();
17
} flag=1;
while((line==2)&&(flag==1)) {
if((cgright1==0)&&(cgright2==0)
) { turnlift();
}
else
if((cgright1==1)&&(cgright2==1)) { turnright();
}
else
if((cgright1==0)&&(cgright2==1)) { former();
}
}
} while(line==3)
{ flag=0; former();
delay(700);
turnlift();
delay(200);
while((line==3)&&(flag==0)&&(
cgright1==1)) { former();
}
flag=1;
while((line==3)&&(flag==1)) {
if((cgright1==0)&&(cgright2==0)
)
{ turnlift();
}
else
if((cgright1==1)&&(cgright2==1))
{ turnright();
}
else
if((cgright1==0)&&(cgright2==1))
{
former();
}
}
}
while((line==4)||(line==5)||(line==6)||(line==7))
18
{ former();
}
while(line==8) { flag=0; former(); delay(600); turnlift();
delay(300);
while((line==8)&&(flag==0)&&(cgright1==1)) { former();
} flag=1; x=50000;
while((line==8)&&(flag==1)) {
if((cgright1==0)&&(cgright2==0)
) { turnlift();
}
else
if((cgright1==1)&&(cgright2==1)) {
turnright();
}
else
if((cgright1==0)&&(cgright2==1)) { former();
} x--; if(x==0) { speedtemp2=5;
}
}
}
while(line==9)
{ speedtemp2=2; former(); delay(600); stop(); while(1);
}
}
void ser() interrupt 4 { RI=0; a=SBUF; if(a=='1')
fl=0;
SBUF=a;
19
while(!TI);
TI=0;
}
void tim() interrupt 1
{
TH0=(65536-1000)/256; TL0=(65536-1000)%256; speedcount--;
if(speedcount==0)
{
if(speedflag==1)
{
enlift=0;
enright=0;
speedcount=speedtemp2; speedflag=0; }
else
{
enlift=1;
enright=1;
speedcount=3; speedflag=1; }
}
}
void int0() interrupt 0
{
EX0=0;
line++; enlift=1; enright=1; former(); delay(80); EX0=1; }
20