基于51系列单片机控制步进电机调速闭环系统设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
摘要:步进电动机是一种将脉冲信号变换成相应的角位移(或线位移)的电磁装置,是一种特殊的电动机。
由于其精确性以及其良好的性能在实际当中得到了广泛的应用。
本文介绍了以51系列单片机AT89S52为控制核心所设计的步进电机(型号42BY G016)控制系统,从系统的硬件电路以及软件的设计方面实现了对步进电机的控制。
并且由传感器E E-EX672采集转速数据进而进行关于速度的闭环控制,经过实际应用电路证明,该仿真控制系统的随动性能好,抗干扰能力强,稳定性好。
关键词:单片机、步进电机、光电开关、PID算法、闭环控制
一、步进电机
1.1 步进电机的工作原理
步进电机是将电脉冲信号转变为角位移或线位移的执行机构。
在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。
这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点,使得在速度、位置等控制领域用步进电机来控制变的非常的简单。
1.2 步进电机的特点
本实验所用的步进电机为感应子式步进电机(型号为42B YG016)。
感应子式步进电机与传统的反应式步进电机相比,结构上转子加有永磁体,以提供软磁材料的工作点,而定子激磁只需提供变化的磁场而不必提供磁材料工作点的耗能,因此该电机效率高,电流小,发热低。
因永磁体的存在,该电机具有较强的反电势,其自身阻尼作用比较好,使其在运转过程中比较平稳、噪音低、低频振动小。
感应子式步进电机某种程度上可以看作是低速同步电机。
一个四相电机可以作四相运行,也可以作二相运行。
(必须采用双极电压驱动),而反应式电机则不能如此。
例如:四相八拍运行(A-AB-B-BC-C-CD-D-DA-A)完全可以采用二相
八拍运行方式.不难发现其条件为C=,D=. 一个二相电机的内部绕组与四相
电机完全一致,小功率电机一般直接接为二相,而功率大一点的电机,为了方便使用,灵活改变电机的动态特点,往往将其外部接线为八根引线(四相),这样使用时,既可以作四相电机使用,可以作二相电机绕组串联或并联使用。
(本实验采用两相四拍)
1.3 步进电机的静态指标
相数:产生不同对极N、S磁场的激磁线圈对数。
常用m表示。
拍数:完成一个磁场周期性变化所需脉冲数或导电状态用n表示,或指电机转过一个齿距角所需脉冲数,以四相电机为例,有四相四拍运行方式即A B-BC-CD-DA-AB,四相八拍运行方式即A-AB-B-BC-C-CD-D-DA-A.
步距角:对应一个脉冲信号,电机转子转过的角位移用θ表示。
θ=360度(转子齿数J*运行拍数),以常规二、四相,转子齿为50齿电机为例。
四拍运行时步距角为θ=360度/(50*4)=1.8度(俗称整步),八拍运行时步距角为θ=360度/(50*8)=0.9度(俗称半步)。
1.4 步进电机的动态指标
1)步距角精度:
步进电机每转过一个步距角的实际值与理论值的误差。
用百分比表示:误差步距角*100%。
不同运行拍数其值不同,四拍运行时应在5%之内,八拍运行时应在15%以内。
2)失步:
电机运转时运转的步数,不等于理论上的步数。
称之为失步。
3)失调角:
转子齿轴线偏移定子齿轴线的角度,电机运转必存在失调角,由失调角产生的误差,采用细分驱动是不能解决的。
4)最大空载起动频率:
电机在某种驱动形式、电压及额定电流下,在不加负载的情况下,能够直接起动的最大频率。
5)最大空载的运行频率:
电机在某种驱动形式,电压及额定电流下,电机不带负载的最高转速频率。
6)运行矩频特性:
电机在某种测试条件下测得运行中输出力矩与频率关系的曲线称为运行矩频特性,这是电机诸多动态曲线中最重要的,也是电机选择的根本依据。
1.5 步进电机的驱动控制系统
控制系统的组成方框图如下:
1)脉冲信号的产生
脉冲信号由单片机AT89S52的I/O口产生,一般的脉冲信号的占空比为0.3-0.4左右,电机转速越高,占空比则越大。
本实验采用的占空比为0.5。
2)信号分配
感应子式不仅以二、四相电机为主,二相电机工作方式有二相四拍和二相八拍两种,具体分配如下:二相四拍为,步距角为1.8度;二相
八拍为,步距角为0.9度。
本设计采用步距角为1.8度。
3)功率放大
功率放大是驱动系统最为重要的部分。
步进电机在一定转速下的转矩取决于它的动态平均电流而非静态电流(而样本上的电流均为静态电流)。
平均电流越大电机力矩越大,要达到平均电流大这就需要驱动系统尽量克服电机的反电势。
因而不同的场合采取不同的的驱动方式,到目前为止,驱动方式一般有以下几种:恒压、恒压串电阻、高低压驱动、恒流、细分数等。
步进电机一经定型,其性能取决于电机的驱动电源。
步进电机转速越高,力距越大则要求电机的电流越大,驱动电源的电压越高。
电压对力矩影响如下:
4)功率放大细分驱动器
在步进电机步距角不能满足使用的条件下,可采用细分驱动器来驱动步进电机,细分驱动器的原理是通过改变相邻(A,B)电流的大小,以改变合成磁场
的夹角来控制步进电机运转的。
二、驱动器
由于单片机的I/O不具有直接驱动步进电机的能力,故在本系统中需要步进电机驱动器,我们选择驱动器为KD-221,该驱动器具有输入电压范围广,控制信号输入方式多样等特点。
其具体接法如下:
2.1、电源接线:
①、E高:当驱动电压大于10V时,正极接此座,使用时最大不能大于40V,以防损坏模块。
②、E低:当驱动电压小于10V时,正极接此座。
③、地:驱动电压E高、E低的的负极接此座。
④、A ,:接电机A相线圈的二根引线。
⑤、B, :接电机B相线圈的二根引线。
2.2、控制信号接线:
①、CP:接控制器发给步进电机的走步脉冲信号线。
②、CW:接控制器发给步进电机的走步方向信号线。
③、VP:接CP和CW信号的负极,即逻辑电路电源的负极。
④、本驱动器内部设计接收信号为RTT L电平,即5V电平,如其它逻辑电平信号需要接限流电阻,否则可能损坏光耦元件。
三、光电开关
本系统中所用传感器为E E-EX672关电开关,该传感器为开关型传感器,四个接线脚分别为“+,L,OUT,-”其输入电压范围广为直流5-24V,L为控制指示端,当“L”与“+”相连时,传感器未检测到物体时L E D灯发光,当“L”悬空时则相反,其特点为:
1.动作模式备有遮光时ON/入光时ON(可切换型)
2.应答频率为1K HZ的高速响应
3.入光显示灯明显,容易进行动作确认.
4.电源电压为D C-24V的广范围
5.备有遮光时入光显示灯灯亮型
其连接电路如下图所示:
“L”与“+”相连时,传感器未检测到物体时L E D灯发光。
“L”悬空传感器检测到物体时L ED灯发光。
四、硬件设计电路图
下图中为单片机的最小系统,其P0.0-P0.7口分别连接到LCD1602的D0-D7引脚,与P2.5,P2.6,P2.7相连的按键开关分别控制步进电机的正反转,加速,减速,P2.0,P2.1,P2.2分别接 LCD1602的RS,RW,E引脚。
下图中为电机驱动部分。
驱动电压为+12V,用单片机的P 1.0与电机驱动器
的CW 相连控制单片机的转向,P 1.1与电机驱动器的CP 相连,给驱动器输入脉冲。
a,b,c,d 分别接入步进电机。
SX-672为检测转速的传感器外接+5V 驱动电压,输出接入单片机的T1脚。
五、软件设计
5.1 控制算法比较:
PID 控制原理PID 调节器由比例调节器(P),积分调节器(I )和微分调节器(D) 构成,它通过对偏差值的比例积分和微分运算后,用计算所得的控制量来控制被控对象.图1所示为P I D 控制系统框图。
图1 PID 控制系统框图
5.1.1 比例调节(P ) 比例调节是数字控制中最简单的一种调节方法。
其特点是调节器的输出与控制偏差e 成线性比例关系,控制规律为:
0*p y k e y =+ (1)
式中:p k -比例系数,0y -偏差e 为零时调节器的输出值.
当输出值S 与设定的期望值R 间产生偏差时,比例调节器会自动调节控制变量y (如为控制阀门的开度)的大小。
控制变量y 的大小会朝着减小偏差e 的方向变化.比例系数的p k 大小决定了比例调节器调节的快慢程度,p k 大调节器调节的
速度快,但过大会使p k 控制系统出现超调或振荡现象。
p k 小调节器调节的速度慢,但过小又起p k 不到调节作用。
另外,虽然比例调节器控制规律简单,控制参数易于整定,但缺点是它只能在一种负载情况下实现无静差值的调节,当负
载变化时,除非重新调整相应的),值的大小,否则控制系统将会产生无法消除的静差值。
5.1.2 比例微分调节(PI )
比例调节器的主要缺点是存在无法消除的静差值,影响了调节精度.为了消除静差值,在比例调节器的基础上并人一个积分调节器构成比例积分调节器,其调节规律可用下列(2)式表示.
1
()t
p i
y k e edt y
T =+
+⎰ (2)
式中:i T 为积分常数,它的物理意义是当调节器积分调节作用与比例调节作用的输出相等时所需的调节时间称为积分常数。
积分常数的i T 大小决定了积分作用强弱程度,i T 选择的越小,积分的调节作用越强,但系统振荡的衰减速度越慢。
当 i T 过小时,甚至会造成系统的持续振荡,使调节器的输出波动不定,给生产过程带来严重的危害。
相反地当选i T 择的越大,积分的调节作用越弱,虽然过渡过程中不容易出现振荡现象,但消除偏差e 的时间却很长。
积分调节对偏差有累积作
用,所以,只要有偏差e 存在积分的调节作用就会不断地增强,直至消除比例调节器无法消除的静差值。
5.1.3 比例积分微分调节(PID )
加入积分调节后,虽可消除静差,使控制系统静态特性得以改善,但由于积分调节器输出值的大小是与偏差值e 的持续时间成正比的,这样就会使系统消除静差的调节过程变慢,由此带来的是系统的动态性能变差.尤其是当积分常数很大i T 时,情况更为严重。
另外,当系统受到冲激式偏差冲击时,由于偏差的变化率很大,而PI 调节器的调节速度又很慢,这样势必会造成系统的振荡,给生产过程带来很大的危害.改善的方法是在比例积分调节的基础上再加人微分调节,构成比例积分微分调节器(PID)。
其调节规律可用(3)式表示。
00
1
()t
e
p d
i
t
d y k
e edt T y T d =+
++⎰
(3) 式中: d T 为微分常数,它的物理意义是当调节器微分调节作用与比例调节作用
的输出相等时所需的调节时间称为微分常数.
5.2 PID 控制算法
单片机控制系统通过A /D 电路检测输出值s ,并计算偏差e 和控制变量y ,再经D /A 转换后输出给执行机构,从而实现缩小或消除输出偏差的目的,使系统输出值s 稳定在给定值区域内。
在计算机控制过程中,整个计算过程采用的是数值计算方法,当采样周期足够小时,这种数值近似计算相当谁确,使离散的被控过程与连续过程相当接近。
图2为单片机闭环控制系统框图 J 。
PID 算法是将描述连续过程的微分方程转化为差分方程,然后,根据差分方程编制计算程序来进行控制计算的。
另外在PI D 控制中,由于PID 算式选择的不同,最终所得到的控制效果是不同的。
下面进行P I D 控制算法的研究。
图5 单片机闭环控制系统框图 5.2.1 位置式PI D 的控制算法 如前所述P I D 调节的微分方程为:
00
1
()t
e
p d
i
t
d y k
e edt T y T d =+
++⎰
将此微分方程写成对应的差分方程形式.
1001[()]n
n n n p n k d k i e e y k e e T T y T T
-=-=+++∑ (4)
式中:
n e -第n 次采样周期内所获得的偏差信号;1n e --第n-1次采样周期内所获得的偏差信号;T -采样周期;n y -调节器第r t 次控制变量的输出;
为了编写计算机程序的方便,现将算式(4)写成下列形式
100()n
n p n a k b n n k y k e k e k e e y -==++-+∑ (5)
式中:*p a i
k T k T =
,*p d
b k T k T
=
因为采样周期T ,积分常数和i T 微分常数选d T 定后皆为常数,因此及必为a k b
k
常。
当调整参数改善控制性能时,也只须调整p k 、a k 和的大小即b k 可。
5.2.2 增量式PI D 的控制算法
在位置式P I D 控制算法中,每次的输出与控制偏差e 过去整个变化过程相关,这样由于偏差的累加作用很容易产生较大的累积偏差,使控制系统出现不良的超调现象。
由算式(4)可得:
1
222
2001[()]n n n n p n k d k i e e y k e e T T y T T
-----=-=+++∑ (6)
用(4)式减去(6)式,可得增量式P I D 的算式:
112[()*(2)]d n p n n n n n n i T T
y k e e e e e e T T
---∆=-+
+-+ (7) 其中,1n n n y y y -∆=-
为了编写程序方便,将(7)式改写成下列形式:
12***n n n n y A e B e C e --∆=++ (8)
式中:(1)d
p i T T A k T T
=+
+,(12)d p T B k T =-+,*d p T C k T =
从增量式P I D 的算式中可知,只要知道了现时以前的三次采样周期内的偏差
信号n e ,1n e -,2n e -即可计算出本次采样周期内的控制变量y 的增量n y ∆。
综合以上分析,我们采用增量式PID 算法,
本系统的软件控制算法主要采用了增量式PI D 控制算法。
其控制算法的流程图为:
5.3 步进电机控制流程图如下:
六、数据处理和分析
1、PWM的设定
我们通过设定P WM来控制步进电机的转速。
当T=6S时,我们通过试凑的方法了解到,当PWM=1/300时,所给步进电机刚好启动,当PWM=1/17时,步进电机速度达到最大。
2、步进电机的测速
我们通过用软件设定一个转速,然后与用光电开关采集回来的速度相比
较,采用闭环的P I D 控制来达到步进电机稳定调速的目的。
我们在程序中设定转速为72 rpm ,通过与P3.2采集回来的数据相比较,当采集回来的数据小于72rpm 时,我们通过改变P ID 的相应的参数(p k =1.2,i T =1.1 ,d T =0.9)来调节电机的转速,让步进电机的转速加起来,使之与72 rpm 相吻合。
同样,当采集回来的数据大于72rpm 时,也改变PI D 的相应的参数来调节电机的转速,让步进电机的转速加起来,使之与72 rpm 相吻合。
七、实验心得及体会
通过本次课程设计我们学习到了许多书本上没有的知识,通过自己查资料和互相讨论,对系统进行整体设计后基本达到了要求,实现步进电机速度闭环控制
并通过对系统控制算法的比较,综合考虑,选用了闭环的P ID 控制,使我们对P I D 的控制有了更深刻的认识,使自己将理论与实际相结合起来同时对51系列的单片机的设计及编程有了更深的了解,学会了很多。
同时衷心感谢老师的指导。
附录
1.显示及测速程序
#includ e < reg51.h >
#includ e < intrin s.h >
#define ucharunsign ed char
#define uint unsign ed int
floatf=0;
bit F_in=0,truer;
sbit P10=P3^0 ;
sbit P12=P3^2;
//sbit P14=P1^4;
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
//sbit BEEP = P3^7;
ucharcode cdis1[ ] = {"motors peed:"};
ucharcode cdis2[ ] = {" number: "};
#define delayN OP(); {_nop_();_nop_();_nop_();_nop_();};
ucharkey_bu f; //显示缓存
uchartemp;
uchar key,key_nu m=0;
ucharLCD0_d ata,LCD1_d ata,LCD2_d ata,LCD3_d ata; //键顺序吗
uchardata testda ta[] = {0x00,0x00,0x00,0x00};
uchardata in_dat a[] = {0x01,0x02};
ucharshift;
uint i;
uint q;
uint j;
/********************************************************/
void initim e()
{
TMOD=0x51; //T1计数器,T0定时器,方式1
TL0=(65536-10000)%256;
TH0=(65536-10000)/256; //定时10000us 0.01s
TL1=0;
TH1=0;
ET0=1;
EA=1;
}
void delay(uint ms)
{
uchart;
while(ms--)
{
for(t = 0; t < 120; t++);
}
}
void mydela y()
{
for(i=0;i<100;i++)
for(j=0;j<1000;j++);
}
/*************************************************************/
/* */
/* 延时x*0.14ms */
/* */
/*************************************************************/
void delay0(ucharx)
{
unsign ed char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
bit lcd_bu sy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayN OP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
void lcd_wd at(uchardat)
{
while(lcd_bu sy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayN OP();
LCD_EN = 1;
delayN OP();
LCD_EN = 0;
}
void lcd_wc md(ucharcmd)
{
while(lcd_bu sy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayN OP();
LCD_EN = 1;
delayN OP();
LCD_EN = 0;
}
void lcd_po s(ucharpos)
{
lcd_wcmd(pos | 0x80); //数据指针=80+地址变量}
void dectob it(int dec)
{
L CD3_d ata=dec/1000+0x30;
dec=dec % 1000;
L CD2_d ata=dec/100;
dec=dec % 100;
LCD1_d ata=dec/10+0x30;
dec=dec % 10+0x30;
LCD0_d ata=dec;
}
void displa y1()
{
lcd_po s(0x0b);
lcd_wd at(LCD3_d ata);
lcd_po s(0x0c);
lcd_wd at(LCD2_d ata);
lcd_po s(0x0d);
lcd_wd at(LCD1_d ata);
lcd_po s(0x0e);
lcd_wd at(LCD0_d ata);
lcd_po s(0x4b);
lcd_wd at(0x31);
}
void lcd_in it()
{
delay(15);
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(5);
lcd_wc md(0x38);
delay(5);
lcd_wc md(0x38);
delay(5);
lcd_wcmd(0x0c); //显示开,关光标
delay(5);
lcd_wcmd(0x06); //移动光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}
/*************************************************************/ V oid main()
{
ucharm;
lcd_in it();
initim e();
TR0=1;
TR1=1; //初始化LCD
P10=1;
P12=0;
lcd_po s(0x00); //设置显示位置为第一行
for(m=0;m<16;m++)
lcd_wd at(cdis1[m]);
lcd_po s(0x40); //设置显示位置为第二行
for(m=0;m<16;m++)
lcd_wd at(cdis2[m]);
//TMOD=0x21; //将T1设置为8位自动重装工作方式。
// TH1=175; //对T1定时常数进行预置。
//TL1=175;
// TR1=1; //启动T1。
while(1)
{
dectob it(f);
// key_bu f=key_bu f+0x30;
}
}
timer()interr upt 1 using2
{
i=i+1;
if(i==600)
{ i=0;
f=TH1*256+TL1;
TL1=0;
TH1=0;
}
TL0=(65536-10000)%256;
TH0=(65536-10000)/256;
}
2.电机驱动程序
#includ e <reg52.h>
#includ e <intrin s.h>
#define ucharunsign ed char
#define uint unsign ed int
//#define k 2000
sbit cp=P1^0;
sbit cw=P1^1;
sbit key2=P1^5;
sbit key=P1^6;
sbit key1=P1^7;
uint i;
uint K;
void key_scan()//键盘扫描函数{
if(add==0) //加速
{
flag=1;
Delay(100);
if(add==0)
{
while(!add);
k=k-5;
if(k<32)
k=32;
}
}
if(sub==0) //减速
{
flag=1;
Delay(100);
if(sub==0)
{
while(!sub);
k=k+5;
if(k>620)
k=620;
}
}
if(fx==0) //反向
{
flag=0;
Delay(100);
if(fx==0)
{
while(!fx);
cw=~cw;
}
}
/******************************************/
/******************************************/ void PID()//PID算法
{
x=20000/80; //频率
y=x*3/60; //理想转速
if((speed<y))
k--;
if((speed>y))
k++;
}
void delay(unsign ed int t );
void Delay(unsign ed int z)
{
unsign ed int i,j;
for(i=0;i<z;i++)
for(j=0;j<125;j++);
}
void main()
{
key=1;
key1=1;
key2=1;
TMOD=0x01;
K=2500;
TH0=(65536-K)/256;
TL0=(65536-K)%256;
EA=1;
ET0=1;
TR0=1;
cp=1;
cw=1;
while(1)
{
//TH0=0xf6;
//TL0=0xfd;
if(key==0)
{ Delay(100);
while(!key);
K=K-50;
if(key1==0)
{ Delay(100);
while(!key1);
K=K+50;
}
if(key2==0)
{ Delay(100);
while(!key2);
cw=~cw;
}
}
}
void timer0() interr upt 1 { i=i+1;
if(i==400)
{//cw=~cw;
i=0;
//EA=0;
}
cp=~cp;
TH0=(65536-K)/256; TL0=(65536-K)%256; //TH0=0xf6;
// TL0=0xfd;}。