m FPGA-based FOC controller verilog implementation, including CLARK, PARK, PID and SVPWM, including testbench

Table of contents

1. Algorithm simulation effect

2. Algorithms involve an overview of theoretical knowledge

3. MATLAB core program

4. Complete algorithm code file


1. Algorithm simulation effect

Quartus II 12.1(64-Bit)

ModelSim-Altera 6.6d Starter Edition

The simulation results are as follows:

2. Algorithms involve an overview of theoretical knowledge

The structure of the whole system is as follows:

1. Collect two-phase current

2. After the Clarke transformation, the two-axis orthogonal current is obtained,

3. Obtain the orthogonal current quantities Id and Iq after rotation transformation, where Iq is related to torque, and Id is related to magnetic flux. In actual control, Id is often set to 0. The obtained two quantities are not time-varying, so these two quantities can be controlled independently, similar to the DC flow control. It is not necessary to know the specific voltage to be given to the three-phase motor.

4. Send the Iq and Id quantities obtained in the third step to the PI regulator respectively to obtain the corresponding output Vq and Vd;

5. Obtain the rotation angle of the motor through the sensor.

6. Carry out inverse park transformation to obtain the two-axis current.

7. Carry out inverse Clarke transformation on Va and Vb in step 6 to obtain the actual required three-phase voltage and input it to the inverter bridge to drive the motor to rotate.

       What FOC controls is actually the direction of the electromagnetic field of the motor. The rotor torque of the rotor is proportional to the vector product of the stator magnetic field vector and the rotor magnetic field vector. It can be seen from the relationship of the vectors that if the torque of the motor is kept maximum at all times, the stator magnetic field vector and the rotor magnetic field vector should be perpendicular to each other. And because the magnitude and direction of the magnetic field are directly related to the magnitude and direction of the current, the key to controlling the BLDC with the FOC control algorithm is to control the magnitude and direction of the three-phase input current. The key to controlling the current to generate the stator magnetic field perpendicular to the rotor magnetic field is to control the stable three-phase input voltage and its current vector, and we have to know the real-time position of the rotor.

       Direction control of input current, FOC gives the concept of space current vector. Its essence is to combine the three-phase current vectors, and then decompose them into two components perpendicular to and parallel to the rotor magnet axis direction, that is, the dq structure. The magnetic field generated by the current component in the vertical direction is perpendicular to the magnetic field of the rotor, which produces the rotational torque. However, the current component parallel to the rotor magnetic axis will generate a magnetic field consistent with the rotor magnetic field, and no torque will be generated. In addition, a good control algorithm needs to minimize the current component parallel to the rotor magnetic axis, because this current component will only cause excess heat in the motor and increase bearing wear. We need to control the coil current so that the current component in the direction perpendicular to the rotor magnetic axis is maximized. The resulting motor torque is proportional to the magnitude of this current component.

3. Verilog core program

...................................................................
PID_tops PID_tops_u(
                .i_clk   (i_clk),
					 .i_rst   (i_rst),
					 .i_kp    (16'b0001_1111_1111_1111),
					 .i_ki    (16'b0000_0000_0010_0011),
					 .i_kd    (16'b0000_0000_0000_0001),
					 .i_din   (err1),
					 .o_dout  (o_pid_dout),
					 //test port
					 .o_doutp (),
					 .o_douti (),
					 .o_doutd ()
               );
	
wire signed[15:0]o_Id;
wire signed[15:0]o_Iq;
wire signed[15:0]err11;	
wire signed[15:0]err12;	

assign err11 = o_pid_dout-o_Id;
assign err12 = 0-o_Iq;


wire signed[15:0]o_pid_dout1;
wire signed[15:0]o_pid_dout2;							

PID_tops PID_tops_u1(
                .i_clk   (i_clk),
					 .i_rst   (i_rst),
					 .i_kp    (16'b0001_1111_1111_1111),
					 .i_ki    (16'b0000_0000_0010_0011),
					 .i_kd    (16'b0000_0000_0000_0001),
					 .i_din   (err11),
					 .o_dout  (o_pid_dout1),
					 //test port
					 .o_doutp (),
					 .o_douti (),
					 .o_doutd ()
               );	
	
	
PID_tops PID_tops_u2(
                .i_clk   (i_clk),
					 .i_rst   (i_rst),
					 .i_kp    (16'b0001_1111_1111_1111),
					 .i_ki    (16'b0000_0000_0010_0011),
					 .i_kd    (16'b0000_0000_0000_0001),
					 .i_din   (err12),
					 .o_dout  (o_pid_dout2),
					 //test port
					 .o_doutp (),
					 .o_douti (),
					 .o_doutd ()
               );

//
//INV PARK					
wire signed[15:0]o_Uaref;				
wire signed[15:0]o_Ubref;
INVPARK INVPARK_u(
               .i_clk   (i_clk),
					.i_rst   (i_rst),
					.i_D     (o_pid_dout1),
					.i_Q     (o_pid_dout2),
					.i_theta (o_theta),
					.o_alpha (o_Uaref),
					.o_beta  (o_Ubref)
              );					
					
//
//SVPWM
wire w_PWM1;
wire w_PWM2;
wire w_PWM3;
wire w_PWM4;
wire w_PWM5;
wire w_PWM6;

SVPWM SVPWM_u(
            .i_clk  (i_clk),
				.i_rst  (i_rst),
				.i_Uaref(o_Uaref),
				.i_Ubref(o_Ubref),
				.o_PWM1 (w_PWM1),
				.o_PWM2 (w_PWM2),
				.o_PWM3 (w_PWM3),
				.o_PWM4 (w_PWM4),
				.o_PWM5 (w_PWM5),
				.o_PWM6 (w_PWM6)
            );

//
//IGBT+PMSM
IGBT_PMSM_simple IGBT_PMSM_simple_u(
                       .i_clk  (i_clk),
							  .i_rst  (i_rst),
							  .i_PWM1 (w_PWM1),
							  .i_PWM2 (w_PWM2),
							  .i_PWM3 (w_PWM3),
							  .i_PWM4 (w_PWM4),
							  .i_PWM5 (w_PWM5),
							  .i_PWM6 (w_PWM6),
							  .i_pid  (o_pid_dout),
							  .i_Te   (16'd100),
							  .o_Ia   (o_Ia),
							  .o_Ib   (o_Ib),
							  .o_Ic   (o_Ic),
							  .o_Te   (o_Te),
							  .o_Wm   (o_Wm),
							  .o_theta(o_theta)
                       );

//
//CLARK
CLARK CLARK_u(
             .i_clk (i_clk),
				 .i_rst (i_rst),
				 .i_Ia  (o_Ia),
				 .i_Ib  (o_Ib),
				 .o_Id  (o_Ialpha),
				 .o_Iq  (o_Ibeta)
            );

//
//PARK	
PARK PARK_u(
               .i_clk   (i_clk),
					.i_rst   (i_rst),
					.i_d     (o_Ialpha),
					.i_q     (o_Ibeta),
					.i_theta (o_theta),
					.o_ID    (o_Id),
					.o_IQ    (o_Iq)
              );
 
endmodule 
08_060_m		  

4. Complete algorithm code file

V

Guess you like

Origin blog.csdn.net/hlayumi1234567/article/details/130414748