电动车跷跷板设计 采用AVR Mega系列单片机Mega16作为主控芯片Word下载.docx
《电动车跷跷板设计 采用AVR Mega系列单片机Mega16作为主控芯片Word下载.docx》由会员分享,可在线阅读,更多相关《电动车跷跷板设计 采用AVR Mega系列单片机Mega16作为主控芯片Word下载.docx(13页珍藏版)》请在冰豆网上搜索。
综上考虑,我们采用步进电机。
3、倾角探测
自制倾角传感器。
车上固定一个重摆,重摆一端牵引分压电阻器,不同倾角下,返回的电压值亦不同,通过ADC读取电压值,从而获得小车所处位置倾角。
这一方案成本低廉,使用简单,但对车身的稳定性要求较高。
车速必须平稳到几乎没有任何加速度,且响应速度较慢。
采用集成倾角传感器。
本系统使用ZCT245AL-485双轴倾角传感器。
采样频率2~15HZ可调,分辨率可达0.1度,与单片机通过485进行通信。
传感器精度高,响应速度快,在这个对响应速度有特殊要求的系统中十分适宜。
出于对精度和响应速度的考虑,我们采用集成倾角传感器。
4、电机驱动板
使用分立元件进行搭建。
此方案成本低廉,但元件参数一致性不好控制。
使用L298电机驱动芯片进行电机控制。
单片机产生序列脉冲分别加至芯片输入口,输出口可控制步进电机。
此方案简单易行稳定。
故本系统采用L298驱动步进电机。
5、显示模块
LCD串行模式占用IO资源少,连接方式简单,显示内容丰富。
为了使人机界面更加友好,我们选用LCD作为系统的显示模块。
6、语音播报
利用STA013芯片对MP3进行解码,实现平衡状态的语音播报,这是我们独具特色的一个模块。
7、90度夹角内上板方案的选择
在跷跷板与地面接触线处放置引导光源,引导小车上板。
此方案需小车依靠光敏器件寻找光源方向,完成上板动作。
但上板后方向难以保证是准直方向,而且板宽较短,不易在板上进行小车准直调整,同时引导光源容易受背景光源的干扰。
在板纵向中央做一黑线带标志,与板平行并延长至地面,小车在给定范围内出发,先找到黑线带,循迹上板,这样可保证上板方向和以后行进方向的准直。
综上考虑,我们选择方案二。
8、重心微调方案
小车在平衡位置附近做小幅度前进后退动作,通过倾角传感器判断动作后结果与平衡的差距,并作出相应处理。
小车内内置一重物摆,可通过一个小电机调整重物摆的倾角,从而达到对小车重心位置微调的目的。
方案三:
小车内加置一个小丝杠,通过一个小步进电机带动丝杠运动,丝杠上夹持一重物块儿,完成对小车重心的微调。
出于对车体内部结构紧凑的考虑,我们采用方案三。
综上,我们采用:
自制车体、步进电机、L298控制步进电机、集成倾角传感器、LCD显示、循迹上板、丝杠夹持重物进行重心微调的方案。
(三)系统设计:
本系统采用AVRMega系列单片机Mega16为主控芯片,小车车体为四轮结构,其中两后轮为主动轮,采用两个独立的步进电机驱动,前轮可自由转动。
小车内部加重心微调装置,光电对管循迹装置。
其中重心微调装置由步进电机,丝杠,重物滑块构成。
外部有电池组,稳压模块,单片机最小系统板,倾角传感器,LCD显示模块和报警装置构成。
程序算法以贪婪法为主思想,实现平衡位置最短距离逼近调整。
由于车体有重心微调装置,在程序中有两级调差,两级调节共同作用,使得小车可以平稳快速的到达平衡位置。
(四)结构框图:
(见图1)
图1结构框图
二、理论分析与计算
(一)测量与控制方法:
平衡的调节以贪婪算法为主要思想,根据重心和平衡理论,平衡状态一定出现在跷跷板中点或者越过中点的位置,暂且称这些区域为危险区域。
因此在达到危险区域之前是不会出现跷跷板的状态变化,亦即处于安全状态。
所以根据这一理论基础可以在小车到达危险区域之前全速行驶,检测到贪婪位置后再进行状态的调整。
整体运动控制采用状态机理论,通过外部事件触发状态机的跳变,进行不同状态的处理。
利用时间片轮循实现多任务。
利用定时器将系统时间进行细分,中断中执行状态机的标志变换,然后再根据状态进行相关的命令处理。
微观上分时操作,宏观上同时操作。
完成电动车模式选择,计时,角度测量,循迹,LCD显示和平衡指示等功能。
在时间片轮循的基础上实现优先级设定,利用定时器将系统时间进行细分,中断中执行与优先级相关的变量的改变,根据变量的不同实现事件处理顺序的优先级设定。
(二)重心步进值计算:
小车总质量:
M车轮半径:
R车轮电机步进角:
α
微调重物块质量:
m丝杠螺距:
L丝杠传动电机步进角:
θ
丝杠上重物移动的步进距离
重心的步进步长为
在这个重心两级调节系统中,重心的步进步长可以做得非常精细,在
=
时,步进距可达到千分之一毫米。
三、电路与程序设计
(一)检测与驱动电路设计
1.光电对管电路
光电对管检测引导线,检测小车的行进路线是否为准直,电路图见附图1。
2.电机驱动电路
利用LM298驱动步进电机,电路图见附图2。
3.稳压电源电路
本系统所使用的电池组电压为12V,故需通过稳压电路为单片机提供5V电源,电路图见附图3
4.mp3语音播报模块
使用mp3对平衡状态进行语音播报,电路图见附图4。
(二)总体电路图(见附图5)
(三)软件设计与工作流程图
系统运行描述:
系统上电后LCD显示启动进度条,之后进行模式判断进入两种不同模式:
在板上调整平衡的状态:
全速运行到贪婪线,此阶段不进行角度的扫描。
随后减速运行,并即时扫描倾角。
到角度到达0度–n度范围内时进入微调阶段,n由丝杠所能调节的重心距离决定,当达到平衡状态时LED闪三下,LCD显示调整平衡成功并通过MP3进行语音播报。
在平衡位置停留5秒中后全速运行到B。
检测B并在B处停留5秒。
全速返回A处,显示全程时间数据。
爬板调整平衡的状态:
调整平衡的部分和在板上调整平衡一样。
平衡后扫描角度,当角度出现比较大的变化时判断为扰动并重新调节平衡。
停留5秒钟指示运动完成并显示相关数据。
图2程序流程图
四、系统测试
(一)基础部分任务完成情况测试(部分数据,详见附表一)
过程
测试数
A至C
C至平衡
C至B
B到A
平衡时倾角
第一次
6s
26s
14s
0.3°
第二次
25s
5s
0.5°
第三次
22s
13s
(二)发展部分任务完成情况测试(部分数据,详见附表二)
测试指标
完成时间
启动到第一次平衡
扰动后到新平衡
全程时间
新平衡处水平倾角
41s
45s
99s
38s
48s
110s
0.4°
42s
113s
(三)测试结果分析
在小车上坡过程中,由于我们使其尽量靠近其贪婪线,故行车速度和时间参数一致性好,在测试中表现得很统一。
反之,由于小车平衡点是个不稳定位置,只有在一个很窄的“危险区”内才有可能达到,因而,每一次平衡点的到达过程是一个不可预知运动过程,其时间参数有很大的离散型。
由于在到达“危险区”前和度过“危险区”后,小车全速前进,小车行车过程尽量把时间节余给调节平衡的过程,小车整体行车时间较为理想。
五、设计总结
在这短暂的四天三夜中,我们从拿到题时对系统整体功能的分析到最后作品的完成,遇到过许多棘手的问题,全队情绪曾一度低落。
一点点问题的发现到这些问题的逐一解决,我们克服了心理上的懦弱,坚定了信心,情况逐渐向明朗的方向前进。
在遇到困难甚至进度上的完全停滞时,我们最终顶了上来。
意志力帮助我们取得了胜利。
六、参考文献
[1]谭浩强.。
《C语言程序设计》(第二版)。
清华大学出版社
[2]王划一等。
《自动控制原理》。
国防工业出版社
[3]童诗白、华成英。
《模拟电子技术基础》。
高等教育出版社
[4]于海生等。
《微型计算机控制技术》。
附录
附图1光电对管电路
附图2电机驱动电路
附图3稳压电源电路
附图4mp3语音模块
附图5总体电路图
附表一:
基础部分测试数据
第四次
24s
第五次
28s
第六次
第七次
第八次
第九次
第十次
附表二:
发展部分测试数据
35s
105s
37s
52s
109s
39s
47s
119s
51s
117s
43s
49s
112s
53s
115s
部分源代码:
#include"
config.h"
constunsignedcharSet_F[]="
#00,FILT04"
;
//constunsignedcharSet_F[]="
#00,FILT30"
constunsignedcharSet_baud[]="
#00,*9600B"
constunsignedcharSet_encode[]="
#00,*AS"
constunsignedcharSet_zero[]="
#@@,&
Z"
constunsignedcharSet_output[]="
#00,*n"
uint8Angle[]="
"
voidUSART_Init(unsignedintbaud)
{
unsignedinttmp;
/*设置波特率*/
tmp=F_CPU/baud/16-1;
UBRRH=(unsignedchar)(tmp>
>
8);
UBRRL=(unsignedchar)tmp;
/*接收器与发送器使能*/
UCSRB=(1<
<
RXEN)|(1<
TXEN);
/*设置帧格式:
8个数据位,2个停止位*/
UCSRC=(1<
URSEL)|(1<
USBS)|(1<
UCSZ0)|(1<
UCSZ1);
}
voidUSART_Transmit(unsignedchardata)
/*等待发送缓冲器为空*/
while(!
(UCSRA&
(1<
UDRE)));
/*将数据放入缓冲器,发送数据*/
UDR=data;
unsignedcharUSART_Receive(void)
(UCSRA&
RXC)))
returnUDR;
voidsend_cmd(void)
uint8i;
USART_Transmit('
$'
);
voidGet_Angle(void)
uint8i=0;
if(USART_Receive()=='
X'
)
{
Angle[0]='
for(i=1;
i<
15;
i++)
{
Angle[i]=USART_Receive();
}
Angle[14]=0x20;
Angle[15]=0x20;
}