基于自由摆的平板控系统.docx
《基于自由摆的平板控系统.docx》由会员分享,可在线阅读,更多相关《基于自由摆的平板控系统.docx(29页珍藏版)》请在冰豆网上搜索。
基于自由摆的平板控系统
2011年全国大学生电子设计竞赛
设计(论文)报告
基于自由摆的平板控制系统
(日期)
摘要
摘要:
本自由摆的平板控制系统采用STC12C5A60S2单片机作为主控系统,L298N作为电机驱动模块,STC12C5A60S2单片机通过L298N驱动模块驱PK545-NAC-C29步进机,使步进机上的平板随着摆杆的摆动而旋转。
硬件部分主要包括STC12C5A60S2单片机最小系统,L298N电机驱动电路,N1000060倾角传感器,电源模块等。
本设计主要运用STC12C5A60S2单片机控制4相6线步进电机,由单片机产生脉冲信号精确控制步进机的转速和角度,使步进电机上的平板能够随着摆杆摆动而保持水平平衡。
关键词:
STC单片机;L298N电机驱动芯片;传感器
目录
摘要1
目录i
1设计任务与要求1
1.1设计任务1
1.2设计要求1
2方案比较与论证2
2.1主控器的选择与论证2
2.2电机的选择与论证2
2.3驱动模块的选择与论证3
3系统硬件设计3
3.1总体电路框图3
3.2单元电路设计4
3.3整体电路图7
4系统软件设计7
4.1总体软件框图7
4.2各模块软件设计8
4.3总程序10
5系统调试与测试10
5.1测试仪器10
5.2测试指标10
5.3测试结果分析11
6设计总结11
参考文献11
附录12
附录A:
电路图12
附录B:
电路板图13
附录C:
元器件清单13
附录D:
总程序14
设计题目
1设计任务与要求
设计任务
1、设计并制作一个自由摆上的平板系统,其结构如图1-1所示。
摆杆的一端通过转轴固定在一支架上,另一端固定安装一台电机,平板固在电机转轴上;当摆杆如图1-2所示摆动时,驱动电机可以控制平板转动。
图1-1图1-2
设计要求
1、控制电机使平板可以随着摆杆的摆动而旋转(3~5周),摆杆摆一个周期,平板旋转一周(360º),偏差绝对值不大于45°。
2、在平板上粘贴一张画有一组间距为1cm平行线的打印纸。
用手推动摆杆至一个角度θ(θ在30º~45º间),调整平板角度,在平板中心稳定放置一枚1元硬币(人民币);启动后放开摆杆让其自由摆动。
在摆杆摆动过程中,要求控制平板状态,使硬币在5个摆动周期中不从平板上滑落,并尽量少滑离平板的中心位置。
3、用手推动摆杆至一个角度θ(θ在45º~60º间),调整平板角度,在平板中心稳定叠放8枚1元硬币,见图1-2;启动后放开摆杆让其自由摆动。
在摆杆摆动过程中,要求控制平板状态使硬币在摆杆的5个摆动周期中不从平板上滑落,并保持叠放状态。
根据平板上非保持叠放状态及滑落的硬币数计算成绩。
2方案比较与论证
主控器的选择与论证
方案一:
采用STC12C5A60S2
方案二:
采用STC89C52
方案三:
采用AT89C52
方案论证:
方案一,STC12C5A60S2芯片价格便宜,应用范围广,功能强大,高速运转,低功耗,强抗静电,强抗干扰,内部集成双串口、8路10bitADC和两路八位PWM;方案二,STC89C52芯片价格便宜,应用范围广,运转速度慢,抗静电抗干扰弱,内部无ADC;方案三,AT89C52芯片价格便宜,应用范围广,运转速度慢,抗静电抗干扰弱,内部无ADC。
鉴于设计要求,故采用方案一。
电机的选择与论证
方案一:
采用步进电机
方案二:
采用直流电机
方案三:
舵机
方案论证:
方案一,步进电机价格便宜,容易控制,旋转角度于脉冲成正比,每步的旋转角度精确度高,不会将一步的误差积累到下一步,且具有优秀的起停和反转响应;方案二,直流电机价格低,调速范围广,易于平滑调节,过载、起动、制动转矩大,难于控制转轴的角度和转速;方案三,舵机价格偏高,性能易受电压影响,控制旋转的角度精确度不高。
鉴于设计要求,故采用方案一。
驱动模块的选择与论证
方案一:
采用L298N芯片
方案二:
采用ULN2803芯片
方案三:
采用三极管
方案论证:
方案一,L298N芯片价格便宜,电路设计简单,驱动电流大,足以驱动大功率的步进电机;方案二,ULN2803芯片价格便宜,电路设计简单,驱动电流小,不能驱动大功率的步进电机;方案三,三极管价格便宜,驱动电路设计复杂,不稳定,出问题难于查询。
本设计采用PK545-NAC-C29步进电机,故采用方案一。
3系统硬件设计
总体电路框图
为了使系统能够实现各种复杂的控制功能,本设计采用一种功能强大的、高速低功耗性价比高的单片机STC12C5A60S2完成对其他部分控制。
本设计采用N1000060倾角传感器对摆杆的倾斜角度的采集数据,通过STC12C5A60S2单片机内部自带的A/D转换将数据送给单片机,单片机通过数据分析控制L298N驱动电路,使步进机旋转保持平板的水平平衡,用1602液晶显示A/D的数据。
总体框图如图3-1所示。
图3-1总体框图
单元电路设计
1、STC12C5A60S2单片机最小系统
STC12C5A60S2单片机最小系统P1^1口、P1^2口、P1^3、P1^4口接L298驱动电流的输入口,单片机通过对L298N的控制,使L298发出脉冲控制步进机;P2^3口、P2^4口、P2^5口接1602液晶,控制液晶显示A/D采集N1000060倾角传感器的数据,A/D转换是用STC12C5A60S2内部自带的A/D。
单片机最小系统如图3-2、3-3所示。
图3-2最小系统
图3-3串口部分
2、L298N电机驱动
L298N是一种二相四相步电机的专用驱动器,内含两个H-Bridge的高电压、大电流双桥式驱动器,接收标准;OUT1、OUT2、OUT3、OUT4之间分别接两个步进机;INPUT1、INPUT2、INPUT3、INPUT4接单片机I/O,接收输入控制电位来控制电机旋转。
L298N驱动电路如图3-4所示。
图3-4L298N驱动
3、供电电源
供电电源采用集成稳压器7805,电路图中,稳压器7805输入端的电容为输入端滤波电容,输出端的电容为输出端滤波电容;家用电220V经过变压器接入供电电源模块,能输出直流电压-12V、-5V、5V、12V。
供电电源如图3-5所示。
图3-5供电电源
整体电路图
见附录A
4系统软件设计
总体软件框图
1、总体软件框图如图4-1所示。
图4-1总体软件框图
各模块软件设计
1、步进电机右转函数
voidl_turn(uinti)//步进电机右转函数
{
AA;
delay_ms(i);
AB;
delay_ms(i);
BB;
delay_ms(i);
BC;
delay_ms(i);
CC;
delay_ms(i);
CD;
delay_ms(i);
DD;
delay_ms(i);
DA;
delay_ms(i);
}
2、步进电机左转函数
voidr_turn(uinti)//步进电机左转函数
{
DA;
delay_ms(i);
DD;
delay_ms(i);
CD;
delay_ms(i);
CC;
delay_ms(i);
BC;
delay_ms(i);
BB;
delay_ms(i);
AB;
delay_ms(i);
AA;
delay_ms(i);
}
3、STC12C5A60S2内部AD
BYTEget_ad0()//AD读取传感器1的值
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch0|ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while(!
(ADC_CONTR&ADC_FLAG));
returnADC_RES;
}
BYTEget_ad5()//AD读取传感器2的值
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch5|ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while(!
(ADC_CONTR&ADC_FLAG));
returnADC_RES;
}
总程序
见附录D
5系统调试与测试
测试仪器
1、数字万用表
2、量角器
测试指标
当N100060倾角传感器与水平方向有角度时,N100060倾角传感器会产生一个一压,STC12C5A60S2单片机通过内部自带AD转换采集N100060反馈的电压值。
每个电压值对应一个角度,通过量角器测出角度,列出表格。
如表格5-1所示。
表5-1
角度
-90
-60
-45
-30
0
30
45
60
90
AD值
102.4
239.0
307.2
377.5
512
648.6
716.8
784.9
921.6
倾角传感器
0.5V
1.167V
1.5V
1.843V
2.5V
3.167V
3.5V
3.833V
4.5V
测试结果分析
从表格5-1可得:
倾角传感器与水平方向平行时,输出电压是2.5V;向左右与水平方向倾斜90度时,其电压的变化量为2V。
由此可得(误差允许范围内)倾角传感器与水平方向的角度a与倾角传感器的电压变化量v的数学关系为:
v=a(1/45)
本设计采用4相6线PK545-NAC-C29步进电机,4相8拍运行方式A-AB-B-BC-C-CD-D-DA-A,对应一个脉冲信号,步距角为θ=360度/(50*8)=0.9度(俗称半步)。
本设计把N100060倾角传感器固定在步进电机上,与水平方向平行,当摆杆有一个角度时,STC12C5A60S2单片机内部自带AD读取N1000060倾角传感器电压值,就能精确控制步进电机的转动角度,使步进电机上的平板保持平衡。
如:
当STC12C5A60S2单片机内部自带AD读取N1000060倾角传感器电压值为3.5V时,其N1000060倾角传感器电压变化量为v=1V,通过上式计算得N100060倾角传感器与水平方向的角度a为45度,从而就能控制步进电机旋转45度,使步进电机上的平板保持平衡。
6设计总结
经过四天三夜的辛勤努力,本设计实现了题目的全部要求。
但由于时间紧,任务重,系统还存在许多可以改进的地方,比如电路布局、抗干扰性等方面还有很大的提升空间,经过改进,相信性能还会有进一步的提升。
在软件编程方面,成功的通过软件编程消除了步进电机的抖动问题,采用的方法是:
通过A/D转换采集倾角传感器的数据,10个数据一组,然后取平均值。
本次竞赛极大的锻炼了我们各方面的能力,虽然我们遇到了很多困难和障碍,但总体上成功与挫折交替,困难与希望并存,我们将继续努力争取更大的进步。
参考文献
[1]毛礼锐,沈灌群.中国教育通史[M].济南:
山东教育出版社,1988.20-22.
[2]王英杰,高益民.高等教育的国际化[J].清华大学教育研究,2000
(2):
13-16.
[3]中华人民共和国国务院.计算机软件保护条例[J/0L].东方网,2001.12.28
附录
附录A:
电路图
附录A-1
附录A-2
附录B:
电路板图
附录B-1
附录C:
元器件清单
电阻
6个
瓷片电容
12个
电解电容
4个
键盘
6个
单片机
1个
开关
2个
L298N
1个
稳压7805
1个
稳压7812
1个
N1000060
2个
步进电机
1个
MS232
1个
串口
1个
电位器
1个
整流桥
1个
变压器
1个
发光二极管
4个
二极管
8个
附录D:
总程序
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
typedefunsignedcharBYTE;
typedefunsignedintWORD;
sfrADC_CONTR=0xBC;
sfrADC_RES=0xBD;
sfrADC_RESL=0xBE;
sfrADC_LOW2=0xBE;
sfrP1ASF=0x9D;
#defineADC_POWER0x80
#defineADC_FLAG0x10
#defineADC_START0x08
#defineADC_SPEEDLL0x00
#defineADC_SPEEDL0x20
#defineADC_SPEEDH0x40
#defineADC_SPEEDHH0x60
sbiten=P2^5;//使能
sbitrs=P2^3;//数据命令
sbitrw=P2^4;//读写
//定义步进电机连接端口
sbitA1=P1^1;//转三周
sbitB1=P1^2;//转四周
sbitC1=P1^3;//转五周
sbitD1=P1^4;//来回摆动
//定义要用到按键的管脚
sbitk1=P3^4;
sbitk2=P3^5;
sbitk3=P3^6;
sbitk4=P3^7;
//定义全局变量
uintsu=20;//8最大
uintj=0;
uintjian_zhi=0;
uinttemp1=0;
ucharshu[]={'0','1','2','3','4','5','6','7','8','9','-',':
',''};
uinti=6;
uintchong1=0;
uintsu1=20;//8最大
uintsu2=20;
uintm=0;
uintad=0;
uintad0=0;
uintj1=0;
uintj2=0;
uintad5=0;
BYTEch0=0;//模拟通道选择
BYTEch5=5;
uinter_flag=0;
//使用1-2相驱动
#defineAA{A1=1;B1=0;C1=0;D1=0;}
#defineBB{A1=0;B1=1;C1=0;D1=0;}
#defineCC{A1=0;B1=0;C1=1;D1=0;}
#defineDD{A1=0;B1=0;C1=0;D1=1;}
#defineAB{A1=1;B1=1;C1=0;D1=0;}
#defineBC{A1=0;B1=1;C1=1;D1=0;}
#defineCD{A1=0;B1=0;C1=1;D1=1;}
#defineDA{A1=1;B1=0;C1=0;D1=1;}
//函数声明
voiddelay_ms(uintx);
voidr_turn(uinti);
voidl_turn(uinti);
voiddelay(WORDn)
{
WORDx;
while(n--)
{
x=110;
while(x--);
}
}
voiddelay_ms(uintx)//延时函数
{
uinty,z;
for(y=x;y>0;y--)
for(z=130;z>0;z--);
}
voidl_turn(uinti)//步进电机右转函数
{
AA;
delay_ms(i);
AB;
delay_ms(i);
BB;
delay_ms(i);
BC;
delay_ms(i);
CC;
delay_ms(i);
CD;
delay_ms(i);
DD;
delay_ms(i);
DA;
delay_ms(i);
}
voidr_turn(uinti)//步进电机左转函数
{
DA;
delay_ms(i);
DD;
delay_ms(i);
CD;
delay_ms(i);
CC;
delay_ms(i);
BC;
delay_ms(i);
BB;
delay_ms(i);
AB;
delay_ms(i);
AA;
delay_ms(i);
}
voidl_dan()
{
switch(m)
{
case0:
AA;m++;break;
case1:
AB;m++;break;
case2:
BB;m++;break;
case3:
BC;m++;break;
case4:
CC;m++;break;
case5:
CD;m++;break;
case6:
DD;m++;break;
case7:
DA;m++;break;
case8:
m=0;break;
default:
break;
}
}
voidr_dan()
{
switch(m)
{
case0:
DA;m++;break;
case1:
DD;m++;break;
case2:
CD;m++;break;
case3:
CC;m++;break;
case4:
BC;m++;break;
case5:
BB;m++;break;
case6:
AB;m++;break;
case7:
AA;m++;break;
case8:
m=0;break;
default:
break;
}
}
voidting_zhi()
{
A1=0;
B1=0;
C1=0;
D1=0;
}
//LCD1602初始化
voidwrite_com(ucharcom)
{
rs=0;
P0=com;
delay
(1);
en=1;
delay
(1);
en=0;
}
voidwrite_data(uchardatae)
{
rs=1;
P0=datae;
delay(5);
en=1;
delay(5);
en=0;
}
voiddisplay_shu(ucharhang,ucharadd,ucharnum)//在1602显示数据的函数,hang为第几行,add为位置,num为数据
{
ucharshi;
shi=num;
if(hang==1)
{
write_com(0x80+add);
write_data(0x30+shi);
}
if(hang==2)
{
write_com(0x80+0x40+add);
write_data(0x30+num);
}
}
voidinit_LCD()//初始化LCD
{
en=0;
rw=0;
write_com(0x38);//显示模式控制
write_com(0x0c);//显示开关及光标控制
write_com(0x06);//数据指针设置
write_com(0x01);//清零
write_com(0x80);
}
voidInitADC()
{
P1ASF=0x21;//输入通道选择与CH相配合使用,选择P1^2
ADC_RES=0;//转化的数据存储所在,高八位
ADC_CONTR=ADC_POWER|ADC_SPEEDLL;
//内部AD主要的控制寄存器ADC_CONTR,选择P1^2;
delay(100);
}
BYTEget_ad0()//AD读取传感器1的值
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch0|ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while(!
(ADC_CONTR&ADC_FLAG));
returnADC_RES;
}
BYTEget_ad5()//AD读取传感器2的值
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch5|ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while(!
(ADC_CONTR&ADC_FLAG));
returnADC_RES;
}
voidkeyscan()
{
if(k1==0)
{
delay(5);
if(k1==0)
{
while(!
k1);
display_shu(1,1,1);
su=32;
j=150;
while(j--)
r_turn(su);//8最快
su=0;
}
}
if(k2==0)
{
delay(5);
if(k2==0)
{
while(!
k2);
display_shu(1,1,2);
su=32;
j=200;
while(j--)
l_turn(su);//8最快
su=0;
}
}
if(k3==0)
{
delay(5);
if(k3==0)
{
while(!
k3);
display_shu(1,1,3);
su=32;
j=250;
while(j--)
l_turn(su);//8最快
su=0;
}
}
if(k4==0)
{
delay(5);
if(k4==0)
{
while(!
k4);
display_shu(1,1,4);
er_flag=1;
}
}
}
voidmain()
{
uintshu1=0,shu2=0;
init_LCD();
InitADC();
ting_zhi();
su=32;
su1=32;
su2=32;
j1=20;
j2=30;
delay_ms(1000);
while
(1)
{
keyscan();
ad=get_ad0();
ad<<=2;
ad+=ADC_RESL;
delay_ms
(1);
ad5=get_ad5();
ad5<<=2;
ad5+=ADC_RESL;
//display_shu(1,1,ad/1000);
//display_shu(1,2,ad%1000/100);
//display_shu(1,3,ad%100/10);
//display_shu(1,4,ad%10);
//display_shu(2,1,a