步进电机细分驱动控制系统设计.docx
《步进电机细分驱动控制系统设计.docx》由会员分享,可在线阅读,更多相关《步进电机细分驱动控制系统设计.docx(10页珍藏版)》请在冰豆网上搜索。
步进电机细分驱动控制系统设计
步进电机细分驱动控制系统设计
姓名:
张凯 学号:
20104977
指导老师:
杨小平、杞宁
组员:
张凯 20104977 (组长)
张明 20104991
王涛 20104978
合肥工业大学电子科学与应用物理学院
电子科学与技术系
概述
步进电机在输入状态发生变化时会转过一定的角度,输入状态不变时不会转动,且在不细分输入情况下每次转过较大的角度,再细分情况下每次转过较小的角度。
本设计是利用FPGA实现四相步进电机细分驱动控制,并且系统既能实现步进电机的细分驱动又能实现不细分驱动,还能实现步进电机的正、反转控制。
设计方案与实现
下图是通过QuartusⅡ综合产生的RTL级电路图。
整个电路共分为6大模块:
32进制可加可减计数器(cnt32)、16进制(自加)计数器(cnt16)、4位输出选择器(dec2)、4个4位比较器(new_comp:
moto5、moto6、moto7、moto8)、查找表(rom32)、4位输入4位输出2选1多路选择器(mux2to1)。
其中,u_d控制正反转,s选择细分和不细分,en控制停和转,y[3:
0]接步进电机的4相输入,clk0和clk5为时钟,且clk5>>clk0(本课设选clk0=4Hz,clk5=32768Hz)。
设步进电机的4相输入分别为A、B、C、D。
细分:
cnt32计数输出5位数据送rom32,rom32输出16位数据分别送new_comp:
moto5、moto6、moto7、moto8的a[3:
0]端口与cnt16计数送来的4位数据b[3:
0]比较。
如果a>=b,则agb=1’b1;反之agb=1’b0。
由于clk5>>clk0,从而agb能输出一段占空比稳定的信号(只持续1个或多个clk0周期),即产生1/4、2/4、3/4信号。
再如果s为高电平,则就能实现步进电机的细分输入。
不细分:
如果s为低电平,则mux2to1选通由dec2送来的非细分信号dataa[3:
0],从而实现步进电机的非细分输入。
具体模块源程序
1.32进制可加可减计数器(cnt32)
modulecnt32(clk,en,u_d,cq);
inputclk,en,u_d;
output[4:
0]cq;
reg[4:
0]cq;
always@(posedgeclkorposedgeen)
begin
if(en)
cq<=cq;
else if(u_d)
cq<=cq+1'b1;
else
cq=cq-1'b1;
end
endmodule
2.16进制(自加)计数器(cnt16)
modulecnt16(clk,cq);
inputclk;
outputcq;
reg[3:
0]cq;
always@(posedgeclk)
cq<=cq+1'b1;
Endmodule
3.4位输出选择器(dec2)
moduledec2(clk,a,d);
inputclk;
input[1:
0]a;
output[3:
0]d;
reg[3:
0]d;
always@(posedgeclk)
case(a[1:
0])
2'b00:
d<=4'b1001;
2'b01:
d<=4'b1100;
2'b10:
d<=4'b0110;
2'b11:
d<=4'b0011;
default:
d<=4'bxxxx;
endcase
endmodule
4.4位比较器(new_comp:
moto5、moto6、moto7、moto8)
modulenew_comp(a,b,agb);
input[3:
0]a,b;
outputagb;
regagb;
always@(aorb)
if(a>=b)
agb<=1'b1;
else
agb<=1'b0;
Endmodule
5.查找表(rom32)
通过MIF文件调用LPM库中的ROM产生
MIF文件(文件名为PWM_1.MIF)为:
WIDTH=16;
DEPTH=32;
ADDRESS_RADIX=HEX;
DATA_RADIX=HEX;
CONTENTBEGIN
0 :
f000;
1 :
f600;
2 :
f900;
3 :
fc00;
4 :
ff00;
5 :
cf00;
6 :
9f00;
7 :
6f00;
8 :
0f00;
9 :
0f60;
a :
0f90;
b :
0fc0;
c :
0ff0;
d :
0cf0;
e :
0af0;
f :
06f0;
10 :
00f0;
11 :
00f6;
12 :
00f9;
13 :
00fc;
14 :
00ff;
15 :
00cf;
16 :
009f;
17 :
006f;
18 :
000f;
19 :
600f;
1a :
900f;
1b :
c00f;
1c :
f00f;
1d :
f00c;
1e :
f009;
1f :
f006;
END;
调用过程为:
生成的ROM模块为:
//synopsystranslate_off
`timescale1ps/1ps
//synopsystranslate_on
modulerom32(
address,
clock,
q);
input [4:
0] address;
input clock;
output [15:
0] q;
wire[15:
0]sub_wire0;
wire[15:
0]q=sub_wire0[15:
0];
altsyncram altsyncram_component(
.clock0(clock),
.address_a(address),
.q_a(sub_wire0),
.aclr0(1'b0),
.aclr1(1'b0),
.address_b(1'b1),
.addressstall_a(1'b0),
.addressstall_b(1'b0),
.byteena_a(1'b1),
.byteena_b(1'b1),
.clock1(1'b1),
.clocken0(1'b1),
.clocken1(1'b1),
.data_a({16{1'b1}}),
.data_b(1'b1),
.q_b(),
.rden_b(1'b1),
.wren_a(1'b0),
.wren_b(1'b0));
defparam
altsyncram_component.address_aclr_a="NONE",
altsyncram_component.init_file="PWM_1.MIF",
altsyncram_component.intended_device_family="Cyclone",
altsyncram_component.lpm_hint="ENABLE_RUNTIME_MOD=NO",
altsyncram_component.lpm_type="altsyncram",
altsyncram_component.numwords_a=32,
altsyncram_component.operation_mode="ROM",
altsyncram_component.outdata_aclr_a="NONE",
altsyncram_component.outdata_reg_a="CLOCK0",
altsyncram_component.widthad_a=5,
altsyncram_component.width_a=16,
altsyncram_component.width_byteena_a=1;
endmodule
6.4位输入4位输出2选1多路选择器(mux2to1)
modulemux2to1(dataa,datab,sel,result);
input[3:
0]dataa,datab;
inputsel;
output[3:
0]result;
reg[3:
0]result;
always@(selordataaordatab)
if(sel)
result<=datab;
else
result<=dataa;
Endmodule
7.顶层模块(setp_moto)
modulesetp_moto(clk0,u_d,clk5,en,s,y);
inputclk0,clk5,u_d,s,en;
output[3:
0]y;
reg[3:
0]y;
wire[4:
0]cq1;
wire[3:
0]cq2,d;
wire[15:
0]q;
wireagb1,agb2,agb3,agb4;
cnt32moto1(.clk(clk0),.en(en),.u_d(u_d),.cq(cq1));
cnt16moto2(.clk(clk5),.cq(cq2));
dec2moto3(.clk(clk0),.a(cq1[1:
0]),.d(d));
rom32moto4(.clock(clk0),.address(cq1),.q(q));
new_compmoto5(.a(q[15:
12]),.b(cq2),.agb(agb1));
new_compmoto6(.a(q[11:
8]),.b(cq2),.agb(agb2));
new_compmoto7(.a(q[7:
4]),.b(cq2),.agb(agb3));
new_compmoto8(.a(q[3:
0]),.b(cq2),.agb(agb4));
mux2to1moto9(.sel(s),.dataa(d),.datab({agb1,agb2,agb3,agb4}),.result(y));
Endmodule
结果与分析
上图为不细分时的波形图。
由图可以看出,每次clk0上升沿输出y[3:
0]就会发生变化,从而实现步进电机的不细分输入(DA→AB→BC→CD→DA)。
由于细分时的时钟频率不能调太小(调太小的话,仿真时容易卡机;但如果不调小的话,就产生不了比较好的波形。
),所以这里就不给出细分时的波形图了。
通过QuartusⅡ产生了正确的RTL级电路图(见附录),下到FPGA实验箱上步进电机实现了细分转动和非细分转动,以及正反转。
(本课设采用4细分)
心得与体会
虽然我们做得晚,但由于我们理解了电路原理,并且给了我们VHDL的源程序,所以我们仅用了1天多一点的时间就把Verilog程序写出来了,并下载到实验箱上跑。
如果不给我们VHDL程序的话,我们做得就有可能吃力许多。
也有许多人就看不懂VHDL程序,幸亏当初我好好学了,那点程度的程序对我来说根本没压力。
这也是我们能把VHDL程序迅速翻译成Verilog程序的一个原因。
当然,Verilog的语法我已经忘了不少,我是边翻译边看书做的。
当初Verilog实验的时候我就做得很好,并且Modelsim也会用,所以我对QuartusⅡ和Modelsim很快就上手了。
我现在基本上不看书,多亏了本次课设,又让我回顾了以前学过的许多东西,也锻炼了我的动手和分析编程能力。
当然,我也学到了许多,认识到了自己知识的匮乏,自己还有很多要学的,所学的东西都是皮毛。
唯一感到吃力的是ROM模块的生成。
因为是第一次调用内部模块,我按照老师所给的例子操作总是不能成功,最后请教杨老师,原来是没建工程。
老师给的例子就没建工程,导致我也没建工程,究其原因是我太死板了,干什么事都太按部就班了,这点我应当改。
MIF文件是怎么产生的我也不清楚,老师给了我们MIF文件,我也就没深研究。
虽然不太清楚步进电机是怎么工作的,但我知道它的工作模式分为细分和不细分。
细分转得慢,不细分转得快。
只有在它的输入状态切换时它才会转过一定的角度,输入状态不变时它就不转。
附录:
QuartusⅡ综合产生的RTL级电路图