四相步进电机定位控制系统.docx
《四相步进电机定位控制系统.docx》由会员分享,可在线阅读,更多相关《四相步进电机定位控制系统.docx(29页珍藏版)》请在冰豆网上搜索。
![四相步进电机定位控制系统.docx](https://file1.bdocx.com/fileroot1/2022-11/26/8b41b1da-7273-4f68-9e29-115cf4c35463/8b41b1da-7273-4f68-9e29-115cf4c354631.gif)
四相步进电机定位控制系统
四相步进电机定位控制系统
四相步进电机定位控制系统功能概述
步进电机每接收到一组脉冲数字信号,便旋转一个角度,成为步进角。
不同规格的步进电机的步进角不同,这决定于其内部的线圈数量。
线圈中的供应电流可以决定线圈所产生的磁场方向。
假设有两组线圈A和B,如图一所示。
A线圈如果提供A点低电位而A′点高电位,电流由A′螺旋向上流到A,形成向上的磁场方向;同理,提供B点低电位而B′点高电位,电流由B′螺旋流到B,形成向左的磁场方向。
A和B这两组线圈形成的总磁场方向即为左上方。
如果将电动机的转子置于线圈所产生的磁场中,便会受到磁场的作用而产生与磁场方向一致的力,转子便开始转动,直到转子的磁场方向与线圈的磁场方向一致为止。
如图二所示。
由A和B两组线圈电流方向的排列组合,最多可以产生8种磁场方向,分别是0°、45°、90°、135°、180°、225°、270°、315°。
这些方向的电流方向列于表一。
图一图二
由表一可知,假设电动机转子刻度原先在0°的位置,想让其转到180°,就必须让端口信号依次由0001、0011、0010、0110到0100变化。
但是是否有更快的办法,是否一定要经过4个信号过程呢?
其实有更快更省电的方式让电动机从0°达到180°的位置。
这就是所谓的激磁方式的不同。
四相电动机可以分为3种激磁方式。
表一:
四相步进电机的8个方向和电流以及电压信号的关系
磁场方向
0°
45°
90°
135°
180°
225°
270°
315°
电流方向
A线圈
B线圈
A→A′
A→A′
0
A←A′
A←A′
A←A′
0
A→A′
0
B→B′
B→B′
B→B′
0
B←B′
B←B′
B←B′
端口信号
0001
0011
0010
0110
0100
1100
1000
1001
1-相激磁法:
当目标角度是90的整数倍时,采用这种方法。
例如要从0转到270,只要让端口信号的顺序为0000,0001,0010,0100,1000即可。
2-相激磁法:
当目标角度是45而非90的整数倍时,可采用这种方法。
例如要从0转到225,只要让端口信号的顺序为0000,0011,0110,1100即可。
1-2-相混合激磁法:
按照表二中所列的信号顺序。
表二:
四相步进电机3种不同激磁方式对应提供的端口信号
磁场方向
0°
45°
90°
135°
180°
225°
270°
315°
端口信号
0001
0011
0010
0110
0100
1100
1000
1001
1-相激磁
√
√
√
√
2-相激磁
√
√
√
√
1-2-相激磁
√
√
√
√
√
√
√
√
四相步进电机定位控制系统的VHDL源码及注释
--四相步进电机示例程序
libraryIEEE;
useIEEE.std_logic_1164.all;
useIEEE.std_logic_arith.all;
useIEEE.std_logic_unsigned.all;
entitystep_motoris
port(reset:
inSTD_LOGIC;--系统复位信号
dir:
inSTD_LOGIC;--步进电机正反转方向控制开关(0:
逆时针;1:
顺时针)
clk:
inSTD_LOGIC;--系统时钟(FPGA内部提供的4MHz的时钟信号)
ini:
inSTD_LOGIC;--使能开关
manner:
inSTD_LOGIC_VECTOR(1downto0);--激磁方式的选择开关(00:
自动选择激磁方式;--01:
1-相激磁;10:
2-相激磁;11:
1-2-相激磁)
angle:
inSTD_LOGIC_VECTOR(7downto0);--步进角的倍数设定输入键
baBA:
outSTD_LOGIC_VECTOR(3downto0));--步进电机的状态输出
endstep_motor;
architecturestepmotor_archofstep_motoris
signalcount:
INTEGERrange0to7;--内部电路的计数累加器,用于产生输出所需对应的状态
signalcntInc:
INTEGERrange-2to2;--设定累加器所需的累加/减计数值
signalcntIni:
INTEGERrange-1to0;--设定累加器所需的计数初值
signalangleDnCount:
INTEGERrange255downto0;--设定步进角所需的计数次数
signalangleDnCntDec:
INTEGERrange2downto1;--设定步进角所需的累减计数值
begin
--步进电机方向设定电路模块
该模块的功能是设定步进电机的旋转方向(顺时针或逆时针),并设定电机在顺时针转动或逆时针转动时所需的初值与累加/减值。
process(dir,manner,angle)
begin
ifdir='0'then
casemanneris
when"01"=>--1-相激磁
cntIni<=0;
cntInc<=2;
angleDnCntDec<=2;
when"10"=>--2-相激磁
cntIni<=-1;
cntInc<=2;
angleDnCntDec<=2;
when"11"=>--1-2-相激磁
cntIni<=0;
cntInc<=1;
angleDnCntDec<=1;
whenothers=>--自动选择激磁方式
--angle为偶数即角度为90的倍数时,采用1-相激磁,否则2-相激磁
if(angle(0)='1')then--2-相激磁
cntIni<=-1;
cntInc<=2;
angleDnCntDec<=2;
else--1-相激磁
cntIni<=0;
cntInc<=2;
angleDnCntDec<=2;
endif;
endcase;
else
casemanneris
when"01"=>--1-相激磁
cntIni<=0;
cntInc<=-2;
angleDnCntDec<=2;--"10";
when"10"=>--2-相激磁
cntIni<=-1;
cntInc<=-2;
angleDnCntDec<=2;--"10";
when"11"=>--1-2-相激磁
cntIni<=0;
cntInc<=-1;
angleDnCntDec<=1;--"01";
whenothers=>--自动选择激磁方式
if(angle(0)='1')then--2-相激磁
cntIni<=-1;
cntInc<=-2;
angleDnCntDec<=2;
else--1-相激磁
cntIni<=0;
cntInc<=-2;
angleDnCntDec<=2;
endif;
endcase;
endif;
endprocess;
--步进电机步进移动与定位控制电路模块
该模块的主要功能是利用ini(使能开关),将数值传到该模块中,并配合输入的clk(系统时钟)作为同步控制信号,进行步进电机的步进移动与定位控制。
counting_reset:
process(reset,ini,angle,clk)
begin
ifreset='1'then--复位低电平有效
count<=0;
angleDnCount<=0;
elsifclk'eventandclk='1'then
ifini='0'then--使能高电平有效
count<=0+cntIni;
angleDnCount<=CONV_INTEGER(angle);
else
count<=count+cntInc;
ifangleDnCount>angleDnCntDecthen--判断是否已到达设定位置
angleDnCount<=angleDnCount-angleDnCntDec;
else
angleDnCount<=0;
endif;
endif;
endif;
endprocess;
--编码输出电路模块
该模块的功能是将count与angledncount产生的数值经过编码,并利用baBA输出连线信号,将结果输出显示。
baBA<="0000"whenangleDnCount=0else
"0001"whencount=0else
"0011"whencount=1else
"0010"whencount=2else
"0110"whencount=3else
"0100"whencount=4else
"1100"whencount=5else
"1000"whencount=6else
"1001";--whencount>=7;
endstepmotor_arch;
四相步进电机定位控制系统的模块图
四相步进电机定位控制系统的仿真结果
⑴自动模式,顺时针,旋转角为45*11的情况:
⑵自动模式,顺时针,旋转角为45*16的情况:
⑶1-相激磁,逆时针,旋转角为45*7的情况:
⑷1-相激磁,顺时针,旋转角为45*7的情况:
⑸2-相激磁,逆时针,旋转角为45*17的情况:
⑹2-相激磁,逆时针,旋转角为45*17的情况:
⑺1-2-相激磁,顺时针,旋转角为45*11的情况:
⑻1-2-相激磁,顺时针,旋转角为45*8的情况:
直流电机速度控制系统
直流电机速度控制系统功能概述
驱动电路称为桥式驱动或是H型驱动电路(如右图所示),采用的控制方法称为脉冲宽度调制法(PWM),即利用晶体管on-off(导通-不导通)进行控制的方法。
使用FPGA纯数字式的控制时,假设电机速度从静止开始加速,首先Q1、Q2必须维持导通一段时间,此时电机所承受的电压约为供电电压U,称之为强加速。
待速度接近目标速度时,加速可以减缓,此时Q1、Q2和Q3、Q4轮流导通,只是Q1、Q2在一个周期内所导通的时间ton比Q3、Q4导通的时间toff长一些,此时称为弱加速。
任何时候,电机所承受的平均电压U0可表示为U0=U*(ton-toff)(ton+toff)。
如果速度已经达到目标,便可以调整ton和toff的时间比例使之相等,此时平均电压为零,称为定速控制。
由此可知,平均电压若为正值,是加速控制;负值时是减速控制;为0时即达到匀速。
当然,还涉及到确定电机目前的速度是多少,比目标速度快还是慢,也就是速度检测的问题,常用的办法是光遮断法,在此就不再论述了。
在程序仿真时只简单的输入固定的速度模拟一下。
直流电机速度控制系统的VHDL源码及注释
libraryIEEE;
useIEEE.std_logic_1164.all;
useIEEE.std_logic_arith.all;
useIEEE.std_logic_unsigned.all;
entitymotorctrlis
port(clk:
inSTD_LOGIC;--FPGA内部提供的4MHZ的时钟信号
reset:
inSTD_LOGIC;--系统内部自复位信号
speed_now:
inSTD_LOGIC_VECTOR(7downto0);--速度检测编码器检测到的当前速度
target_speed:
inSTD_LOGIC_VECTOR(7downto0);--设定电机预定达到的目标速度
th_speed:
inSTD_LOGIC_VECTOR(7downto0);--设定电机进入弱加速时的临界速度差值
pwme:
outSTD_LOGIC);--脉宽调制的输出,负责控制电机转动的信号
end;
architecturemotorctrl_archofmotorctrlis
--definethesignal_structureandflowofthedevice定义内部信号
signalcnt125:
INTEGERrange0to124;--125个时钟的计数器
signalcnt375:
INTEGERrange0to374;--375个时钟的计数器
signalcnt500:
INTEGERrange0to499;--500个时钟的计数器
signaldth:
STD_LOGIC_VECTOR(7downto0);--设定电机进入弱加速时的临界值(dth=target_speed-th_speed)
signalpwm:
STD_LOGIC;--负责产生脉宽调制的信号,提供正确的输出
--相位类型,负责产生正反转两种状态信号,用来控制电机的加速和减速
phase有2种状态:
状态0:
phase<=phb1,电机正转(加速状态);
状态1:
phase<=phb2,电机反转(减速状态)。
typephase_typeis(phB1,phB2);
signalphase:
phase_type;
--------------------------------------------
--速度类型,负责产生加速、弱加速、减速与定速4种状态信号,以控制电机的转速
speeding4种状态:
状态0:
speeding<=upa,电机进行加速动作;
状态1:
speeding<=upb,电机进行弱加速动作;
状态2:
speeding<=dn,电机进行减速动作;
状态3:
speeding<=final,电机进行定速动作;
typespeeding_typeis(UPA,UPB,Dn,final);
signalspeeding:
speeding_type;
-----------------------------------------------
begin
--速度控制模块
该模块实现下列的控制功能:
1)如果speed_now=target_speed,则定速控制,即ton=toff=ktclk,on-off的时间均等于clk的k倍周期时间;
2)如果speed_now>=target_speed–th_speed,则进行弱加速控制,ton=(3/4)ktclk,toff=(1/4)ktclk;
3)如果speed_now4)如果speed_now>target_speed,则减速控制,ton=(1/4)ktclk,toff=(3/4)ktclk;
另外,方向控制通过将pwme信号的输出反向。
根据上面的分析,需要3个分频器,分别产生ktclk,(1/4)ktclk和(3/4)ktclk的周期信号。
假设时钟周期tclk为10MHz,电机频率为20kHz,因此k=10MHz/20kHz=500,(1/4)k=125,(3/4)=375,这也就是定义cnt125,cnt375,cnt500三个计数器的原因。
peeding_machine:
process(reset,clk)
begin
ifreset='1'then--复位高电平有效
speeding<=UPA;
dth<="00000000";
elsif(clk'eventandclk='1')then
dth<=target_speed-th_speed;--弱加速的临界值
casespeedingis--速度控制状态机
whenUPA=>--情况1
if(speed_now=target_speed)then
speeding<=final;
elsif(speed_now>target_speed)then
speeding<=Dn;
elsif(speed_nowspeeding<=UPA;
elsif(speed_now>=dth)and(speed_nowspeeding<=UPB;
endif;
whenUPB=>--情况2
if(speed_now=target_speed)then
speeding<=final;
elsif(speed_nowspeeding<=UPA;
elsif(speed_now>=dth)and(speed_nowspeeding<=UPB;
elsif(speed_now>target_speed)then
speeding<=Dn;
endif;
whenDn=>--情况3
if(speed_now=target_speed)then
speeding<=final;
elsif(speed_nowspeeding<=UPA;
elsif(speed_now>target_speed)then
speeding<=Dn;
elsif(speed_now>=dth)and(speed_nowspeeding<=UPB;
endif;
whenfinal=>--情况4
if(speed_now>target_speed)then
speeding<=Dn;
elsif(speed_now>=dth)and(speed_nowspeeding<=UPB;
elsif(speed_now=target_speed)then
speeding<=final;
elsif(speed_nowspeeding<=UPA;
endif;
whenothers=>
null;
endcase;
endif;
endprocess;
--相位控制模块
该模块具有下列控制功能:
1)如果希望正向转动(即Q1,Q2导通),则使用状态0:
phb1;
2)如果希望反向移动(即Q3,Q4导通),则使用状态1:
phb2;
上面的速度设定模块只是对有关的输入信号进行判断,告知FPGA用何种模式进行速度控制,并不产生输出信号(pwm)。
因此,必须设计第二个状态判别器“phase”,负责计数与产生pwm(脉宽调制)信号。
phase相位控制器的设计原理如下:
phb1状态为Q1,Q2开启(即pwme=1),而Q3,Q4关闭(即pwme=0)的状态,phb2状态为Q1,Q2关闭,而Q3,Q4开启。
三极管的开关时间依据所激活的计数器而定。
phase_machine:
process(reset,clk)
begin
ifreset='1'then--复位高电平有效
cnt500<=0;
cnt375<=0;
cnt125<=0;
pwm<='0';
pwme<='0';
phase<=phB1;
elsif(clk'eventandclk='1')then
pwme<=pwm;
casephaseis
whenphB1=>
if(speeding=UPA)then
cnt375<=374;
cnt125<=124;
cnt500<=499;
pwm<='1';--加速状态pwm恒为1,不用计数器
elsif(speeding=UPB)then
cnt500<=499;
cnt375<=cnt375-1;
cnt125<=124;
pwm<='1';--弱加速状态pwm输出为1是375个时钟,0为125个时钟
elsif(speeding=Dn)then
cnt500<=499;
cnt375<=cnt375-1;
cnt125<=124;
pwm<='0';--减速状态pwm输出0是375个时钟,1为125个时钟
elsif(speeding=final)then
cnt500<=cnt500-1;
cnt375<=374;
cnt125<=124;
pwm<='1';--匀速状态下,pwm输出1和0的时间均为500个时钟
else
cnt500<=0;
cnt375<=0;
cnt125<=0;
pwm<='0';
endif;
if(cnt375=0orcnt500=0)then--计数器记满后,相位转换
cnt500<=499;
cnt375<=374;
phase<=phB2;
endif;
whenphB2=>
if(speeding=UPA)then
cnt375<=374;
cnt125<=124;
cnt500<=499;
pwm<='1';
elsif(speeding=UPB)then
cnt500<=499;
cnt375<=374;
cnt125<=cnt125-1;
pwm<='0';
elsif(speeding=Dn)then
cnt500<=499;
cnt375<=374;
cnt125<=cnt125-1;
pwm<='1';
elsif(speeding=final)then
cnt500<=cnt500-1;
cnt375<=374;
cnt125<=124;
pwm<='0';
else
cnt500<=