基于自由摆的平板控制系统最终全国大学生电子设计竞赛要点Word格式.docx
《基于自由摆的平板控制系统最终全国大学生电子设计竞赛要点Word格式.docx》由会员分享,可在线阅读,更多相关《基于自由摆的平板控制系统最终全国大学生电子设计竞赛要点Word格式.docx(26页珍藏版)》请在冰豆网上搜索。
4.3测试结果及分析9
4.3.1测试结果(数据)9
4.3.2测试分析与结论10
附录1:
电路原理图11
附录2:
完整测试数据12
附录3:
源程序13
【本科组】
1系统方案
本系统主要由中央处理器模块、电机驱动模块、摆杆角度测量模块、电源模块组成,下面分别论证这几个模块的选择。
1.1中央处理器的论证与选择
方案一:
目前应用很广泛的51系列单片机。
该系列的单片机具有价格低廉、性能稳定、技术成熟等特点。
但缺点也很明显,运行速度不是很快,而此次设计应需要较为复杂的运算,所以可能达不到要求。
方案二:
AVR系列的单片机。
该系列单片机较于早期的51单片机,片内资源更丰富,接口也更强大,同时采用的是RISC精简指令集,在运行速度上较与51有绝对的优势。
而价格低廉的优势也同样存在。
方案三:
ARM处理器。
ARM处理器主要应用于嵌入式系统的开发,支持Thumb(16位)/ARM(32位)双指令集,兼容性好,大量使用寄存器执行速度快。
单从性能上讲,AMR绝对强与AVR与51,但其价格昂贵,并不是很适合本次设计。
因此次设计需要设计加速度传感器对于角度的计算,需要较大的计算量,且系统对于精度的要求较高,故选择方案二。
1.2电机驱动模块的论证与选择
L298H桥式驱动芯片。
该芯片具有性能稳定、控制灵活、输出电流大等特点,可以很方便控制直流电机的转动方向。
但其价格较高,外接电路较为复杂。
ULN2003达林顿阵列芯片。
ULN2003是高耐压、大电流复合晶体管阵列,工作电压高,工作电流大,灌电流可达500mA,并且能够在关闭状态承受50V的电压,输出还可以在高负载电流并行运行。
采用此方案不能控制直流电机的运动方向,但采用步进电机则完全可以控制,且电路极其简单,基本不需要其他外围元器件。
相对于L298来说,价格上又有绝对的优势。
步进电机细分仪。
高精度的步进电机细分仪能将驱动电机的电流细分化,不仅能提高步进电机的精度,还能减噪和提高电机运行时的稳定性,驱动上也较普通驱动芯方便,只需给一定频率的脉冲信号即可控制速度。
但出于条件限制,我们并有足够的设备,且价格很高,最终还是没选择此种方案。
综合以上三种方案,选择方案二。
1.3摆杆角度测量模块的论证与选择
加速度传感器。
采用HQ7455-mma7455数字三轴加速度模块。
该模块使用和测试方便,可以实现基于运动的功能,也提供I2C和SPI接口,方便与MCU的通讯。
将加速度传感器安装在摆杆的尾部,摆杆摆动时根据角速度传感器测量出来的x轴上重力加速度的分量计算出摆杆角度。
此种方案经过实验后发现加速度传感器很不稳定,首先是在静止状态下震动幅度过大,其次是在运动状态中测量出来的角度不准确,还有严重的滞后问题。
基于这些原因,放弃了此种方案。
电位器。
随着摆杆转动,利用电位器调制出的电压信号,使用AVR单片机的片内ADC即可读取。
具有稳定性好,读出的数值与摆杆角度的线性相关也较吻合。
综合考虑采用方案二。
2系统理论分析与计算
2.1系统理论的分析
2.1.1摆杆旋转角度的获取
将高精度的电位器安装在摆杆的转轴位置,电位器连接在5V电源上,随着摆杆的摆动,电位器上能产生0~5V的电位差,利用单片机片内的10位ADC即可读取。
采集多组读出的AD值和摆杆实际角度,然后建立线性回归方程,即可获取摆杆旋转角度。
作出的线性回归图形如图一所示:
图一摆杆角度与模数转换线性拟合图
2.1.2平板旋转角度的控制
根据摆杆转动角度依据题目要求,驱动减速步进电机实时转动相应角度。
如图二所示:
图二平板旋转控制流程图
2.1.3步进电机转动控制
此次使用的减速步进电机在速度、方向上都能精确控制。
所以可根据对摆臂旋转角度、平板旋转角度等数据计算后更改步进电机脉冲信号的走向控制步进电机的方向,更改步进延时控制电机的速度。
2.2摆杆斜角度的计算
在电位器上加上5V的电压并把电位器固定到摆轴的定点,电位器本身固定不动、调节轴与摆杆相连,当摆杆静止在某个角度(-60~60度)时,电位器输出对应的电压值不变,采样出足够的点并分析其线性关系,利用闲心回归方程得到相应线性关系,通过不断测试数据来改进电位器输出电压与角度的关系
2.3步进电机的计算
2.3.1摆杆摆动三周电机的转动
单片机首先检测摆杆是否开始摆动(松手检测),摆杆摆动后,当检测到摆杆摆到了平衡位置时电机转动半圈,以此类推直到走完三圈。
2.3.2摆动摆杆通过电机控制平板使硬币不从平板上掉落
当检测到按键按下时延时一段时间以适宜操作者的反应时间,之后步进电机转动相应角度到平板到平板与摆杆垂直时电机停止转动,之后让硬币随摆杆摆动而摆动。
2.3.3摆杆固定时控制激光笔
把摆杆固定到一定角度(30~60度)位置时,通过角度计算公式:
计算出β角,让电机转动β度。
2.3.4摆杆摆动时电机控制激光笔
同2.3.3,摆杆摆动到下一位置与前一角度对应的β角之差就是电机要转动的角度,通过检测摆动最高点和最低点来决定电机的转动方向
3电路与程序设计
3.1电路的设计
3.1.1系统总体框图
系统总体框图如图三所示:
图三系统总体框图
3.1.2摆杆角度检测子系统框图与电路原理图
1、摆杆角度检测子系统框图
图四摆杆角度检测子系统框图
3.1.3步进电机驱动子系统电路原理图
1、步进电机驱动子系统电路
图五步进电机子系统电路
3.1.4电源
因本系统需为单片机的ADC提供参考电压,所以对电压稳定的要求较高,故采用现成的+5V电源模块,并焊接了一块有多个接口的板子,以便其他模块的供电连接。
3.2程序的设计
3.2.1程序功能描述与设计思路
1、程序功能描述
根据题目要求软件部分需实现电位器端的模数转换、步进电机驱动、键盘检测、LED灯显示、各种参数及数据的计算等。
(1)模数转换实现功能:
采用AVR单片机的片内十位ADC。
(2)步进电机驱动:
控制连接ULN2003驱动模块的IO口,输出制定频率的电位变化控制步进电机的转动速度与转动方向。
(3)键盘检测:
实时扫描连键盘的单片机IO的电位变化,读出按键。
2、程序设计思路
(1)模式选择:
程序启动后进入模式选择状态。
键盘检测输入,LED灯显示当前状态。
编写电机驱动接口函数,入口参数有电机转动方向、电机转动步数、每步延时。
(3)电位器电压检测:
利用AVR片内的10位ADC。
需要检测点位时调用进行模数转换,检测寄存器状态判断装化完成。
3.2.2程序流程图
1、主程序结构图图
图六主程序结构图
2、摆杆角度检测子程序流程图
图七摆杆角度检测子程序
3、电机驱动子程序流程图
图八电机驱动子程序流程图
4测试方案与测试结果
4.1测试方案
1、软件仿真测试
2、硬件设计测试
4、设计要求测试
4.2测试方式与仪器
1、软件仿真:
用PROTEUS软件画出系统要求的电路,测试程序是否编写正确。
这一测试主要是对模式选择子系统的测试;
2、硬件电路检测:
使用万用表测量电路是否连接正确,米尺和三角板测量摆杆的长度和水平是否符合要求。
3、设计要求测试
(1)基本要求1:
调整平板至水平位置,启动程序后松手,平板旋转结束用量角器测量平板偏离初始位置角度。
(2)基本要求2:
按要求操作后用三角板测量硬币偏离平板距离
(3)基本要求3:
按要求操作后计算硬币非保持叠放状态数量和滑落硬币数。
(4)发挥部分1:
按要求操作后计算光斑离开中心线的距离。
(5)发挥部分2:
按要求操作后计算光斑偏离中心线最远距离。
4.3测试结果及分析
4.3.1测试结果(数据)
表一:
ADC值与实际测量的摆杆角度(中心线为为90°
):
ADC
50
60
70
80
90
100
110
120
130
140
角度(°
)
463
496
519
560
575
615
639
671
704
739
表二:
基本要求1平板旋转角度误差:
测量次数
1
2
3
4
5
6
7
8
误差(°
表三:
基本要求2硬币偏离平板中心线距离:
偏移(cm)
表四:
基本要求3硬币非保持叠放状态数量和滑落硬币数
非保持叠放状态数量
滑落硬币数
表五:
发挥部分1光斑离开中心线的距离:
距离(cm)
表六:
发挥部分2斑离开中心线的距离:
N
4.3.2测试分析与结论
根据上述测试数据,由此可以得出以下结论:
1、电路焊接正确。
2、基本要求1符合设计需要
3、基本要求2符合设计需要
4、基本要求3,如果操作时手颤抖和操作不及时能使得误差较大,但大部分时候符合设计要求。
5、发挥部分1基本能符合设计要求,误差在允许范围内
6、发挥部分2因步进电机的转速以及电位器稳定性等问题,编写程序后光斑并不能落到靶子上。
参考文献:
[1]闫爱军范海明.基于AVR单片机的四相步进电机驱动设计[J].舰船防化-2011年2期
[2]陆广平张美琪.基于AVR单片机的步进电机运动控制系统设计[J].微电机-2010年3期
电路原理图
完整测试数据
源程序
/*
*文件名:
process.c
*函数功能:
设计要求的五种操作模式
*
*/
#include<
avr/io.h>
stdlib.h>
math.h>
avr/pgmspace.h>
#defineDATA_NUM10
unsignedchartest_adc[DATA_NUM]={704,707,719,768,728,736,775,783,792,799};
unsignedchartest_jd[DATA_NUM]={110,119,132,174,130,149,194,206,214,224};
/****************************基本要求一********************************/
//检测松手
//检测低谷
voidcheck_valley()
{
unsignedintjd;
while
(1)
{
jd=adc_read();
if(jd>
570&
&
jd<
590)break;
}
return;
}
voidbasic_q1()
unsignedchari;
//*****************************************/
for(i=0;
i<
3;
i++)
check_valley();
//
moto_run(0,512,1000);
//半圈
//***********以上旋转三周*******************//
moto_run(0,20,1000);
while
(1);
/***************************************************************/
/*=========================基本要求二==========================*/
//角度计算
unsignedcharjd_cal(unsignedintad_z)
return(0.2698*ad_z-69.962)+5;
voidmoto_cal(unsignedchar*fx,unsignedchar*jd)
unsignedchartemp;
temp=adc_read();
unsignedcharget_moto_jd()
unsignedintmoto_jd;
moto_jd=(temp-100)*5;
returnmoto_jd;
voidbasic_q2()
unsignedcharb_jd;
//单摆角度
unsignedcharfx;
unsignedintbs;
//电机转动步数
unsignedintad_top;
//在顶端的adc值
unsignedinttemp;
//松手即启动
_delay_ms(100);
//反应延时
ad_top=adc_read();
b_jd=jd_cal(ad_top);
if(b_jd>
90)
fx=0;
bs=(b_jd-90)/0.3516;
//步进电机每步角度
else
{
fx=1;
bs=(90-b_jd)/0.3516;
moto_run(fx,bs,900);
moto_close();
//==================基本要求3==========================//
voidbasic_q3()
unsignedintbs_ext;
//附加角度
bs_ext=bs*0.1;
moto_run(fx,bs_ext,2000);
check_valley();
if(fx==0)fx=1;
elsefx=0;
//================发挥部分一=============/
unsignedcharread_key()
staticunsignedcharkey_last=0;
staticunsignedcharld=0;
//连带
unsignedcharkey=0;
PIND|=0b11100000;
PORTD|=0b11100000;
_delay_ms(10);
while(PIND==0b11100000);
if(KEY_START==0)key=3;
if(KEY_UP==0)key=1;
if(KEY_DOWN==0)key=2;
if(key==key_last)
if(ld<
50)ld++;
if(ld>
=50)returnkey;
elsereturn0;
key_last=key;
ld=0;
returnkey;
voidmoto_adjust()
unsignedintmoto_b=0;
unsignedcharkey;
unsignedcharadjust_ok=0;
LED_PORT=0x00;
SetBit(LED_PORT,2);
SetBit(LED_PORT,LED_RUN);
/*
lcd1602_init();
lcd1602_location(0,0);
lcd1602_print_string("
<
Adjust>
"
);
*/
//校正
/*
lcd1602_location(1,0);
lcd1602_print_string("
ADC:
lcd1602_print_num(adc_read(),5);
*/
key=read_key();
switch(key)
{
case1:
moto_run(1,1,1000);
break;
case2:
moto_run(0,1,1000);
case3:
adjust_ok=1;
}
if(adjust_ok)break;
voidadvance_q1()
unsignedintadc_now,adc_1,adc_2;
unsignedintjd,jd_1,jd_2;
unsignedinti;
unsignedinttemp1,temp2,temp3;
start:
moto_adjust();
adc_now=adc_read();
if(adc_now>
760)
jd=(int)((double)adc_now*1.1797-720.34)+8;
jd=(int)((double)adc_now*1.1797-720.34)+5;
DATA_NUM;
if(adc_now==test_adc[i])jd=test_jd[i];
moto_run(1,jd,2000);
SetBit(LED_PORT,LED_OVER);
//while
(1);
read_key();
gotostart;
//================发挥部分2=============================//
unsignedinta_moto_x;
voida_moto_init()
a_moto_x=(int)((double)adc_read()*1.