Tool/software: Code Composer Studio
Hi,
I am working on Advanced Bus Clamped PWM Method (ABC-PWM) using space vector that involves double switching of a phase in specific sector number. I have implemented a space vector Macro for its implementation with 12 sectors since the applied switching sequence has to change after every 30 degrees. But I am facing a problem in portions where phase is supposed to double switch. For the ABC-PWM, I require:
Phase A (PWM12) to double switch in Sector 1,2,7,8
Phase B (PWM11) to double switch in Sector 3,4,9,10
Phase C (PWM9) to double switch in Sector 5,6,11,12
For this double switching, I have used Compare 'B' Registers (EPwmxxRegs.CMPB.bit.CMPB) of the respective PWM signals since Compare 'A' Registers were already used in normal switching.
I have implemented following code for double switching:
if ((svgen1.VecSector == 1)||(svgen1.VecSector == 2)||(svgen1.VecSector == 7)||(svgen1.VecSector == 8))
{
EPwm12Regs.CMPB.bit.CMPB = usCmpValD; //phase B double switches is sector 1 & 2
EPwm12Regs.AQCTLA.bit.CBU = AQ_SET;
EPwm12Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm12Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm12Regs.AQCTLB.bit.CBD = AQ_SET;
}
else if ((svgen1.VecSector == 3)||(svgen1.VecSector == 4)||(svgen1.VecSector == 9)||(svgen1.VecSector == 10))
{
EPwm11Regs.CMPB.bit.CMPB = usCmpValD; //phase A double switches is sector 1 & 2
EPwm11Regs.AQCTLA.bit.CBU = AQ_SET;
EPwm11Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm11Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm11Regs.AQCTLB.bit.CBD = AQ_SET;
}
else if ((svgen1.VecSector == 5)||(svgen1.VecSector == 6)||(svgen1.VecSector == 11)||(svgen1.VecSector == 12))
{
EPwm9Regs.CMPB.bit.CMPB = usCmpValD; //phase C double switches is sector 1 & 2
EPwm9Regs.AQCTLA.bit.CBU = AQ_SET;
EPwm9Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm9Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm9Regs.AQCTLB.bit.CBD = AQ_SET;
}
//###########################################################################
//
// FILE: control_cpu01.c
//
// TITLE: Inverter Control (SVPWM)
//
//!
//!
//!
//###########################################################################
//
// Included Files
#define MATH_TYPE FLOAT_MATH //IQ_MATH
#include "IQmathLib.h"
#include <math.h>
#include "F28x_Project.h"
#include "settings.h"
#include "Solar_F.h"
//#include "Solar_IQ.h"
// Create an instance of DATALOG Module
//DLOG_4CH_F dlog_4ch1;
// Create an instance of PLL Module
SPLL_3ph_SRF_F spll1;
//SPLL_3ph_SRF_IQ spll1;
SPLL_1ph_SOGI_F spll2;
// Create an instance of ABCtoDQ module
ABC_DQ0_POS_F abc_dq0_pos1;
iCLARKE_F iclark;
// Function Prototypes
void InitEPwm(void);
void ConfigureADC(void);
__interrupt void epwm1_isr(void);
__interrupt void adca1_isr(void);
Uint16 usRunState;
Uint16 usFaultFlag;
Uint16 usResumePWM;
Uint16 usPwmPeriod;
Uint16 EPwm1_DB;
Uint16 EPwm2_DB;
Uint16 EPwm3_DB;
Uint16 usPhase;
Uint16 usPwm2Phase;
Uint16 usPwm3Phase;
Uint16 EPwm1_CMP;
Uint16 EPwm2_CMP;
Uint16 EPwm3_CMP;
float32 fDutyCycle;
float32 fDutyCycle2;
float32 fDutyCycle3;
float32 fTdb;
float32 fTdb2;
float32 fTdb3;
Uint16 TestPwm;
float32 fUma;
float32 fUmb;
float32 fUmc;
float32 fUmz;
float32 fUmax;
float32 fUmin;
float32 fUmaxAbs;
float32 fUminAbs;
float32 fUmodA;
float32 fUmodB;
float32 fUmodC;
float32 fUmodD;
float32 fUmodAlpha;
float32 fUmodBeta;
Uint16 usCmpValA;
Uint16 usCmpValB;
Uint16 usCmpValC;
Uint16 usCmpValD;
//Uint16 usCmpVal1;
//Uint16 usCmpVal2;
//Uint16 usCmpVal3;
float32 fMI240;
// ADC values
//float32 fVa;
//float32 fVb;
//float32 fVc;
float32 fVab;
float32 fVbc;
float32 fVca;
float32 fVabAbs;
float32 fVbcAbs;
float32 fVcaAbs;
float32 fVout;
float32 fVoutFlt;
float32 fIdc;
float32 fIindA;
float32 fIindB;
float32 fIindC;
float32 fIdcFlt;
float32 fWTLpfIind;
float32 fIindAFlt;
float32 fIindBFlt;
float32 fIindCFlt;
float32 fIerrA;
float32 fIerrB;
float32 fIerrC;
float32 fCurrentFaultDc;
float32 fCurrentFaultA;
float32 fCurrentFaultB;
float32 fCurrentFaultC;
float32 fOver_Current;
float32 fOver_Voltage;
float32 fVoutFault;
float32 fIindFlt;
float32 fWTLpfIind;
float32 fIrefMag;
float32 fIrefLimit;
float32 fIset;
float32 fSlope;
float32 fVdc;
float32 fVdcPeak;
float32 fVdcPeakNom;
float32 fVdcRef;
float32 fVin;
float32 fVinFlt;
float32 fVerr;
float32 fKp2;
float32 fKi2;
float32 fInt2;
float32 fVoltCtrl;
float32 fKp;
float32 fKi;
float32 fCurrentRef;
float32 fIerrA;
float32 fIerrB;
float32 fIerrC;
float32 fIntA;
float32 fIntB;
float32 fIntC;
float32 fCurrCtrlA;
float32 fCurrCtrlB;
float32 fCurrCtrlC;
float32 fScale1;
float32 fScale2;
float32 fScale3;
float32 fScale4;
float32 fOffset1;
float32 fOffset2;
float32 fOffset3;
float32 fOffset4;
float32 fSineA;
float32 fSineB;
float32 fSineC;
float32 fSineAB;
float32 fSineBC;
float32 fSineCA;
float32 fTheta;
float32 fThetaA;
float32 fThetaB;
float32 fThetaC;
float32 fThetaAB;
float32 fThetaBC;
float32 fThetaCA;
float32 fPhaseComp;
float32 fThetaModA;
float32 fThetaModB;
//float32 fNormalize;
//float32 fDBCompThres;
//float32 fDBCompCoeff;
//float32 fDBCompA;
//float32 fDBCompB;
//float32 fDBCompC;
//float32 fVmagSq;
//float32 fVmag;
//float32 fVmagFlt;
//float32 fVmagFltWt;
// Variables for viewing signals in CCS graph
#define RESULTS_BUFFER_SIZE 128
int16 Adc1[RESULTS_BUFFER_SIZE];
int16 Adc2[RESULTS_BUFFER_SIZE];
int16 Adc3[RESULTS_BUFFER_SIZE];
int16 Adc4[RESULTS_BUFFER_SIZE];
//int16 Adc5[RESULTS_BUFFER_SIZE];
//int16 Adc6[RESULTS_BUFFER_SIZE];
//int16 Adc7[RESULTS_BUFFER_SIZE];
//int16 Adc8[RESULTS_BUFFER_SIZE];
Uint16 resultsIndex;
Uint16 saveIndex;
volatile Uint16 bufferFull;
Uint16 usStartSaveData;
Uint16 samplePace;
// ****************************************************************************
// Variables for MACROS
// ****************************************************************************
float32 T = 1.0/ISR_FREQUENCY; // Sampling period (sec), see parameter.h
_iq VdTesting = _IQ(0.866), // Vd reference (pu)
VqTesting = _IQ(0.0), // Vq reference (pu)
IdRef = _IQ(0.0), // Id reference (pu)
IqRef = _IQ(0.0), // Iq reference (pu)
SpeedRef = _IQ(1.0), // For Closed Loop tests
lsw1Speed = _IQ(0.02); // initial force rotation speed in search of QEP index pulse
// Instance a few transform objects (ICLARKE is added into SVGEN module)
//CLARKE clarke1 = CLARKE_DEFAULTS;
//PARK park1 = PARK_DEFAULTS;
IPARK ipark1 = IPARK_DEFAULTS;
//PHASEVOLTAGE volt1 = PHASEVOLTAGE_DEFAULTS;
// Instance a Space Vector PWM modulator. This modulator generates a, b and c
// phases based on the d and q stationery reference frame inputs
//SVGENDPWM_240 svgen1 = SVGENDPWM_240_DEFAULTS;
//SVGEN svgen1 = SVGEN_DEFAULTS;
//SVGEN_DPWM1 svgen1 = SVGEN_DPWM1_DEFAULTS;
SVGEN_ACCPWM svgen1 = SVGEN_ACCPWM_DEFAULTS;
//SVGEN_ASCPWM svgen1 = SVGEN_ASCPWM_DEFAULTS;
// Instance a ramp controller to smoothly ramp the frequency
RMPCNTL rc1 = RMPCNTL_DEFAULTS;
// Instance a ramp(sawtooth) generator to simulate an Anglele
RAMPGEN rg1 = RAMPGEN_DEFAULTS;
CLARKE clarke1 = CLARKE_DEFAULTS;
PARK park1 = PARK_DEFAULTS;
// ****************************************************************************
// Variables for Datalog module
// ****************************************************************************
//float DBUFF_4CH1[100],
// DBUFF_4CH2[100],
// DBUFF_4CH3[50],
// DBUFF_4CH4[50],
// DlogCh1,
// DlogCh2,
// DlogCh3,
// DlogCh4;
void Shutdown(void);
//
// Main
//
void main(void)
{
InitSysCtrl();
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM11 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM12 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM9 = 1;
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
InitEPwm11Gpio();
InitEPwm12Gpio();
InitEPwm9Gpio();
// EALLOW;
// GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0; // GPIO
// GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0; // GPIO
// GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // output
// GpioCtrlRegs.GPADIR.bit.GPIO6 = 1; // output
// EDIS;
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT = &epwm1_isr;
PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
EDIS; // This is needed to disable write to EALLOW protected registers
// Configure the ADC and power it up
// Setup the ADC for ePWM triggered conversions
// ************ SHOULD BE DONE BEFORE PWM CONFIG **************
ConfigureADC();
//
// Step 4. Initialize the Device Peripherals:
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0;
EDIS;
InitEPwm();
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =1;
EDIS;
//
// Step 5. User specific code
// Initialize variables
usRunState = 0;
usResumePWM = 0;
fOver_Current = 40.0;
fOver_Voltage = 800.0;
fMI240 = 1.0;
// fVmagFltWt = TWO_PI * 1.0 * SAMPLING_PERIOD; // 1 Hz LPF
fPhaseComp = 0.0;
fVdcPeakNom = 2.2;
fVinFlt = 50;//400.0;
fWTLpfIind = TWO_PI * 20000.0 * SAMPLING_PERIOD; // 20 kHz LPF
fKp = 0.02;
fKi = 20.0;
fKp2 = 0.2;
fKi2 = 30.0;
fOffset1 = 3.6;
// fScale1 = 312.0;
// fScale2 = 533.3;
// fScale3 = 533.3;
// fScale4 = 1.0;
// fOffset1 = -35.0;
// fOffset2 = -814.0;
// fOffset3 = -818.0;
// fOffset4 = -1;
rg1.StepAngleMax = _IQ(GRID_FREQ * SAMPLING_PERIOD);
// SPLL_3ph_SRF_F_init(GRID_FREQ, SAMPLING_PERIOD, &spll1);
// Kp = 166.6;
// Ki = 27755.55;
// T = 1/10e3;
// B0 = (2*Kp + Ki*T)/2
// B1 = -(2*Kp - Ki*T)/2
SPLL_1ph_SOGI_F_init(GRID_FREQ,((float)(SAMPLING_PERIOD)), &spll2);
SPLL_1ph_SOGI_F_coeff_update(((float)(SAMPLING_PERIOD)), (float)(TWO_PI*GRID_FREQ), &spll2);
// fNormalize = 0.1;
// ****************************************************
// Initialize DATALOG module
// ****************************************************
// DLOG_4CH_F_init(&dlog_4ch1);
// dlog_4ch1.input_ptr1 = &DlogCh1; //data value
// dlog_4ch1.input_ptr2 = &DlogCh2;
// dlog_4ch1.input_ptr3 = &DlogCh3;
// dlog_4ch1.input_ptr4 = &DlogCh4;
// dlog_4ch1.output_ptr1 = &DBUFF_4CH1[0];
// dlog_4ch1.output_ptr2 = &DBUFF_4CH2[0];
// dlog_4ch1.output_ptr3 = &DBUFF_4CH3[0];
// dlog_4ch1.output_ptr4 = &DBUFF_4CH4[0];
// dlog_4ch1.size = 200;
// dlog_4ch1.pre_scalar = 5;
// dlog_4ch1.trig_value = 0.01;
// dlog_4ch1.status = 2;
for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
{
Adc1[resultsIndex] = 0;
Adc2[resultsIndex] = 0;
Adc3[resultsIndex] = 0;
Adc4[resultsIndex] = 0;
}
resultsIndex = 0;
saveIndex = 0;
bufferFull = 0;
samplePace = 16; // Rounding( F_sample / F_fundamental / BufferSize )
usStartSaveData = 0;
//
// Enable CPU INT3 which is connected to EPWM1-3 INT:
//
// IER |= M_INT3;
IER |= M_INT1; // for ADC isr
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
//
// Enable PIE interrupt
//
// PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // PWM
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // ADC isr
// conv_duty();
for(;;)
{
asm (" NOP");
}
}
//
// epwm1_isr - EPWM1 ISR
//
__interrupt void epwm1_isr(void)
{
// GpioDataRegs.GPASET.bit.GPIO8 = 1; // Pin 57
asm (" NOP"); asm (" NOP");
asm (" NOP"); asm (" NOP");
asm (" NOP"); asm (" NOP");
asm (" NOP"); asm (" NOP");
asm (" NOP"); asm (" NOP");
// EPwm2Regs.TBPHS.bit.TBPHS = usPwm2Phase;
// EPwm3Regs.TBPHS.bit.TBPHS = usPwm3Phase;
// EPwm1Regs.TBPRD = usPwmPeriod;
// EPwm2Regs.TBPRD = usPwmPeriod;
// EPwm3Regs.TBPRD = usPwmPeriod;
// GpioDataRegs.GPACLEAR.bit.GPIO8 = 1;
// Clear INT flag for this timer
EPwm1Regs.ETCLR.bit.INT = 1;
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
//
// adca1_isr - Read ADC Buffer in ISR
//
__interrupt void adca1_isr(void)
{
// GpioDataRegs.GPASET.bit.GPIO6 = 1;
//**********************************************
// Get ADC Results
//**********************************************
// 1000V => 3.0V
// Sensor HLSR 50-SM/SP33, datasheet sensitivity 9.2mV/A (108.7 A/V)
// Current signals, sampled bias 1.63V,
/*
not to be used here
fIdc = ((float32)AdcaResultRegs.ADCRESULT1 * 0.0007326007326 - 1.63) * 108.7;
fIindC = ((float32)AdcaResultRegs.ADCRESULT2 * 0.0007326007326 - 1.63) * 108.7;
fIindB = ((float32)AdcaResultRegs.ADCRESULT3 * 0.0007326007326 - 1.63) * 108.7;
fIindA = ((float32)AdcaResultRegs.ADCRESULT4 * 0.0007326007326 - 1.63) * 108.7;*/
// fVout = ((float32)AdcaResultRegs.ADCRESULT0 * 0.0007326007326) * 360.0 + fOffset2;
// fIdc = ((float32)AdcaResultRegs.ADCRESULT1 * 0.0007326007326 - 1.65) * 91.5 + fOffset1;
// fIindC = ((float32)AdcaResultRegs.ADCRESULT2 * 0.0007326007326 - 1.65) * 91.5 + fOffset1;
// fIindB = ((float32)AdcaResultRegs.ADCRESULT3 * 0.0007326007326 - 1.65) * 91.5 + fOffset1;
// fIindA = ((float32)AdcaResultRegs.ADCRESULT4 * 0.0007326007326 - 1.65) * 91.5 + fOffset1;
fIdc = 0;
fIindC = 0;
fIindB = 0;
fIindA = 0;
EMATH_OneOrderLpf(fVout, fVoutFlt, fWTLpfIind);
EMATH_OneOrderLpf(fIindA, fIindAFlt, fWTLpfIind);
EMATH_OneOrderLpf(fIindB, fIindBFlt, fWTLpfIind);
EMATH_OneOrderLpf(fIindC, fIindCFlt, fWTLpfIind);
// fVab = fScale2 * (((float32)AdcaResultRegs.ADCRESULT0) * 0.0007326007326) + fOffset2;
// fVa = fScale2 * (((float32)AdcaResultRegs.ADCRESULT6) * 0.0007326007326) + fOffset2;
// fVb = fScale3 * (((float32)AdcaResultRegs.ADCRESULT7) * 0.0007326007326) + fOffset3;
// fVc = fScale4 * (((float32)AdcaResultRegs.ADCRESULT3) * 0.0007326007326 + fOffset4);
// fVc = 0.0 - fVa - fVb;
// EMATH_OneOrderLpf(fVin, fVinFlt, fVmagFltWt);
#if 0
spll2.u[0] = fVab * fNormalize; // fNormalize = 0.1 gives good result
SPLL_1ph_SOGI_F_MACRO(spll2);
EMATH_OneOrderLpf(-spll2.u_D[0]*10.0, fVmagFlt, fVmagFltWt);
UP_DOWN_LIMIT(fVmagFlt, 900.0, 1.0);
fThetaAB = spll2.theta[1] + (fPhaseComp * TWO_PI);
if( fThetaAB > TWO_PI ) { fThetaAB = fThetaAB - TWO_PI; }
fThetaBC = fThetaAB + FOUR_PI_DIV3;
if( fThetaBC > TWO_PI ) { fThetaBC = fThetaBC - TWO_PI; }
fThetaCA = fThetaAB + TWO_PI_DIV3;
if( fThetaCA > TWO_PI ) { fThetaCA = fThetaCA - TWO_PI; }
fSineAB = spll2.__relaxed_sin * SQRT_THREE;
fSineBC = sin(fThetaBC) * SQRT_THREE;
fSineCA = sin(fThetaCA) * SQRT_THREE;
fSineA = (fSineAB - fSineCA)*0.333333;
fSineB = (fSineBC - fSineAB)*0.333333;
fSineC = (fSineCA - fSineBC)*0.333333;
fUmodAlpha = fSineA;
fUmodBeta = (fSineA + 2.0 * fSineB) * 0.57735026918963;
fVabAbs = ABS(fSineAB);
fVbcAbs = ABS(fSineBC);
fVcaAbs = ABS(fSineCA);
fVdc = MAX_THREE(fVabAbs, fVbcAbs, fVcaAbs);
UP_DOWN_LIMIT(fVdc, 1.733, 0.1);
fMI240 = 1.7320508 / fVdc * VdTesting;
UP_DOWN_LIMIT(fMI240, 1.154, 0.5);
#endif
// // if( spll2.__relaxed_sin > 0 )
// if( fSineA > 0 )
// {
// GpioDataRegs.GPASET.bit.GPIO4 = 1;
// }
// else
// {
// GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;
// }
//
// if( fSineC > 0 )
// {
// GpioDataRegs.GPASET.bit.GPIO6 = 1;
// }
// else
// {
// GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
// }
//If measuring va,vb and vc, use this part of code
// ------------------------------------------------------------------------------
// Measure phase currents, subtract the offset and normalize from (-0.5,+0.5) to (-1,+1).
// Connect inputs of the CLARKE module and call the clarke transformation macro
// ------------------------------------------------------------------------------
// clarke1.As = fVa; // Phase A Voltage
// clarke1.Bs = fVb; // Phase B Voltage
// clarke1.Cs = fVc; // Phase C Voltage
// CLARKE_MACRO(clarke1)
// fVmagSq = (clarke1.Alpha)*(clarke1.Alpha) + (clarke1.Beta)*(clarke1.Beta);
// fVmag = sqrt(fVmagSq); // * 1.732050807;
// EMATH_OneOrderLpf(fVmag, fVmagFlt, fVmagFltWt);
#if 0
abc_dq0_pos1.a = fVa;
abc_dq0_pos1.b = fVb;
abc_dq0_pos1.c = fVc;
abc_dq0_pos1.sin = -sin((spll1.theta[1]));
abc_dq0_pos1.cos = -cos((spll1.theta[1]));
ABC_DQ0_POS_F_MACRO(abc_dq0_pos1);
//spll1.v_q[0] = (abc_dq0_pos1.d) * fNormalize; // / abc_dq0_pos1.d);
spll1.v_q[0] = (abc_dq0_pos1.d) / fVmagFlt * fNormalize ;
SPLL_3ph_SRF_F_MACRO(spll1); // takes less time
#endif
// ------------------------------------------------------------------------------
// Connect inputs of the RMP module and call the ramp control macro
// ------------------------------------------------------------------------------
rc1.TargetValue = SpeedRef;
RC_MACRO(rc1)
// ------------------------------------------------------------------------------
// Connect inputs of the RAMP GEN module and call the ramp generator macro
// ------------------------------------------------------------------------------
rg1.Freq = rc1.SetpointValue;
RG_MACRO(rg1)
// Calculate Duty for Boost converter
fThetaA = rg1.Out * TWO_PI;
fThetaB = fThetaA + FOUR_PI_DIV3;
if( fThetaB > TWO_PI ) { fThetaB = fThetaB - TWO_PI; }
fThetaC = fThetaA + TWO_PI_DIV3;
if( fThetaC > TWO_PI ) { fThetaC = fThetaC - TWO_PI; }
fSineA = sin(fThetaA);
fSineB = sin(fThetaB);
fSineC = sin(fThetaC);
fSineAB = (fSineA - fSineB);
fSineBC = (fSineB - fSineC);
fSineCA = (fSineC - fSineA);
fVabAbs = ABS(fSineAB);
fVbcAbs = ABS(fSineBC);
fVcaAbs = ABS(fSineCA);
fVdc = MAX_THREE(fVabAbs, fVbcAbs, fVcaAbs);
UP_DOWN_LIMIT(fVdc, 1.733, 0.1);
fMI240 = 1.7320508 / fVdc;
UP_DOWN_LIMIT(fMI240, 1.154, 0.5);
// fThetaModA = fThetaA + fPhaseComp * TWO_PI;
// if( fThetaModA > TWO_PI ) { fThetaModA = fThetaModA - TWO_PI; }
// fThetaModB = fThetaModA + FOUR_PI_DIV3;
// if( fThetaModB > TWO_PI ) { fThetaModB = fThetaModB - TWO_PI; }
// fUmodAlpha = sin(fThetaModA);
// fUmodBeta = (sin(fThetaModA) + 2.0 * sin(fThetaModB)) * 0.57735026918963;
fUmodAlpha = fSineA;
fUmodBeta = (fSineA + 2.0 * fSineB) * 0.57735026918963;
#if 0
// ------------------------------------------------------------------------------
// Connect inputs of the PARK module and call the park trans. macro
// ------------------------------------------------------------------------------
park1.Alpha = clarke1.Alpha;
park1.Beta = clarke1.Beta;
// park1.Angle = rg1.Out;
park1.Angle = spll1.theta[1];
park1.Sine = __sinpuf32(park1.Angle);
park1.Cosine = __cospuf32(park1.Angle);
PARK_MACRO(park1)
spll1.v_q[0] = park1.Ds * fNormalize;
SPLL_3ph_SRF_F_MACRO(spll1);
// ------------------------------------------------------------------------------
// Connect inputs of the INV_PARK module and call the inverse park trans. macro
// There are two option for trigonometric functions:
// IQ sin/cos look-up table provides 512 discrete sin and cos points in Q30 format
// IQsin/cos PU functions interpolate the data in the lookup table yielding higher resolution.
// ------------------------------------------------------------------------------
ipark1.Ds = park1.Ds;//VdTesting;
ipark1.Qs = park1.Qs;//VqTesting;
// ipark1.Sine = __sinpuf32(rg1.Out);
// ipark1.Cosine = __cospuf32(rg1.Out);
// ipark1.Sine=_IQsinPU(rg1.Out);
// ipark1.Cosine=_IQcosPU(rg1.Out);
ipark1.Sine=__sinpuf32(rg1.Out);
ipark1.Cosine=__cospuf32(rg1.Out);
IPARK_MACRO(ipark1)
#endif
// //For open loop testing
// ipark1.Ds = VdTesting;
// ipark1.Qs = VqTesting;
//
// park1.Angle = rg1.Out;
// park1.Sine = __sinpuf32(park1.Angle);
// park1.Cosine = __cospuf32(park1.Angle);
//
// ipark1.Sine=park1.Sine;
// ipark1.Cosine=park1.Cosine;
// IPARK_MACRO(ipark1)
// ------------------------------------------------------------------------------
// Connect inputs of the SVGEN module and call the space-vector gen. macro
// ------------------------------------------------------------------------------
// svgen1.Ualpha = ipark1.Alpha;
// svgen1.Ubeta = ipark1.Beta;
/* svgen1.Ualpha = fUmodAlpha * VdTesting;
svgen1.Ubeta = fUmodBeta * VdTesting;
*/
svgen1.Vref = VdTesting;
svgen1.omegat = rg1.Out*TWO_PI;
// svgen1.Ualpha = fUmodAlpha * fMI240;
// svgen1.Ubeta = fUmodBeta * fMI240;
/* // DPWM 1 (clamp at peak)
fUma = ipark1.Alpha;
fUmb = 0.5*( 1.732050807 * ipark1.Beta - ipark1.Alpha);
fUmc = 0.5*(-1.732050807 * ipark1.Beta - ipark1.Alpha);
fUmax = MAX_THREE(fUma, fUmb, fUmc);
fUmin = MIN_THREE(fUma, fUmb, fUmc);
fUmaxAbs = ABS(fUmax);
fUminAbs = ABS(fUmin);
if( fUmaxAbs > fUminAbs )
{
fUmz = 1.0 - fUmax;
}
else
{
fUmz = -1.0 - fUmin;
}
fUmodA = fUma + fUmz;
fUmodB = fUmb + fUmz;
fUmodC = fUmc + fUmz;
*/
//240CPWM
/*
SVGENDPWM_240_MACRO(svgen1)
fUmodA = -svgen1.Ta;
fUmodB = -svgen1.Tb;
fUmodC = -svgen1.Tc;
*/
// SVGENASCPWM_MACRO(svgen1)
SVGENACCPWM_MACRO(svgen1)
// SVGENDQ_MACRO(svgen1)
// SVGENDPWM1_MACRO(svgen1)
fUmodA = svgen1.Ta;
fUmodB = svgen1.Tb;
fUmodC = svgen1.Tc;
fUmodD = svgen1.Td;
// if( fVaAbs > fDBCompThres )
// {
// fDBCompA = fDBCompCoeff;
// }
//
// if( fVbAbs > fDBCompThres )
// {
// fDBCompB = fDBCompCoeff;
// }
//
// if( fVcAbs > fDBCompThres )
// {
// fDBCompC = fDBCompCoeff;
// }
//
// fUmodA = fUmodA * fDBCompA;
// fUmodB = fUmodB * fDBCompB;
// fUmodC = fUmodC * fDBCompC;
usCmpValA = (INV_PWM_HALF_TBPRD * fUmodA) + INV_PWM_HALF_TBPRD;
usCmpValB = (INV_PWM_HALF_TBPRD * fUmodB) + INV_PWM_HALF_TBPRD;
usCmpValC = (INV_PWM_HALF_TBPRD * fUmodC) + INV_PWM_HALF_TBPRD;
usCmpValD = (INV_PWM_HALF_TBPRD * fUmodD) + INV_PWM_HALF_TBPRD;
UP_DOWN_LIMIT(usCmpValA, INV_PWM_TBPRD, 0);
UP_DOWN_LIMIT(usCmpValB, INV_PWM_TBPRD, 0);
UP_DOWN_LIMIT(usCmpValC, INV_PWM_TBPRD, 0);
UP_DOWN_LIMIT(usCmpValD, INV_PWM_TBPRD, 0);
EPwm11Regs.CMPA.bit.CMPA = usCmpValA; //phase A
EPwm12Regs.CMPA.bit.CMPA = usCmpValB; //phase B
EPwm9Regs.CMPA.bit.CMPA = usCmpValC; //phase C
if ((svgen1.VecSector == 1)||(svgen1.VecSector == 2)||(svgen1.VecSector == 7)||(svgen1.VecSector == 8))
{
EPwm12Regs.CMPB.bit.CMPB = usCmpValD; //phase B double switches is sector 1 & 2
EPwm12Regs.AQCTLA.bit.CBU = AQ_SET;
EPwm12Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm12Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm12Regs.AQCTLB.bit.CBD = AQ_SET;
}
else if ((svgen1.VecSector == 3)||(svgen1.VecSector == 4)||(svgen1.VecSector == 9)||(svgen1.VecSector == 10))
{
EPwm11Regs.CMPB.bit.CMPB = usCmpValD; //phase B double switches is sector 1 & 2
EPwm11Regs.AQCTLA.bit.CBU = AQ_SET;
EPwm11Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm11Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm11Regs.AQCTLB.bit.CBD = AQ_SET;
}
else if ((svgen1.VecSector == 5)||(svgen1.VecSector == 6)||(svgen1.VecSector == 11)||(svgen1.VecSector == 12))
{
EPwm9Regs.CMPB.bit.CMPB = usCmpValD; //phase B double switches is sector 1 & 2
EPwm9Regs.AQCTLA.bit.CBU = AQ_SET;
EPwm9Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm9Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm9Regs.AQCTLB.bit.CBD = AQ_SET;
}
//
// usCmpVal1 = (Uint16)(fDutyCycle * (float32)CONTROL_TBPRD); // Duty for Top switch
//// usCmpVal2 = (Uint16)(fDutyCycle * (float32)CONTROL_TBPRD);
//// usCmpVal3 = (Uint16)(fDutyCycle * (float32)CONTROL_TBPRD);
//
// UP_DOWN_LIMIT(usCmpVal1, CONTROL_TBPRD, 5);
//
// EPwm1Regs.CMPA.bit.CMPA = usCmpVal1;
// EPwm2Regs.CMPA.bit.CMPA = usCmpVal1;
// EPwm3Regs.CMPA.bit.CMPA = usCmpVal1;
if( (ACTIVE == usRunState) && (NORMAL == usFaultFlag) )
{
if( usResumePWM )
{
// only need to change here for enabling/disabling phases
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1;
EDIS;
usResumePWM = 0;
}
if( (fOver_Current <= ABS(fIdc) ) ||
(fOver_Current <= ABS(fIindA)) ||
(fOver_Current <= ABS(fIindB)) ||
(fOver_Current <= ABS(fIindC)) )
{
Shutdown();
fCurrentFaultDc = fIdc;
fCurrentFaultA = fIindA;
fCurrentFaultB = fIindB;
fCurrentFaultC = fIindC;
usFaultFlag = OVER_CURRENT;
}
if( fOver_Voltage <= ABS(fVout) )
{
Shutdown();
fVoutFault = fVout;
usFaultFlag = OVER_VOLTAGE;
}
// open loop
fVdcRef = fVdc * SQRT_THREE_RECIP * fVdcPeak;
// UP_DOWN_LIMIT(fVdcRef, 1000.0, 50.0);
fDutyCycle = fVinFlt / fVdcRef; // for top switch
UP_DOWN_LIMIT(fDutyCycle, 0.8, 0.3);
fDutyCycle2 = fDutyCycle;
fDutyCycle3 = fDutyCycle;
// // Voltage Control
// fVdcRef = fVdc * SQRT_THREE_RECIP * fVdcPeak;
//// fVdcRef = fVdcPeak;
// UP_DOWN_LIMIT(fVdcRef, 800.0, 50.0);
//
// fVerr = fVdcRef - fVoutFlt;
// fInt2 += fVerr * fKi2 * CONTROL_PERIOD;
// UP_DOWN_LIMIT(fInt2, 0.8, -0.8);
// fVoltCtrl = fKp2 * fVerr + fInt2;
// UP_DOWN_LIMIT(fVoltCtrl, 30.0, 0);
//
//
// // Current Control
// fCurrentRef = fVoltCtrl;
//
// fIerrA = fCurrentRef - fIindAFlt;
// fIntA += fIerrA * fKi * CONTROL_PERIOD;
// UP_DOWN_LIMIT(fIntA, 0.8, -0.8);
// fCurrCtrlA = fKp * fIerrA + fIntA;
// UP_DOWN_LIMIT(fCurrCtrlA, 0.8, 0.2);
//
// fIerrB = fCurrentRef - fIindBFlt;
// fIntB += fIerrB * fKi * CONTROL_PERIOD;
// UP_DOWN_LIMIT(fIntB, 0.8, -0.8);
// fCurrCtrlB = fKp * fIerrB + fIntB;
// UP_DOWN_LIMIT(fCurrCtrlB, 0.8, 0.2);
//
// fIerrC = fCurrentRef - fIindCFlt;
// fIntC += fIerrC * fKi * CONTROL_PERIOD;
// UP_DOWN_LIMIT(fIntC, 0.8, -0.8);
// fCurrCtrlC = fKp * fIerrC + fIntC;
// UP_DOWN_LIMIT(fCurrCtrlC, 0.8, 0.2);
//
//
// fDutyCycle = 1.0 - fCurrCtrlA; // fDutyCycle is duty for top switch (Q1), fD0 is for Q2
// fDutyCycle2 = 1.0 - fCurrCtrlB;
// fDutyCycle3 = 1.0 - fCurrCtrlC;
EPwm1_CMP = (Uint16)(fDutyCycle * (0.5 * (float32)CONTROL_TBPRD));
EPwm2_CMP = (Uint16)(fDutyCycle2 * (0.5 * (float32)CONTROL_TBPRD));
EPwm3_CMP = (Uint16)(fDutyCycle3 * (0.5 * (float32)CONTROL_TBPRD));
EPwm1Regs.CMPA.bit.CMPA = EPwm1_CMP; // Phase A Main
EPwm2Regs.CMPA.bit.CMPA = EPwm2_CMP; // Phase B Main
EPwm3Regs.CMPA.bit.CMPA = EPwm3_CMP; // Phase C Main
}
else
{
Shutdown();
}
// EPwm1_DB = (Uint16)(fTdb * 0.1);
// EPwm11Regs.DBFED.bit.DBFED = EPwm1_DB;
// EPwm12Regs.DBFED.bit.DBFED = EPwm1_DB;
// EPwm9Regs.DBFED.bit.DBFED = EPwm1_DB;
// // Connect inputs of the DATALOG module
// DlogCh1 = svgen1.Ta;
// DlogCh2 = svgen1.Tb;
// DlogCh3 = svgen1.Tc;
// DlogCh4 = DlogCh2 - DlogCh3;
// // ------------------------------------------------------------------------------
// // Call the DATALOG update function.
// // ------------------------------------------------------------------------------
// DLOG_4CH_F_FUNC(&dlog_4ch1);
//**********************************************
// View data in CCS graph
//**********************************************
if( usStartSaveData == 1 )
{
saveIndex++;
if( (bufferFull == 0) && (samplePace <= saveIndex) )
{
// Adc1[resultsIndex] = fVinFlt * 1.0;
// Adc2[resultsIndex] = fVdcRef * 1.0;
// Adc3[resultsIndex] = fUmodA * 1000.0;
// Adc4[resultsIndex] = fDutyCycle * 1000.0;
/* Adc1[resultsIndex] = fVabAbs * 1000.0;
Adc2[resultsIndex] = fVbcAbs * 1000.0;
Adc3[resultsIndex] = fVdc * 10.0;
Adc4[resultsIndex] = fVdcRef * 10.0;*/
Adc1[resultsIndex] = svgen1.Ta * 100.0;
Adc2[resultsIndex] = svgen1.Tb * 100.0;
Adc3[resultsIndex] = svgen1.Tc * 100.0;
Adc4[resultsIndex] = svgen1.Td * 100.0;
resultsIndex++;
saveIndex = 0;
}
if(RESULTS_BUFFER_SIZE <= resultsIndex)
{
resultsIndex = 0;
bufferFull = 1;
saveIndex = 0;
usStartSaveData = 0;
}
}
// GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//
// InitEPwm - Initialize EPWMx configuration
//
void InitEPwm()
{
fTdb = 250.0; // ns
fTdb2 = 250.0; // ns
fTdb3 = 250.0; // ns
EPwm1_DB = (Uint16)(fTdb * 0.1);
EPwm2_DB = (Uint16)(fTdb2 * 0.1);
EPwm3_DB = (Uint16)(fTdb3 * 0.1);
fDutyCycle = 0.3;
usPhase = (Uint16)(0.666666 * 0.5 * (float32)CONTROL_TBPRD);
usPwm2Phase = usPhase; // Phase B Main
usPwm3Phase = usPhase; // Phase C Main
EPwm1Regs.TBPRD = (Uint16)(0.5 * (float32)CONTROL_TBPRD); // Set timer period
EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync Output Select: CTR = zero
// EPwm1Regs.rsvd2[0] = 0x0002; // EPWMxSYNCOUT Source Enable Register
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// EPwm1Regs.CMPA.bit.CMPA = (Uint16)(fDutyCycle * (float32)CONTROL_TBPRD);
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm1Regs.AQCTLB.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQSFRC.bit.RLDCSF = 3; // Load immediately
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm1Regs.DBRED.bit.DBRED = EPwm1_DB;
EPwm1Regs.DBFED.bit.DBFED = EPwm1_DB;
EPwm2Regs.TBPRD = (Uint16)(0.5 * (float32)CONTROL_TBPRD); // Set timer period
EPwm2Regs.TBPHS.bit.TBPHS = usPwm2Phase; // Phase is 0
EPwm2Regs.TBCTR = 0x0000; // Clear counter
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Disable phase loading
EPwm2Regs.TBCTL.bit.PHSDIR = TB_DOWN; // Count down after the synchronization event
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
// EPwm2Regs.rsvd2[0] = 0x0002; // EPWMxSYNCOUT Source Enable Register
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// EPwm2Regs.CMPA.bit.CMPA = (Uint16)(fDutyCycle * (float32)CONTROL_TBPRD);
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm2Regs.AQCTLB.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR;
EPwm2Regs.AQSFRC.bit.RLDCSF = 3; // Load immediately
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm2Regs.DBRED.bit.DBRED = EPwm2_DB;
EPwm2Regs.DBFED.bit.DBFED = EPwm2_DB;
EPwm3Regs.TBPRD = (Uint16)(0.5 * (float32)CONTROL_TBPRD); // Set timer period
EPwm3Regs.TBPHS.bit.TBPHS = usPwm3Phase; // Phase is 0
EPwm3Regs.TBCTR = 0x0000; // Clear counter
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Disable phase loading
EPwm3Regs.TBCTL.bit.PHSDIR = TB_UP; // Count down/up (0/1) after the synchronization event
EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
// EPwm3Regs.rsvd2[0] = 0x0002; // EPWMxSYNCOUT Source Enable Register
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// EPwm3Regs.CMPA.bit.CMPA = (Uint16)(fDutyCycle * (float32)CONTROL_TBPRD);
EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm3Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm3Regs.AQCTLB.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm3Regs.AQCTLB.bit.CAD = AQ_CLEAR;
EPwm3Regs.AQSFRC.bit.RLDCSF = 3; // Load immediately
EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm3Regs.DBRED.bit.DBRED = EPwm3_DB;
EPwm3Regs.DBFED.bit.DBFED = EPwm3_DB;
// Interrupt setting
// EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
// EPwm1Regs.ETPS.bit.INTPRD = ET_2ND; // Generate INT on 1st event
// EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
// ADC SOC
EALLOW;
EPwm1Regs.ETSEL.bit.SOCASEL = 1; // Select SOC on Zero
EPwm1Regs.ETSEL.bit.SOCAEN = 1; //enable SOCA
EPwm1Regs.ETPS.bit.SOCAPRD = ET_2ND; // Generate pulse on ___ event
EDIS;
// EPwm1Regs.TBPRD = CONTROL_TBPRD; // Set timer period
// EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
// EPwm1Regs.TBCTR = 0x0000; // Clear counter
// EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
// EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
// EPwm1Regs.TBCTL.bit.SYNCOSEL = 1; // Sync Output Select: CTR = zero
// EPwm1Regs.rsvd2[0] = 0x0002; // EPWMxSYNCOUT Source Enable Register
// EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
// EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
// EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
// EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
// EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
// EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// // EPwm1Regs.CMPA.bit.CMPA = (Uint16)(fDutyCycle * (float32)PWM_PRD_UD);
// EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
// EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
// EPwm1Regs.AQCTLB.bit.CAU = AQ_SET; // Set PWM1A on Zero
// EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR;
// EPwm1Regs.AQSFRC.bit.RLDCSF = 3; // Load immediately
// EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
// EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
// EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
// EPwm1Regs.DBRED.bit.DBRED = EPwm1_DB;
// EPwm1Regs.DBFED.bit.DBFED = EPwm1_DB;
// PWM modules for 3-phase inverter
// EPWM 11, 12, 9
EPwm11Regs.TBPRD = INV_PWM_TBPRD; // Set timer period
EPwm11Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
EPwm11Regs.TBCTR = 0x0000; // Clear counter
EPwm11Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
EPwm11Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm11Regs.TBCTL.bit.SYNCOSEL = 1; // Sync Output Select: CTR = zero
EPwm11Regs.rsvd2[0] = 0x0002; // EPWMxSYNCOUT Source Enable Register
EPwm11Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm11Regs.TBCTL.bit.CLKDIV = TB_DIV1;
// EPwm11Regs.CMPA.bit.CMPA = (Uint16)(fDutyCycle * (float32)INV_PWM_HALF_TBPRD);
EPwm11Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm11Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm11Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
EPwm11Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
EPwm11Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm11Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm11Regs.AQCTLB.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm11Regs.AQCTLB.bit.CAD = AQ_CLEAR;
EPwm11Regs.AQSFRC.bit.RLDCSF = 3; // Load immediately
EPwm11Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm11Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm11Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm11Regs.DBRED.bit.DBRED = EPwm1_DB;
EPwm11Regs.DBFED.bit.DBFED = EPwm1_DB;
EPwm12Regs.TBPRD = INV_PWM_TBPRD; // Set timer period
EPwm12Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
EPwm12Regs.TBCTR = 0x0000; // Clear counter
EPwm12Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
EPwm12Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm12Regs.TBCTL.bit.SYNCOSEL = 1; // Sync Output Select: CTR = zero
EPwm12Regs.rsvd2[0] = 0x0002; // EPWMxSYNCOUT Source Enable Register
EPwm12Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm12Regs.TBCTL.bit.CLKDIV = TB_DIV1;
// EPwm12Regs.CMPA.bit.CMPA = (Uint16)(fDutyCycle * (float32)INV_PWM_HALF_TBPRD);
EPwm12Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm12Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm12Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
EPwm12Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
EPwm12Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm12Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm12Regs.AQCTLB.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm12Regs.AQCTLB.bit.CAD = AQ_CLEAR;
EPwm12Regs.AQSFRC.bit.RLDCSF = 3; // Load immediately
EPwm12Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm12Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm12Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm12Regs.DBRED.bit.DBRED = EPwm1_DB;
EPwm12Regs.DBFED.bit.DBFED = EPwm1_DB;
EPwm9Regs.TBPRD = INV_PWM_TBPRD; // Set timer period
EPwm9Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
EPwm9Regs.TBCTR = 0x0000; // Clear counter
EPwm9Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
EPwm9Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm9Regs.TBCTL.bit.SYNCOSEL = 1; // Sync Output Select: CTR = zero
EPwm9Regs.rsvd2[0] = 0x0002; // EPWMxSYNCOUT Source Enable Register
EPwm9Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm9Regs.TBCTL.bit.CLKDIV = TB_DIV1;
// EPwm9Regs.CMPA.bit.CMPA = (Uint16)(fDutyCycle * (float32)INV_PWM_HALF_TBPRD);
EPwm9Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm9Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm9Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
EPwm9Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
EPwm9Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm9Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm9Regs.AQCTLB.bit.CAU = AQ_SET; // Set PWM1A on Zero
EPwm9Regs.AQCTLB.bit.CAD = AQ_CLEAR;
EPwm9Regs.AQSFRC.bit.RLDCSF = 3; // Load immediately
EPwm9Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm9Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm9Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm9Regs.DBRED.bit.DBRED = EPwm1_DB;
EPwm9Regs.DBFED.bit.DBFED = EPwm1_DB;
}
//
// ConfigureADC - Write ADC configurations and power up the ADC for both
// ADC A and ADC B
//
void ConfigureADC(void)
{
Uint16 acqps;
EALLOW;
//write configurations
AdcaRegs.ADCCTL2.bit.PRESCALE = 2; //set ADCCLK divider to /2.0
AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
//Set pulse positions to late
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//power up the ADC
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
//delay for 1ms to allow ADC time to power up
DELAY_US(1000);
EDIS;
// Determine minimum acquisition window (in SYSCLKS) based on resolution
if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
{
acqps = 14; //75ns
}
else //resolution is 16-bit
{
acqps = 63; //320ns
}
//Select the channels to convert and end of conversion flag
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; //SOC0 will convert pin A0
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = ADCTRIG; //ADCTRIG9 - ePWM3, ADCSOCA, ADCTRIG5 - ePWM1, ADCSOCA
AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;
AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps;
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = ADCTRIG;
AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;
AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps;
AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = ADCTRIG;
AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;
AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps;
AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = ADCTRIG;
AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;
AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps;
AdcaRegs.ADCSOC4CTL.bit.TRIGSEL = ADCTRIG;
AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;
AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps;
AdcaRegs.ADCSOC5CTL.bit.TRIGSEL = ADCTRIG;
// AdcaRegs.ADCSOC6CTL.bit.CHSEL = 14;
// AdcaRegs.ADCSOC6CTL.bit.ACQPS = acqps;
// AdcaRegs.ADCSOC6CTL.bit.TRIGSEL = ADCTRIG;
//
// AdcaRegs.ADCSOC7CTL.bit.CHSEL = 15;
// AdcaRegs.ADCSOC7CTL.bit.ACQPS = acqps;
// AdcaRegs.ADCSOC7CTL.bit.TRIGSEL = ADCTRIG;
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 5; //end of SOCx will set INT1 flag
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
EDIS;
}
void Shutdown(void)
{
// software forced low on PWMA and PWMB
// EPwm1Regs.AQCSFRC.bit.CSFA = 1;
// EPwm1Regs.AQCSFRC.bit.CSFB = 1; // ***** THIS LINE HAS NO EFFECT ON PWMB *****
// PWM1B STAYS HIGH
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO3 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO5 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO6 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO7 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO8 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO9 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO10 = 1; // output
GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // output
EDIS;
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO5 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO8 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO9 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO10 = 1;
GpioDataRegs.GPACLEAR.bit.GPIO11 = 1;
usRunState = FAULT;
usResumePWM = 0;
fDutyCycle = 0.0;
fDutyCycle2 = 0.0;
fDutyCycle3 = 0.0;
EPwm1_CMP = 0;
EPwm2_CMP = 0;
EPwm3_CMP = 0;
fVerr = 0.0;
fInt2 = 0.0;
fVoltCtrl = 0.0;
fIerrA = 0.0;
fIerrB = 0.0;
fIerrC = 0.0;
fIntA = 0.0;
fIntB = 0.0;
fIntC = 0.0;
fCurrCtrlA = 0.0;
fCurrCtrlB = 0.0;
fCurrCtrlC = 0.0;
}
//
// End of file
//
This code gives me the double switching. But the parts that were supposed to clamp to +1 have pulses of very high width due to which I can not go ahead and use the signals on my 3 phase inverter. When I remove the above mentioned double switching code, then undesired pulses of very high width disappear along with the desired double switching. There is something wrong with my code of double switching that is interacting with the remaining code to generate undesired pulses of very high width. I have attached image of PWM signal obtained from F28379D that shows very high width pulses. Can you please take a look at my code attached and let me know how can I fix this problem?

