Using the KMS SVPWM to Create a 3 Phase PWM Modulator without a Motor

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using the KMS SVPWM to Create a 3 Phase PWM Modulator without a Motor

807 Views
derekcook
Senior Contributor I

Hello, 

I am using the mkv31f512vll12p. I would like to use the SVPWM KMS block to create a constant 200V 50Hz 3 phase PWM to validate my IGBT hardware. How would I go about doing this? I do not have a motor connected to the system during the validation. Therefore, there is no resolver or encoder reading in the rotor angle of the motor. Because of this, I have commented out most of the DRV_updateAtFastTick() to test this out. I have also tried this with the commented parts of DRV_updateAtFastTick() left in.

I see the SVPWM block takes in as an input the stationary voltage reference frame from the IPARK block, which takes in as an input the rotor angle and voltage reference to produce this. 

pastedImage_1.png

pastedImage_2.png

I have tried a couple of things: 

##

1) Using a stationary rotor angle. It looks like KMS expects this to be between -_LQ(1.0) and _LQ(1.0)? 

2) Using a rotor angle that increments from -_LQ(1.0) to _LQ(1.0) changing _LQ(0.1) every fast tick. 

Stationary rotor angle:

/* START SVPWM BLOCK ***********************************************************/
/* Turn inverter switches on */
SVPWM_enable(&svpwm);
// Define Rotor Angle

tempAngle = _LQ(1.0); 

// Define Reference Voltage
tempStatorRefVoltageDQ.d = _LQ(0.0);
tempStatorRefVoltageDQ.q = _LQ(200.0);

// Assign sin and cos of angle
_LQsincosPU(tempAngle, &tempOrient.sinAngle, &tempOrient.cosAngle);

// Run Inverse Park Transform
IPARK_run(&ipark, &tempOrient, &tempStatorRefVoltageDQ);

// Run 3 Phase PWM
SVPWM_updateFastTick(&svpwm, &(ipark.output.vector), ipark.output.magnitude);
/* END SVPWM BLOCK *************************************************************/

Rotating Rotor Angle: 

/* START SVPWM BLOCK ***********************************************************/
/* Turn inverter switches on */
SVPWM_enable(&svpwm);
// Define Rotor Angle
if(rotorAngle < 0.9)
{
rotorAngle += 0.1;
}

else
{
rotorAngle = -1.0;
}

tempAngle = _LQ(rotorAngle); // between -LQ(1.0) and LQ(1.0)

// Define Reference Voltage
tempStatorRefVoltageDQ.d = _LQ(0.0);
tempStatorRefVoltageDQ.q = _LQ(200.0);

// Assign sin and cos of angle
_LQsincosPU(tempAngle, &tempOrient.sinAngle, &tempOrient.cosAngle);

// Run Inverse Park Transform
IPARK_run(&ipark, &tempOrient, &tempStatorRefVoltageDQ);

// Run 3 Phase PWM
SVPWM_updateFastTick(&svpwm, &(ipark.output.vector), ipark.output.magnitude);
/* END SVPWM BLOCK *************************************************************/

I never see any PWM output out of the Phase A, B and C PWM outputs. This remains low. Also, if I want 200V out am I correct to do this? 

// Define Reference Voltage
tempStatorRefVoltageDQ.d = _LQ(0.0);
tempStatorRefVoltageDQ.q = _LQ(200.0);

Thanks for your assistance in this matter, 

Derek

Labels (1)
3 Replies

589 Views
derekcook
Senior Contributor I

Hey Adam and Philip, 

Thanks for your help! I figured it out. All I had to do was call the following commands: 

user.state = USER_RUN_VOLTAGE;
user.command.statorRefVoltage.d = _LQ(0.0);
user.command.statorRefVoltage.q = _LQ(0.50);
user.state = USER_RUN_VOLTAGE;
user.command.statorRefVoltage.d = _LQ(0.0);
user.command.statorRefVoltage.q = _LQ(0.50);

This produces a three phase PWM using the SVPWM block. 

I hardcoded in the 0.50 which gave me 50% of my 400VAC input voltage, 200V. The scaling was an important mistake I was making. It is important that this value is scaled _LQ(0.0) to _LQ(1.0). To achieve this I could also have done: _LQ(200.0 / FULL_SCALE_VOLTAGE). 

It is also important to replace the rotorAngle output from the QEI block with a simulated rotating rotor angle, or you will just get a DC output from the SVPWM block (because the rotor angle is not changing because the motor is disconnected). I did this by creating a 50Hz rotating angle from _LQ(-1.0) -> _LQ(1.0), and then wrapping the angle back around to -1 once it reached 1. This value was set to the rotorAngle value. 

589 Views
linestream-adam
Senior Contributor I

Derek,

Your concept is spot on. I think the issues you are running into are due to the normalization scheme in KMS.

All voltages in the KMS firmware are normalized against the FULL_SCALE_VOLTAGE define in the system.h file.  So to specify a voltage you would need to make your call look like this:

tempStatorRefVoltageDQ.q = _LQ(200.0 / FULL_SCALE_VOLTAGE);

But, the Park block specifically takes the input in terms of modulation, NOT voltage.  So your call should change to:

tempStatorRefVoltageDQ.q = _LQmpy(_LQ(200.0 / FULL_SCALE_VOLTAGE), feedback.output.invVdc_1kHz);

That will convert your 200V into the normalized version (by dividing by the normalizing factor) and convert it into modulation by dividing by the current bus voltage (multiplying by the inverse of the bus voltage).

You also might have removed the call that will enable the PWM outputs.  Look for a function call SVPWM_enable.

0 Kudos

589 Views
philip_drake
NXP Employee
NXP Employee

What other engineers have done with their custom hardware is use the tools available in the KMS GUI.

What I would suggest is that you use the notes in the Adapting KMS for Custom Hardware see section 4 on page 52 on how to verify the operation of your hardware from the KMS GUI. The concepts used in this app note are covered in the Lab Guide if you need to figure out some of the use of the GUI.

Try this before going through the trouble of re-architecting the reference design.

Best Regards,

Philip Drake.

0 Kudos