全国大赛帆板控制系统最新.docx
《全国大赛帆板控制系统最新.docx》由会员分享,可在线阅读,更多相关《全国大赛帆板控制系统最新.docx(53页珍藏版)》请在冰豆网上搜索。
全国大赛帆板控制系统最新
目录
一、引言1
二、系统方案1
(一)方案论证与比较1
1、主控电路1
2、角度传感器的选用2
3、按键选用2
4、显示2
5、电机的驱动2
6、风扇3
7、电源3
(二)总体设计方案3
三、理论分析与计算3
(一)距离计算3
(二)角度计算4
(三)控制算法4
四、电路与程序设计4
(一)硬件设计4
1、总体电路图(见附录1)4
2、主控电路4
3、风扇控制5
4、显示模块5
5、声光提示模块6
6、传感器模块6
(二)软件设计6
1、风扇控制算法设计6
2、声光提示算法设计7
3、系统流程图7
五、系统测试7
(一)测试方法与仪器7
(二)测试结果8
1、功能要求测试8
2、按键控制风力等级测试8
(三)测试结果分析9
六、设计总结9
参考文献9
附录1硬件原理图10
附录2程序代码11
帆板控制系统
摘要:
报告介绍基于STC89C52单片机的帆板角度控制系统,系统可以利用风扇控制装置对帆板角度进行控制,并通过LCD12864实时显示角度变化。
还可依据设定的帆板角度信息智能控制风扇转速,在很短时间内(5秒以内)动态调整帆板摆角,同时实时显示帆板角度等信息。
系统包括:
单片机主控模块、角度信号采集模块、键盘输入模块、显示模块、电源模块、风扇电机驱动模块。
系统主控模块采用性价比高的单片机最小系统;选用ADXL345加速度传感器完成系统角度信号采集功能;利用LCD12864实时显示角度变化的信息,5*6矩阵键盘完成风力等级和角度设定的输入;系统电源模块采用两路稳压输出电路(5v、15v),提供控制系统与风扇电机的工作电源;风扇电机采用L298N模块驱动。
本系统制作成本较低、工作性能控制稳定,能很好达到设计要求。
关键词:
STC89C52;加速度传感器;LCD12864;L298N
一、引言
单片机又称单片微控制器,单片机具有体积小、功耗低、控制功能强、扩展灵活、微型化和使用方便等优点,广泛应用于仪器仪表中,结合不同类型的传感器,可实现诸如电压、功率、频率、湿度、温度、流量、速度、厚度、角度、长度、硬度等物理量的测量。
本系统就是以单片机为核心建立起来的,要实现对帆板转角大小的控制,其归根就是对风扇的控制,帆板的转角随着风扇风力的变化而变化,角度传感器给单片机不同的角度检测信号,经单片机处理后在LCD液晶上显示,同时给出声光提示。
系统体现了模块化的设计理念,将单片机和各个器件结合在一起,完成系统化的设计,充分发挥了单片机的可靠性、可操作性和强大处理功能。
二、系统方案
(一)方案论证与比较
1、主控电路
【方案一】采用可编程逻辑器件FPGA作为控制器。
FPGA可以实现各种复杂的逻辑功能,IO资源丰富,易于进行功能扩展。
但本系统不需要复杂的逻辑功能,且从使用、功耗及经济的角度考虑我们放弃了此方案。
【方案二】STC89C52单片机采用STC89C52单片机作为主控器,其算术功能强,软件编程简洁灵活、自由度大,可用软件编程实现各种逻辑控制功能,且其功耗低、技术成熟,成本低廉。
本系统主要是进行信号的处理以及风扇电机的控制。
综合考虑,本系统设计的功能依靠51单片机均可实现,故采用方案二。
2、角度传感器的选用
【方案一】用UZZ9001Y与KMZ41连接构成一个角度测量系统。
电路组成繁琐,制作较困难,稳定性较差。
【方案二】倾角传感器。
该集成芯片为专用的水平倾角测量芯片,具有体积小、灵敏度高等优点,但是输出为模拟信号,需要用到DA转换,操作间为复杂,且占用I/O口较多,不利于本统功能模块的操作。
【方案三】用ADXL345数字加速度传感器。
ADXL345是一款小而薄的超低功耗的3轴加速度计,可测量帆板在斜面所受重力加速度在斜面上的分量,进而转换成倾斜角,测量精度较高。
ADXL345输出信号为数字信号,避免了A/D转换,操作简单;此外ADXL345只需用到两个I/O口,占用资源少,能满足本设计的要求。
本系统选择了第三种方案。
3、按键选用
【方案一】采用独立键盘。
多个使用时,线路连接不便,操作繁琐。
【方案二】采用5*6的距阵键盘,可输入的值比较多,可设定的功能也多。
在本系统中需要多个键,系统选择了第二种方案。
4、显示
【方案一】使用数码管显示。
要完成功能电路的显示需要多个数码管,此方案占用I/O口多,连接不便,显示效果差,功耗大。
【方案二】用LCD1602液晶显示。
1602是一种专门用于显示字母、数字、符号等点阵式,1602分为上下2行,每行显示16个字符。
驱动简单,但不能显示汉字。
【方案三】用LCD12864液晶显示。
LCD12864功能强大,不仅能显示字母、数字、符号,还可以显示汉字和图形,最多可显示4行,每一行最多显示8个中文,16个半宽字体。
(最好选用带字库的,方便编写程序。
)LCD12864和LCD1602使用方法类似,驱动简单,耗电量小,无辐射危险,显示直观、抗干扰能力强,但体积较大。
本系统选择了第三种方案。
5、电机的驱动
【方案一】用分立w元件构成的H桥电路利用分立三极管元件构成的H桥电路结构简单,但驱动能力有限,所带负载不可过大。
【方案二】采用L298N集成H桥芯片。
在L298N集成芯处中集成了两套H桥电路,可直接驱动两路直流电机,利用单片机产生的PWM信号,可方便地进行电机调速。
【方案三】用ULN2003功率放大器件。
ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管w组成。
通过使用不同的放大电路和不同参数的器件,可达到不同的放大的要求,放大后能得到较大的功率。
本系统设计采用方案二。
6、风扇
【方案一】用普通的散热风扇。
风力小,风力流失大,很难达到系统要求。
【方案二】用带通风通道的风扇。
风力集中,流失小,能很好的吹动帆板。
本系统设计采用方案二。
7、电源
【方案一】自制稳压电源。
采用变压器与三端稳压器相结合,使220V电压经变压器变压,降为系统所需电压,过整流桥并利用两个大的电容滤波,从而得到较为稳定的直流电压。
自制电源体积大,需接入220V电压,电压不稳定,使用不方便。
【方案二】三块6V蓄电池串联供电。
直接选用所需型号蓄电池,能量足,供电稳定,高低温适应性强。
本系统选用第二种方案。
(二)总体设计方案
系统功能的实现,以STC89C52单片机为核心,在单片机系统实现的输入输出和显示功能的基础上,由单片机的内置逻辑和运算功能,加上外围电路得以实现。
根据设计任务要求,该电路的总体框图可分为几个基本的模块,总体框图如下图2—1所示:
图2—1总体框图
三、理论分析与计算
(一)距离计算
帆板尺寸:
长15cm,宽10cm。
风扇到帆板的距离:
7~15cm。
本系统帆板转轴直径0.5cm
(二)角度计算
帆板转角:
0~60度。
帆板转角测量原理:
风扇吹动帆板转动,产生帆板角度变化,利用ADXL345数字加速度传感器测出三维坐标x、y、z的变化,将加速度传感器固定在帆板上,从而通过固定y,利用x、z的关系求出角度。
角度θ=(180*atan(tempz/tempx))/3.14。
角度的测量范围是0—90°,可以满足系统要求。
(三)控制算法
首先利用键盘控制风扇的转速,使帆板能够偏转一定的角度,再利用加速度传感器测出帆板的角度,送显示电路显示。
具体控制算法采用C语言编程实现,具体程序代码见附录2。
四、电路与程序设计
(一)硬件设计
1、总体电路图(见附录1)
2、主控电路
系统采用STC89C52单片机构成主控制电路,电路如图4—1所示:
图4—1主控电路
3、风扇控制
风扇电机选用L298N模块驱动,并由4*4按键矩阵控制PWM,改变电机速度,达到控制风扇风力大小的目标。
L298N驱动模块如下图4—2所示:
图4—2风扇控制
4、显示模块
使用LCD12864显示,如下图4—3所示:
图4—3显示模块
5、声光提示模块
图4—4声光提示模块
6、传感器模块
图4—5传感器模块
(二)软件设计
1、风扇控制算法设计
风扇控制算法如下图4—6所示:
图4—6风扇控制算法
2、声光提示算法设计
声光提示算法如下图4—7所示:
图4—7声光提示算法
3、系统流程图
整个系统程序流程图如图4—8所示:
图4—8系统流程图
五、系统测试
(一)测试方法与仪器
利用四位半数字万用表、秒表、量角器等设备通电对系统进行测试。
(二)测试结果
1、功能要求测试
序号
指标(目标值)
实测值
1
显示范围为0-60°,实时显示。
0-66°
2
分辨力为2°,绝对误差≤5°。
分辨1°误差3°
3
使帆板转角θ稳定在45°±5°范围内,制过程在10秒内完成,实时显示θ,并由声光提示
5秒
4
θ在5秒内达到设定值
5秒
表1
2、按键控制风力等级测试
风力等级
角度W
角度W
角度W
0
0°
0°
0°
5
1°
1°
1°
10
9°
10°
11°
15
23°
22°
23°
20
25°
29°
31°
25
37°
37°
39°
30
40°
39°
40°
35
47°
46°
43°
40
49°
49°
51°
45
51°
52°
53°
50
55°
56°
52°
55
55°
57°
54°
60
58°
59°
57°
65
57°
60°
58°
70
60°
62°
59°
75
61°
63°
60°
80
64°
63°
64°
85
65°
64°
65°
90
65°
65°
65°
95
65°
65°
65°
99
66°
66°
66°
表2
(三)测试结果分析
本系统总体性能良好。
但是也有不足的地方,由于帆板摆动大的问题,当系统工作时,影响到转角实际测量的精确性。
这个地方有待改进。
六、设计总结
本方案的系统设计基本符合2011年全国大学生电子设计竞赛试题(F题)的要求。
通过本次设计,深深感到理论与实践之间的差距。
很多知识点在理论上完全理解了,但到具体的电路设计与实现中,会出现很多一时无法理解的问题,要通过不断测试修改软硬件,才能用理论来指导实践,进一步深入理解理论。
参考文献
[1]郭天祥.51单片机C语言教程.北京:
电子工业出版社,2009年.
[2]阎石.数字电子技术基础(第四版).北京:
高等教育出版社,1997年.
[3]李建忠.单片机原理及应用.西安:
西安电子科技大学出版社,2002年.
附录1硬件原理图
附录2程序代码
主函数
/***************************************************************/
#include
#include"control.h"
#include"12864.h"
#include"ADXL.H"
#defineucharunsignedchar
#defineuintunsignedint
sbitkey=P2^7;
voidtimer_init()
{
TMOD=0X10;
TH1=(65535-100)/256;
TL1=(65535-100)%256;
EA=1;
ET1=1;
TR1=1;
}
voidmain()
{
chardevid;
timer_init();
lcd_12864_init();
Init_ADXL345();//初始化ADXL345
devid=Single_Read_ADXL345(0X00);//读出的数据为0XE5,表示正确
while
(1)
{
adxl345();
if(key==0)
keyscan_1();
else
keyscan();
}
}
/***************************************************************/
Controh.H文件
#ifndef__contral_h_
#define__contral_h_
externsignedcharpwm;
externvoiddelayms(unsignedintxms);
externvoidkeyscan();
externvoidkeyscan_1();
#endif
/***************************************************************/
Control.C文件
#include
#include"control.h"
#include"12864.h"
#defineucharunsignedchar
#defineuintunsignedint
#definekeydataP0
sbitA1=P2^4;
sbitA2=P2^5;
sbitENA=P2^6;
signedintcount=0;
signedcharpwm=0;
signedcharanjian=0;
ucharnumshi=0;
ucharnumge=0;
voiddelayms(unsignedintxms)
{
unsignedinti,j;
for(i=0;ifor(j=0;j<110;j++);
}
voidpwm_dis()
{
numshi=pwm/10;
numge=pwm%10;
write_12864_data(0x30+numshi);
write_12864_data(0x30+numge);
}
voidanjian_dis()
{
numshi=anjian/10;
numge=anjian%10;
write_12864_data(0x30+numshi);
write_12864_data(0x30+numge);
}
voidkeyscan()
{
unsignedchardat=0;
unsignedcharnum=0;
keydata=0xfe;
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
delayms(5);
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
dat=keydata;
switch(dat)
{
case0xee:
num=1;
break;
case0xde:
num=2;
break;
case0xbe:
num=3;
break;
case0x7e:
num=4;
break;
}
while(dat!
=0xf0)
{
dat=keydata;
dat=dat&0xf0;
}
}
}
keydata=0xfd;
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
delayms(5);
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
dat=keydata;
switch(dat)
{
case0xed:
num=5;
break;
case0xdd:
num=6;
break;
case0xbd:
num=7;
break;
case0x7d:
num=8;
break;
}
while(dat!
=0xf0)
{
dat=keydata;
dat=dat&0xf0;
}
}
}
keydata=0xfb;
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
delayms(5);
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
dat=keydata;
switch(dat)
{
case0xeb:
num=9;
break;
case0xdb:
num=10;
break;
case0xbb:
num=11;
break;
case0x7b:
num=12;
break;
}
while(dat!
=0xf0)
{
dat=keydata;
dat=dat&0xf0;
}
}
}
keydata=0xf7;
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
delayms(5);
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
dat=keydata;
switch(dat)
{
case0xe7:
num=13;
break;
case0xd7:
num=14;
break;
case0xb7:
num=15;
break;
case0x77:
num=16;
break;
}
while(dat!
=0xf0)
{
dat=keydata;
dat=dat&0xf0;
}
}
}
switch(num)
{
case1:
write_12864_addr(1,3);
pwm=0;
pwm_dis();
break;
case2:
write_12864_addr(1,3);
pwm=10;
pwm_dis();
break;
case3:
write_12864_addr(1,3);
pwm=20;
pwm_dis();
break;
case4:
write_12864_addr(1,3);
pwm=30;
pwm_dis();
break;
case5:
write_12864_addr(1,3);
pwm=40;
pwm_dis();
break;
case6:
write_12864_addr(1,3);
pwm=50;
pwm_dis();
break;
case7:
write_12864_addr(1,3);
pwm=60;
pwm_dis();
break;
case8:
write_12864_addr(1,3);
pwm=70;
pwm_dis();
break;
case9:
write_12864_addr(1,3);
pwm=80;
pwm_dis();
break;
case10:
write_12864_addr(1,3);
pwm=90;
pwm_dis();
break;
case11:
write_12864_addr(1,3);
pwm=99;
pwm_dis();
break;
case12:
write_12864_addr(1,3);
pwm=35;
pwm_dis();
break;
case13:
write_12864_addr(1,3);
pwm=pwm+5;
pwm_dis();
break;
case14:
write_12864_addr(1,3);
pwm=pwm-5;
pwm_dis();
break;
case15:
write_12864_addr(1,3);
pwm=pwm+1;
pwm_dis();
break;
case16:
write_12864_addr(1,3);
pwm=pwm-1;
pwm_dis();
break;
}
}
voidkeyscan_1()
{
unsignedchardat=0;
unsignedcharnum=0;
keydata=0xfe;
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
delayms(5);
dat=keydata;
dat=dat&0xf0;
while(dat!
=0xf0)
{
dat=keydata;
switch(dat)
{
case0xee:
num=1;
break;
case0xde:
num=2;
break;
case0xbe:
num=3;
break;
case0x7e:
num=4;
break;
}
while(dat