基于最小拍控制的直流伺服电机控制系统设计文档格式.docx
《基于最小拍控制的直流伺服电机控制系统设计文档格式.docx》由会员分享,可在线阅读,更多相关《基于最小拍控制的直流伺服电机控制系统设计文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
4.1开环状态测试6
4.2闭环状态测试6
5设计总结6
参考文献7
附录7
附录一:
系统硬件整体电路图7
附录二:
程序清单:
8
1引言
在数字随动控制系统中,要求系统的输出值尽快地跟踪给定值的变化,最小拍控制就是为满足这一要求的一种离散化设计方法。
所谓的最小拍控制,就是要求闭环系统对于某种特定的输入在最少个采样周期内达到无静差的稳态,且闭环脉冲传递函数有以下形式:
式中,N是可能情况下的最小正整数。
这一形式表明闭环系统的脉冲响应在N个采样周期后变为零,从而意味着系统在N拍之内达到稳态。
但是最小拍控制器有其局限性:
1、最小拍控制器对典型输入的适应性较差。
一种典型的最小拍闭环脉冲传递函数
只适应一种特定的输入而不能适应于各种输入。
2、最小拍控制器的可实现性问题。
对于某些对象的脉冲传递函数,如:
那么所设计的闭环脉冲传递函数
中必须含有纯滞后,且滞后时间至少要等于被控对象的滞后时间。
否则系统的响应超前于被控对象的输入,这在实际中是实现不了的。
3、最小拍控制的稳定性问题。
在选择
时必须有一个约束条件(稳定性条件)—D(z)的零点和G(z)的不稳定极点能够完全对消。
2系统设计与论证
2.1系统总体设计思路
充分理解题意并分析后,我们将系统分为以下几个部分进行设计:
中央控制器(AT89S52)、输入模块、反馈环节、显示模块、数模转化模块、放大模块和电源模块。
根据分析系统设计框图如图2-1所示:
图2-1系统设计框图
输入模块使用4*4键盘,主要功能是设定要求的电机转速值。
电机转速通过按键输入信号经过中央处理器处理后从LCD(1602液晶显示屏)上显示。
利用中央处理器读取输入值,通过用程序设计好的的最小拍控制器调节输出,其中包括电机转速的反馈,最后经过模数转化模块DAC0808转化成电压信号,再经过运算放大器放大电压信号,将此电压信号加在电机两端,作为电机的端电压。
2.2系统模块
2.2.1输入模块
1.按键部分键盘及接口电路的设计有以下两种方案:
方案一:
直接使用I/O口的键盘连接电路。
由于AT89S52的I/O口具有输出锁存和输入缓冲的功能,因而他们组成键盘电路时,可省去输出锁存器和输入缓冲器,键位的列线、行线直接分别与单片机中接口相连。
方案二:
利用I/O口和译码器的接口连接按键电路。
将键盘的4根列线与译码器相连后由译码器74LS138三根口输入单片机,可以节省I/O口。
于本设计所需要的按键总数较少,我们采用方案一,按键电路我们采用4×
4矩阵式键盘电路。
2.键盘扫描方式的方案选择:
采用定时扫描方式。
此扫描方式每隔一段时间对键盘扫描一次,通常利用单片机内部定时器,产生10ms的定时中断,CPU响应定时器溢出中断请求,对键盘进行扫描,以响应键盘输入请求。
采用中断扫描方式。
此扫描方式是在键盘上有键盘合上时才产生中断请求,CPU响应中断,执行中断服务程序,判断键盘上闭合键的键号,并作出相应的处理。
方案三:
采用循环扫描方式。
次扫描方式就是在主程序中一直在扫描键盘,只要有键按下,就响应键盘请求,求取键值。
经综合考虑,本设计选择方案三即循环扫描方式。
因为本设计的程序并不复杂,采用循环扫描可以很好的响应键盘输入,并不影响其他功能的实现。
2.2.2反馈环节
反馈环节是本设计实现最小拍控制必不可少的部分,由测量元件(速度传感器)对被控制对象(电机)的被控参数(速度)进行测量,送给控制器CPU,控制器将测量信号(实际速度量)与给定信号(速度量)进行比较,若有误差则按预定的控制规律产生一控制信号驱动执行机构(伺服电机控制电源)工作,使被控参数(实际速度量)与给定信号(位移速度量)保持一致。
本设计中,电机的转速会以一个方波的形式从电机上输出,相当于一个编码器的作用。
方波的频率和电机的转速成线性关系,所以在程序中设计一个频率计,就可以很好的测得当前的电机转速,从而反馈给控制器进行调节。
2.2.3显示模块
显示模块有以下两种设计方案:
采用LCD(1602液晶显示屏)来显示电机的设定值。
采用LED数码管显示电机的设定值。
本设计采用的是方案一。
因为用LCD显示界面更友好,只要对相应的显示驱动程序有一定的了解就能完成显示功能,节省CPU的资源。
如果用LED数码管显示,就需要用多位的动态扫描方式,这样的设计既浪费CPU资源,同时界面显示效果并不理想。
2.2.4控制器的设计
在系统任务书中我们得知系统的传递函数为:
=1.8,
=0.15,K=100,控制算法选用最小拍控制。
通过Z变换得到脉冲传递函数为:
用单位阶跃输入得到控制器传递函数为:
由于是单位阶跃输入所以其中的
最后通过计算得到
uk=0.0027e(k)-0.0044e(k-1)+0.0016e(k-2)+
1.4368u(k-1)-0.4368u(k-2)
这样就可以编写最小拍控制器的算法程序。
本设计中算法程序如下:
//最小拍控制器的算法实现
floatsuanfa(floattv)
{
floaty;
y=freq*2.5;
//求得当前的电机速度
e2=e1;
e1=e0;
e0=tv-y;
uk=0.0027*e0-0.0044*e1+0.0016*e2+1.4368*uk1-0.4368*uk2;
uk2=uk1;
uk1=uk;
return(uk);
}
2.3软件设计与调试
通过单片机软件设计,本系统主要完成的功能是,通过键盘输入目标的电机转速,系统通过最下拍控制器调节使电机的转速达到设定值。
这其中还包括设定值的显示,和电机转速的采集,以及电压信号的输出。
系统的主程序流程图如下:
中断程序流程图:
4系统测试
4.1开环状态测试
开环状态下,未在系统中加入闭环,通过键盘我们给定电机一个预期转速值。
确定之后,电机在初始状态以很大的扭矩驱使电机转动,随着电机转速实际值渐进给定值时,单位时间内转速的增加值慢慢增大,但是没有超调量,最后达到无静差状态。
这样的调节时间比较长。
4.2闭环状态测试
通过对电机转速的测得,系统实现了闭环控制。
这样我们通过键盘设定一个目标值,电机会通过最小拍控制器对电机的工作状态进行调节。
从而达到预期的控制效果。
加入闭环后,系统的调节时间减小了,但是出现了一定的超调。
通过proteus仿真可以直观的看到控制效果。
5设计总结
通过两周的计算机控制系统课程设计,我认识到计控课程设计是对计算机控制系统知识的验证,可以帮助我们理解巩固所学知识,激发我们对实现一个可控系统的兴趣,更锻炼了我们独立思考、开拓创新的能力。
在这次设计中遇到了很多实际性的问题,所以有些问题不但要深入地理解,而且要不断地更正以前的错误思维。
一切问题必须要靠自己一点一滴的解决,而在解决的过程当中你会发现自己在飞速的提升。
对于最小拍算法控制直流伺服电机的设计,其硬件电路是比较简单的,在Protues里面我们可以很好的仿真。
最大的问题主要是解决程序设计中使用最小拍算法的问题,程序设计是一个很灵活的东西,它反映了你解决问题的逻辑思维和创新能力,它才是一个设计的灵魂所在。
因此在整个设计过程中大部分时间是用在程序上面的。
通过这次课程设计我也发现了自身存在的不足之处,虽然感觉理论上已经掌握,但在运用到实践的过程中仍有意想不到的困惑,经过一番和队友的讨论、分析才得以弄懂。
这也激发了我今后努力学习的兴趣,我想这将对我以后的学习产生积极的影响。
其次,这次课程设计让我充分认识到团队合作的重要性,只有分工协作才能保证整个项目的有条不絮。
另外在课程设计的过程中,当我们碰到不明白的问题时,指导老师总是耐心的讲解,给我们的设计以极大的帮助,使我们获益匪浅。
因此非常感谢丁老师和刘老师的教导。
参考文献
1.于海生.计算机控制技术.北京:
机械工业出版社2009
2.徐新民.单片机原理与应用.杭州:
浙江大学出版社,2006。
3.余锡存曹国华著单片机原理与接口技术.西安:
西安电子科技大学出版社,2003年。
附录
系统硬件整体电路图
#include"
reg52.h"
//#include"
absacc.h"
stdio.h"
math.h"
string.h"
#defineuncharunsignedchar
#defineunintunsignedint
voidwdata(unchardat);
//writedatafunction
voidwcom(uncharcom);
//writecommandfunction
voiddelay(unchart);
//delayfunction
sbitrs=P3^0;
//rs
sbitrw=P3^1;
//rw
sbiten=P3^2;
//en
#defineMAX_LEN16//数据最大长度
#definecount_M150000
#defineH_0(65536-count_M1)/256
#defineL_0(65536-count_M1)%256
uncharcodetab2[]={0x31,0x32,0x33,0x41,0x34,0x35,0x36,0x42,0x37,0x38,0x39,
0x43,0x0e,0x30,0x0f,0x44};
//键盘求值表
uncharcodetab3[]={"
TargetValue:
"
};
uncharcodetab4[]={"
uncharcodetab6[]={"
inputERR"
uncharserial_data[MAX_LEN],serial_len=0,sure_flag=0;
voidkeyscan(void);
//键盘操作程序
uncharscankey(void);
//键盘求值程序
voidchushi(void);
//初始化程序
floatsuanfa(floattv);
//最小拍控制器算法实现
//voidinit_serial(void);
//串口初始化
//voiduart_serial(void);
//串口主程序
voidlcd_write(void);
//液晶显示待发送指令
voidjisuan(void);
//计算结果为十进制
floatfreq=0;
//频率变量
floate0,e1,e2,uk,uk1=50,uk2=50;
unintjieguo;
unintcount;
//sfr16DPTR=0x82;
//申明DPTR
//unintf=0;
//频率计数
chartimes=0;
//计算T0中断次数
//P0=0x00;
//中断初始化
voidinit_interrup(void)
{
IE=0x8a;
//启用T0,T1中断
TMOD=0x51;
//T1为计数器,T2为定时器,都采用mode1
TH0=H_0;
TL0=L_0;
TH1=0;
TL1=0;
TR0=1;
TR1=1;
}
voiddelay(unchart)
unchara,b;
for(a=0;
a<
t;
a++)
for(b=0;
b<
128;
b++);
//ThefunctionforwritedatatoLCDscreen
voidwdata(unchardat)
P1=dat;
rs=1;
rw=0;
en=0;
delay(6);
en=1;
//ThefunctionforwritecommandtoLCDscreen
voidwcom(uncharcom)
P1=com;
rs=0;
//初始程序
voidchushi(void)
unchari;
wcom(0x01);
wcom(0x38);
wcom(0x0c);
wcom(0x06);
delay(4);
wcom(0x80);
for(i=0;
i<
17;
i++)
wdata(tab3[i]);
wcom(0xc0);
delay
(2);
//键盘求值程序
uncharscankey(void)
unchartemp,c,d;
P2=0x0f;
temp=P2;
temp=temp&
0x0f;
//屏蔽高四位,取列值
temp=~(temp|0xf0);
//将temp中的内容与0xf0进行相加,最后求反可得到是那列按下
if(temp==1)
c=0;
//P2.0位低电平
elseif(temp==2)
c=1;
//P2.1位低电平
elseif(temp==4)
c=2;
//P2.2位低电平
elseif(temp==8)
c=3;
//P2.3位低电平
else
//否则给返回值C=0
P2=0xf0;
//给P2的行为高电平,以来判断是高四为的那位为低电平
delay
(1);
0xf0;
//屏蔽低四位
temp=~((temp>
>
4)|0xf0);
//将temp中的高四位向右移动4位,与0xf0相加,最后求反可以得到是那行按下
c=c+0;
//将行P2.4的值加上列的值
c=c+4;
//将行P2.5的值加上列的值
c=c+8;
//将行P2.6的值加上列的值
c=c+12;
//将行P2.7的值加上列的值
d=tab2[c];
return(d);
//最后返回行加列的值
//lcd_writefunction
voidlcd_write(void)
uncharwrite_0,write_1,jian_zhi[MAX_LEN];
for(write_0=0;
write_0<
MAX_LEN;
write_0++)
serial_data[write_0]=0;
}//清空发送缓冲数组
wcom(0x0f);
//将光标置在oxc0处
serial_len=0;
while
(1)
write_1=0xc0;
//光标地址
wcom(write_1);
)//输入指令最大为MAX_LEN
{
wcom(write_1);
//等待键盘值
while((P2&
0x0f)==0x0f);
jian_zhi[write_0]=scankey();
delay
(1);
P2=0x0f;
0x0f)!
=0x0f);
//等待按键放松
if(jian_zhi[write_0]==0x0e)//当按一下取消键时清空所有发送缓冲数组,
{//当连续按下两次时则取消本次通讯,退出
if(write_0==0)
gotowrite_out;
elseif(write_0>
=1)
{
write_1-=1;
wcom(write_1);
write_0-=1;
wdata(tab4[0]);
serial_data[write_0]=0;
serial_len--;
}
}
elseif(jian_zhi[write_0]==0x0f)//确定发送的指令
if(serial_len==3)
{if(serial_data[0]<
2)
sure_flag++;
elseif(serial_data[0]>
2);
else
{
if(serial_data[1]<
5)
elseif(serial_data[1]>
5);
else
{
if(serial_data[2]<
6)
sure_flag++;
else;
}
}
//确定的标志位
gotowrite_out;
//退出本次输入指令
else
{
wdata(jian_zhi[write_0]);
if(jian_zhi[write_0]<
=0x39)
serial_data[write_0]=jian_zhi[write_0]-0x30;
else
serial_data[write_0]=jian_zhi[write_0]-0x37;
write_1++;
write_0++;
serial_len++;
write_out:
/*//合并数组
voidserial_and(void)
uncharand0,and1,and2=0;
and1=serial_len/2;
for(and0=0;
and0<
and1;
and0++)
serial_data[and0]=(serial_data[and0+and2++]<
<
4)|serial_data[and0+and2];
}
}*/
//键盘操作
voidkeyscan(void)
uncharks_0,ks_1;
//延时去抖动
if((P2&
=0x0f)//延时后在判断一次,去除抖动影响
ks_0=scankey();
//求键盘值
while((P2&
//等待放松
while(ks_0==0x41)
{
switch(ks_0)
case0x41:
chushi();
lcd_write();
//调用写指令程序
jisuan();
if((sure_flag==1)&
&
(serial_len<
=3)&
(count<
256))//发送指令的条为确认发送标志sure_flag=1&
本次发送指令的个数erial_len=6
sure_flag=0;
//清除确定标志
//serial_and();
//合并数组
//serial_len/=2;
//uart_serial();
//调用发送指令程序
//P0=serial_data[0];
P0=jieguo;
//P0=255;
wcom(0xc0);
for(ks_0=0;
ks_0<
10;
ks_0++)
wdata(tab6[ks_0]);
}
for(ks_0=0;
delay(250);
}
delay
(1);
}break;
default:
break;
}
ks_0=0;
sure_flag=0;
serial_len=0;
//chushi();
//初始化,等待下一次发送指令
wcom(0xc0);
for(ks_1=0;
ks_1