1.软件版本
matlab2013b,ISE14.7
2.系统原理
我们把里面的各个模块进行仿真:
模块一的设计:
先设计第一级的三个模块:
这里,这三个模块都是一样的,其基本的公式为:
里面的公式是,首先是WT输出cos和sin对应公式中的1和2
然后abc三相输出为3,4,5角。里面的公式为:
simulink仿真结果如下所示:
我们设计的FPGA的仿真结果如下所示:
这里,我们主要对多个不同截止频率的低通滤波器进行设计。
这里,主要有截止频率为10,30,100,和8000四种不同的截止频率的低通滤波器
在simulink中仿真结果如下所示:
我们设计的fpga仿真结果如下所示:
dq转ABC的模块:
u[1]*u[4] + u[2]*u[3]
.5*(-u(1)+1.732*u(2))*u(4) + .5*(-u(2)-1.732*u(1))*u(3)
我们再FPGA中进行设计。得到的仿真结果如下所示:
然后进行整个控制器的设计:
我们根据控制器的内部结构进行编程:
整个模块的整体构架如下所示:
整个程序分为两个顶层文件,上面这个是我在FPGA内部模拟的测试调用文件,你不需要看这个,
下面这个是根据你的simulink设计的顶层模块,其基本管脚如下所示:
注意,输入的三相电流和电压部分,在FPGA中设计必须分开写,所以输入脚看上去很多,实际就是几个三相变量,另外输入部分的i_clk和i_rst是fpga必须用的脚,一个是时钟变量,一个是复位,正常工作的时候复位为0,如果复位为1,那么系统初始化为0.
再看输出,也是simulink对应的,其中几个test变量,是我在设计过程中保留的测试端口,实际中不使用。
然后我们看整个控制器的测试,将设置为顶层文件,然后进行仿真,仿真结果如下所示:
其中六个控制PWM波形如下所示:
3.部分源码
-
`timescale
1ns /
1ps
-
//
-
// Company:
-
// Engineer:
-
//
-
// Create Date: 02:07:36 11/24/2013
-
// Design Name:
-
// Module Name: Controller_tops
-
// Project Name:
-
// Target Devices:
-
// Tool versions:
-
// Description:
-
//
-
// Dependencies:
-
//
-
// Revision:
-
// Revision 0.01 - File Created
-
// Additional Comments:
-
//
-
//
-
module Controller_tops(
-
i_clk,
-
i_rst,
-
i_ifa,i_ifb,i_ifc,
-
i_iia,i_iib,i_iic,
-
i_vdc,
-
i_vsa,i_vsb,i_vsc,
-
i_vsa1,i_vsb1,i_vsc1,
-
o_PWM1,o_PWM2,o_PWM3,o_PWM4,o_PWM5,o_PWM6,
-
o_power,
-
o_wt,
-
o_connect,
-
o_af_on,
-
o_test_port1,
-
o_test_port2,
-
o_test_port3,
-
o_test_port4
-
);
-
-
parameter VDC =
10;
-
-
input i_clk;
-
input i_rst;
-
input signed[
11:
0]i_ifa,i_ifb,i_ifc;
-
input signed[
11:
0]i_iia,i_iib,i_iic;
-
input signed[
11:
0]i_vdc;
-
input signed[
11:
0]i_vsa,i_vsb,i_vsc;
-
input signed[
11:
0]i_vsa1,i_vsb1,i_vsc1;
-
-
output signed[
1:
0]o_PWM1,o_PWM2,o_PWM3,o_PWM4,o_PWM5,o_PWM6;
-
output signed[
11:
0]o_power;
-
output [
10:
0]o_wt;
-
output o_connect;
-
output o_af_on;
-
-
output signed[
11:
0]o_test_port1;
-
output signed[
11:
0]o_test_port2;
-
output signed[
11:
0]o_test_port3;
-
output signed[
11:
0]o_test_port4;
-
-
//PLL
-
reg [
10:
0]o_wt;
-
always @(posedge i_clk
or posedge i_rst)
-
begin
-
if(i_rst)
-
begin
-
o_wt <=
11'd0;
-
end
-
else begin
-
o_wt <= o_wt +
11'd20;
-
end
-
end
-
-
-
-
-
-
//===========================================================================
-
//abc>dq i_filt stationary
-
//===========================================================================
-
wire signed[
11:
0]d_ifa;
-
wire signed[
11:
0]q_ifa;
-
-
abc_dq abc_dq_ifabc(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_A (i_ifa),
-
.i_B (i_ifb),
-
.i_C (i_ifc),
-
.i_theta (11'd0),
-
.o_d (d_ifa),
-
.o_q (q_ifa),
-
.test_cos(),
-
.test_sin()
-
);
-
-
wire signed[
11:
0]d_ifa_filter;
-
wire signed[
11:
0]q_ifa_filter;
-
lowpass_8000Hz_tops lowpass_8000Hz_uifabc1(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_data (d_ifa),
-
.o_data (d_ifa_filter)
-
);
-
-
lowpass_8000Hz_tops lowpass_8000Hz_uifabc2(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_data (q_ifa),
-
.o_data (q_ifa_filter)
-
);
-
-
-
-
-
//===========================================================================
-
//abc>dq i_load rotating
-
//===========================================================================
-
wire signed[
11:
0]d_iload;
-
wire signed[
11:
0]q_iload;
-
-
abc_dq abc_dq_iload(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_A (i_iia),
-
.i_B (i_iib),
-
.i_C (i_iic),
-
.i_theta (o_wt),
-
.o_d (d_iload),
-
.o_q (q_iload),
-
.test_cos(),
-
.test_sin()
-
);
-
-
wire signed[
11:
0]q_iload_filter;
-
wire signed[
11:
0]q_iload_filter2;
-
lowpass_10Hz_tops lowpass_10Hz_tops_iload(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_data(q_iload),
-
.o_data(q_iload_filter)
-
);
-
-
assign q_iload_filter2 = q_iload-q_iload_filter;
-
-
assign o_power = q_iload_filter;
-
-
-
-
wire signed[
11:
0]add1;
-
wire signed[
11:
0]add2;
-
wire signed[
11:
0]add3;
-
wire signed[
11:
0]add4;
-
wire signed[
11:
0]add5;
-
-
-
-
assign add1 = d_iload;
-
assign add3 = q_iload_filter2;
-
assign add4 = (q_iload_filter>=
28)?
4:
0;
-
-
-
//VDC
-
wire signed[
11:
0]vdc_filter;
-
wire signed[
11:
0]vdc_filterx;
-
lowpass_30Hz_tops lowpass_30Hz_tops_vdc(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_data(i_vdc),
-
.o_data(vdc_filter)
-
);
-
-
assign vdc_filterx = VDC-vdc_filter;
-
-
wire flag;
//<-0.1
-
assign flag = (q_iload_filter <
-128)?
1:
0;
-
-
wire signed[
11:
0]PIDX;
-
wire signed[
11:
0]PID;
-
wire signed[
11:
0]PIDO;
-
reg signed[
11:
0]PID1;
-
reg signed[
11:
0]PID21;
-
reg signed[
11:
0]PID22;
-
always @(posedge i_clk
or posedge i_rst)
-
begin
-
if(i_rst)
-
begin
-
PID1 <=
12'd0;
-
PID21 <=
12'd0;
-
PID22 <=
12'd0;
-
end
-
else begin
-
PID1 <= vdc_filterx;
-
PID21 <= PID21+vdc_filterx;
-
PID22 <= PID21;
-
end
-
end
-
assign PIDX = PID21;
-
-
assign PID = PID1/
64 + PIDX/
128;
-
-
assign PIDO = (flag >
0)? vdc_filterx:
0;
-
-
wire signed[
11:
0]d_vr;
-
wire signed[
11:
0]q_vr;
-
-
-
wire signed[
23:
0]add2s;
-
wire signed[
23:
0]add5s;
-
assign add2s = PIDO*d_vr;
-
assign add5s = PIDO*q_vr;
-
-
assign add2 = add2s[
23:
12];
-
assign add5 = add5s[
23:
12];
-
-
wire signed[
11:
0]vds;
-
wire signed[
11:
0]vqs;
-
assign vds = add1 + add2;
-
assign vqs = add3 + add4 + add5;
-
-
-
wire signed[
11:
0]Axx;
-
wire signed[
11:
0]Bxx;
-
wire signed[
11:
0]Cxx;
-
-
dq_abc dq_abc_u5(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_wt (o_wt),
-
.i_vd (vds),
-
.i_vq (vqs),
-
.o_At (Axx),
-
.o_Bt (Bxx),
-
.o_Ct (Cxx)
-
);
-
-
-
-
-
-
wire signed[
11:
0]dvrrr;
-
wire signed[
11:
0]qvrrr;
-
abc_dq abc_dq_vr(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_A (Axx),
-
.i_B (Bxx),
-
.i_C (Cxx),
-
.i_theta (0),
-
.o_d (dvrrr),
-
.o_q (qvrrr),
-
.test_cos(),
-
.test_sin()
-
);
-
-
-
-
-
-
-
//===========================================================================
-
//abc >dq Vsource rotating
-
//===========================================================================
-
-
-
abc_dq abc_dq_vr22(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_A (i_vsa),
-
.i_B (i_vsb),
-
.i_C (i_vsc),
-
.i_theta (o_wt),
-
.o_d (d_vr),
-
.o_q (q_vr),
-
.test_cos(),
-
.test_sin()
-
);
-
-
wire signed[
11:
0]d_vr_filter;
-
wire signed[
11:
0]q_vr_filter;
-
lowpass_100Hz_tops lowpass_100Hz_vr1(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_data (d_vr),
-
.o_data (d_vr_filter)
-
);
-
-
lowpass_100Hz_tops lowpass_100Hz_vr2(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_data (q_vr),
-
.o_data (q_vr_filter)
-
);
-
-
-
//===========================================================================
-
//abc >dq Vsource1 rotating
-
//===========================================================================
-
wire signed[
11:
0]d_vr1;
-
wire signed[
11:
0]q_vr1;
-
-
abc_dq abc_dq_vr1(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_A (i_vsa1),
-
.i_B (i_vsb1),
-
.i_C (i_vsc1),
-
.i_theta (o_wt),
-
.o_d (d_vr1),
-
.o_q (q_vr1),
-
.test_cos(),
-
.test_sin()
-
);
-
-
wire signed[
11:
0]d_vrx;
-
wire signed[
11:
0]q_vrx;
-
assign d_vrx = d_vr - d_vr1;
-
assign q_vrx = q_vr - q_vr1;
-
-
-
wire signed[
11:
0]d_vrx_filter;
-
wire signed[
11:
0]q_vrx_filter;
-
lowpass_100Hz_tops lowpass_100Hz_vr11(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_data (d_vrx),
-
.o_data (d_vrx_filter)
-
);
-
-
lowpass_100Hz_tops lowpass_100Hz_vr12(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_data (q_vrx),
-
.o_data (q_vrx_filter)
-
);
-
-
wire signed[
11:
0]d_vrx_filter2;
-
wire signed[
11:
0]q_vrx_filter2;
-
assign d_vrx_filter2 = {d_vrx_filter[
11],d_vrx_filter[
11],d_vrx_filter[
11],d_vrx_filter[
11:
3]};
-
assign q_vrx_filter2 = {q_vrx_filter[
11],q_vrx_filter[
11],q_vrx_filter[
11],q_vrx_filter[
11],q_vrx_filter[
11:
4]};
-
-
wire signed[
11:
0]o_Avrx;
-
wire signed[
11:
0]o_Bvrx;
-
wire signed[
11:
0]o_Cvrx;
-
-
dq_abc dq_abc_u1(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_wt (o_wt),
-
.i_vd (d_vrx_filter2),
-
.i_vq (q_vrx_filter2),
-
.o_At (o_Avrx),
-
.o_Bt (o_Bvrx),
-
.o_Ct (o_Cvrx)
-
);
-
-
-
-
-
-
//===========================================================================
-
//xxxxxxxxxxxxxxxxxxxxx
-
//===========================================================================
-
wire signed[
11:
0]d_vrx1;
-
wire signed[
11:
0]q_vrx1;
-
wire signed[
11:
0]d_vrx2;
-
wire signed[
11:
0]q_vrx2;
-
wire signed[
11:
0]d_vrxx2;
-
wire signed[
11:
0]q_vrxx2;
-
abc_dq abc_dq_dqvx1(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_A (i_vsa),
-
.i_B (i_vsb),
-
.i_C (i_vsc),
-
.i_theta (o_wt),
-
.o_d (d_vrx1),
-
.o_q (q_vrx1),
-
.test_cos(),
-
.test_sin()
-
);
-
-
abc_dq abc_dq_dqvx2(
-
.i_clk (i_clk),
-
.i_rst (i_rst),
-
.i_A (o_Avrx),
-
.i_B (o_Bvrx),
-
.i_C (o_Cvrx),
-
.i_theta (o_wt),
-
.o_d (d_vrx2),
-
.o_q (q_vrx2),
-
.test_cos(),
-
.test_sin()
-
);
-
-
assign d_vrxx2 = d_vrx1 - d_vrx2;
-
assign q_vrxx2 = q_vrx1 - q_vrx2;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
wire signed[
11:
0]X1;
-
wire signed[
11:
0]X2;
-
wire signed[
11:
0]X3;
-
wire signed[
11:
0]X4;
-
wire signed[
11:
0]X5;
-
wire signed[
11:
0]X6;
-
-
assign X1 = dvrrr-d_ifa_filter;
-
assign X2 = qvrrr-q_ifa_filter;
-
assign X3 = {i_vdc[
11],i_vdc[
11:
1]};
-
assign X4 = d_vrxx2;
-
assign X5 = q_vrxx2;
-
assign X6 = o_wt;
-
-
-
-
-
wire signed[
15:
0]r1r;
-
wire signed[
15:
0]r2r;
-
-
assign r1r =
5*X1 + X4;
-
assign r2r =
5*X2 + X5;
-
-
wire signed[
23:
0]r1r2;
-
wire signed[
23:
0]r2r2;
-
-
assign r1r2 =
-887*r1r;
-
assign r2r2 =
887*r2r;
-
-
wire signed[
11:
0]r1r3;
-
wire signed[
11:
0]r2r3;
-
-
assign r1r3 = r1r2[
23:
12];
-
assign r2r3 = r2r2[
23:
12];
-
-
-
-
//generator PWM
-
wire signed[
11:
0]SVGA;
-
wire signed[
11:
0]SVGB;
-
wire signed[
11:
0]SVGC;
-
SVG SVG_u(
-
.i_clk(i_clk),
-
.i_rst(i_rst),
-
.i_m(r1r3),
-
.i_n(r2r3),
-
.o_A(SVGA),
-
.o_B(SVGB),
-
.o_C(SVGC)
-
);
-
-
-
reg signed[
1:
0] seq;
-
reg [
7:
0]cnt00;
-
always @(posedge i_clk
or posedge i_rst)
-
begin
-
if(i_rst)
-
begin
-
cnt00 <=
8'd0;
-
end
-
else begin
-
cnt00 <= cnt00 +
1;
-
if(cnt00[
7:
6] ==
2'b00)
-
seq <=
2'b00;
-
if(cnt00[
7:
6] ==
2'b01)
-
seq <=
2'b01;
-
if(cnt00[
7:
6] ==
2'b10)
-
seq <=
2'b00;
-
if(cnt00[
7:
6] ==
2'b11)
-
seq <=
2'b11;
-
end
-
end
-
-
assign o_PWM1 = (SVGA[
11:
10] > seq)?
2'b01 :
2'b11;
-
assign o_PWM2 = ~o_PWM1;
-
assign o_PWM3 = (SVGB[
11:
10] > seq)?
2'b01 :
2'b11;
-
assign o_PWM4 = ~o_PWM3;
-
assign o_PWM5 = (SVGC[
11:
10] > seq)?
2'b01 :
2'b11;
-
assign o_PWM6 = ~o_PWM5;
-
-
-
-
assign o_test_port1 = r1r[
15:
4];
-
assign o_test_port2 = r2r[
15:
4];
-
assign o_test_port3 = r1r3;
-
assign o_test_port4 = r2r3;
-
-
-
-
wire flag1;
-
wire flag2;
-
wire flag0;
-
-
assign flag1=(o_wt >=
12'd1900)?
1:
0;
-
assign flag2=(o_wt <=
12'd2000)?
1:
0;
-
-
assign flag0= flag1 & flag2;
-
-
reg o_connect;
-
reg o_af_on;
-
reg[
7:
0]cnt1;
-
reg[
7:
0]cnt2;
-
reg flagd;
-
-
always @(posedge i_clk
or posedge i_rst)
-
begin
-
if(i_rst)
-
begin
-
flagd<=
1'b0;
-
end
-
else begin
-
flagd <= flag0;
-
end
-
end
-
-
-
always @(posedge i_clk
or posedge i_rst)
-
begin
-
if(i_rst)
-
begin
-
cnt1 <=
8'd0;
-
o_connect <=
1'b0;
-
end
-
else begin
-
-
if(flagd == 1'b0 & flag0 == 1'b1)
-
begin
-
if(cnt1 == 10)
-
cnt1 <=
1;
-
else
-
cnt1 <= cnt1 +
1;
-
end
-
else begin
-
cnt1 <= cnt1;
-
end
-
if(cnt1 == 10)
-
o_connect <=
1'b1;
-
else
-
o_connect <=
1'b0;
-
end
-
end
-
-
-
always @(posedge i_clk
or posedge i_rst)
-
begin
-
if(i_rst)
-
begin
-
cnt2 <=
8'd0;
-
o_af_on <=
1'b0;
-
end
-
else begin
-
if(flagd == 1'b0 & flag0 == 1'b1)
-
begin
-
if(cnt2 == 5)
-
cnt2 <=
1;
-
else
-
cnt2 <= cnt2 +
1;
-
end
-
else begin
-
cnt2 <= cnt2;
-
end
-
if(cnt2 == 5)
-
o_af_on <=
1'b1;
-
else
-
o_af_on <=
1'b0;
-
end
-
end
-
-
-
-
-
-
-
-
-
-
-
//output
-
//output signed[1:0]o_PWM1,o_PWM2,o_PWM3,o_PWM4,o_PWM5,o_PWM6;
-
//output signed[11:0]o_power;
-
//output signed[10:0]o_wt;
-
//output signed[11:0]o_connect;
-
//output signed[11:0]o_af_on;
-
-
-
endmodule
A08-24
转载:https://blog.csdn.net/ccsss22/article/details/125688785