This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/TMS320F28027: regarding spwm

Part Number: TMS320F28027

Tool/software: TI C/C++ Compiler

Hii,

I am using this code for three phase voltage source inverter for generating spwm. Can you tell me which part of code affect modulation index or  changing modulation index?

#include <stdio.h>
#include <file.h>
#include "DSP28x_Project.h" // DSP28x Headerfile
#include "f2802x_common/include/F2802x_GlobalPrototypes.h"
#include "f2802x_common/include/pll.h"
#include "f2802x_common/include/clk.h"
#include "f2802x_common/include/wdog.h"
#include "f2802x_common/include/flash.h"
#include "f2802x_common/include/gpio.h"
#include "f2802x_common/include/pie.h"
#include "f2802x_common/include/adc.h"
#include "f2802x_common/include/sci.h"
#include "f2802x_common/include/sci_io.h"
#include "f2802x_common/include/pwm.h"
#include "f2802x_common/include/timer.h"
#include "f2802x_common/include/IQmathLib.h" //IQmath Library header file
extern void DSP28x_usDelay(Uint32 Count);
#pragma DATA_SECTION(sine_table,"IQmathTables"); //IQmath ROM sine table
_iq30 sine_table[512];
int i;
//Interrupt prototype function for timer0
interrupt void cpu_timer0_isr(void);
void update_compare(void);
//Global PWM variables
#define EPWM1_TIMER_TBPRD 21424 // Period register for 2050.2Hz //50hz
#define PHASE 120.0 // Defines the real in degrees phase between phases, 120deg
#define TTIMERREG 2343 // Timer interrupt for 50Hz SPWM
Uint16 EPWM_PHASE=(EPWM1_TIMER_TBPRD*PHASE/180.0); //The phase as seen from the EPWM module
Uint16 duty_cycle_A=1000; // Set duty 50% initially
Uint16 duty_cycle_B=1000; // Set duty 50% initially

Uint16 index=0; // Zero degrees sine
Uint16 index2=170; // 120 degrees sine difference
Uint16 index3=340; // 240 degrees sine difffence

Uint16 DEADTIME_R=5.0; // Deadtime 5usec
Uint16 DEADTIME_F=5.0; // Deadtime 5usec
// Handles setup
CPU_Handle myCpu;
PLL_Handle myPll;
WDOG_Handle myWDog;
CLK_Handle myClk;
ADC_Handle myAdc;
FLASH_Handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
// SCI_Handle mySci;
PWM_Handle PWMA,PWMB,PWMC;
TIMER_Handle myTimer0;
//
//// ADC global variables used in this example:
uint16_t ADC0, ADC1, ADC2, ADC3,sp,mean;
double error, integral;
float ma = 0;
float kp = 0;
float ki = 0;
//
//
//// Handles initialization
void setup_handles()
{
myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));
myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));
myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
// mySci = SCI_init((void *)SCIA_BASE_ADDR, sizeof(SCI_Obj));
myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj));
PWMA = PWM_init((void *)PWM_ePWM1_BASE_ADDR, sizeof(PWM_Obj));
PWMB = PWM_init((void *)PWM_ePWM2_BASE_ADDR, sizeof(PWM_Obj));
PWMC = PWM_init((void *)PWM_ePWM3_BASE_ADDR, sizeof(PWM_Obj));
myTimer0 = TIMER_init((void *)TIMER0_BASE_ADDR, sizeof(TIMER_Obj));
}
////System Initialization
void init_system()
{
//Disable watchcdog
WDOG_disable(myWDog);
//Device calibration for the adc
(*Device_cal)();
//Sets the internal oscillator source
CLK_setOscSrc(myClk, CLK_OscSrc_Internal);
// Setup the PLL for x10 /2 which will yield 60Mhz = 10Mhz * 12 / 2
PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2);
//Disable the PIE peripheral and all the interupts
PIE_disable(myPie);
PIE_disableAllInts(myPie);
CPU_disableGlobalInts(myCpu);
CPU_clearIntFlags(myCpu);
#ifdef _FLASH
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif
}
//
//
////GPIO initialization
void gpio_init()
{
// Initialize GPIO for the EPWM1A and EPWM1B
GPIO_setPullUp(myGpio, GPIO_Number_0, GPIO_PullUp_Disable);
GPIO_setPullUp(myGpio, GPIO_Number_1, GPIO_PullUp_Disable);
GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_EPWM1A);
GPIO_setMode(myGpio, GPIO_Number_1, GPIO_1_Mode_EPWM1B);
GPIO_setDirection(myGpio,GPIO_Number_0,GPIO_Direction_Output);
GPIO_setDirection(myGpio,GPIO_Number_1,GPIO_Direction_Output);
// Initialize GPIO for the EPWM2A and EPWM2B
GPIO_setPullUp(myGpio, GPIO_Number_2, GPIO_PullUp_Disable);
GPIO_setPullUp(myGpio, GPIO_Number_3, GPIO_PullUp_Disable);
GPIO_setMode(myGpio, GPIO_Number_2, GPIO_2_Mode_EPWM2A);
GPIO_setMode(myGpio, GPIO_Number_3, GPIO_3_Mode_EPWM2B);
GPIO_setDirection(myGpio,GPIO_Number_2,GPIO_Direction_Output);
GPIO_setDirection(myGpio,GPIO_Number_3,GPIO_Direction_Output);
// Initialize GPIO for the EPWM2A and EPWM2B
GPIO_setPullUp(myGpio, GPIO_Number_4, GPIO_PullUp_Disable);
GPIO_setPullUp(myGpio, GPIO_Number_5, GPIO_PullUp_Disable);
GPIO_setMode(myGpio, GPIO_Number_4, GPIO_4_Mode_EPWM3A);
GPIO_setMode(myGpio, GPIO_Number_5, GPIO_5_Mode_EPWM3B);
GPIO_setDirection(myGpio,GPIO_Number_4,GPIO_Direction_Output);
GPIO_setDirection(myGpio,GPIO_Number_5,GPIO_Direction_Output);
}


//PWM settings
void pwma_init()
{
// PWMA initialization
CLK_enablePwmClock(myClk, PWM_Number_1);
//PWMA initialiazation
// Setup TBCLK

PWM_setCounterMode(PWMA,PWM_CounterMode_UpDown); // Count up-down
PWM_setPeriod(PWMA,EPWM1_TIMER_TBPRD); // Set timer period
PWM_disableCounterLoad(PWMA); // Disable phase loading
PWM_setSyncMode(PWMA,PWM_SyncMode_Disable);
PWM_setCount(PWMA, 0x0000); // Clear counter
PWM_setClkDiv(PWMA, PWM_ClkDiv_by_1);
PWM_setHighSpeedClkDiv(PWMA, PWM_HspClkDiv_by_1); // Clock ratio to SYSCLKOUT
// Setup shadowing

PWM_setShadowMode_CmpA(PWMA, PWM_ShadowMode_Shadow);
PWM_setShadowMode_CmpB(PWMA, PWM_ShadowMode_Shadow);
PWM_setLoadMode_CmpA(PWMA, PWM_LoadMode_Zero);
PWM_setLoadMode_CmpB(PWMA, PWM_LoadMode_Zero);
PWM_write_CmpA(PWMA,1000); //Initial duty cycle
PWM_write_CmpB(PWMA,1000);
// Set actions
PWM_setActionQual_CntUp_CmpA_PwmA(PWMA, PWM_ActionQual_Set); // Set PWM1A on event A, up count
PWM_setActionQual_CntDown_CmpA_PwmA(PWMA, PWM_ActionQual_Clear); // Clear PWM1A on event A, down count
PWM_setActionQual_CntUp_CmpB_PwmB(PWMA, PWM_ActionQual_Clear); // Set PWM1B on event B, up count
PWM_setActionQual_CntDown_CmpB_PwmB(PWMA, PWM_ActionQual_Set); // Clear PWM1B on event B, down count
//Set DeadBand Control
PWM_setDeadBandOutputMode(PWMA, PWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling);
PWM_setDeadBandPolarity(PWMA, PWM_DeadBandPolarity_EPWMxB_Inverted);
PWM_setDeadBandInputMode(PWMA, PWM_DeadBandInputMode_EPWMxA_Rising_and_Falling);
PWM_setDeadBandRisingEdgeDelay(PWMA, DEADTIME_R);
PWM_setDeadBandFallingEdgeDelay(PWMA, DEADTIME_F);

// // delay
//
//
//
//
//
////--------------------------------------------------------------------------------------------------------------------
////--------------------------------------------------------------------------------------------------------------------
// //PWMB initialization
// CLK_enablePwmClock(myClk, PWM_Number_2);
// Setup TBCLK
PWM_setCounterMode(PWMB,PWM_CounterMode_UpDown); // Count up-down
PWM_setPeriod(PWMB,EPWM1_TIMER_TBPRD); // Set timer period
PWM_enableCounterLoad(PWMB);
PWM_setPhaseDir(PWMB,PWM_PhaseDir_CountDown);
PWM_setSyncMode(PWMB,PWM_SyncMode_Disable);
PWM_setCount(PWMB, 0x0000); // Clear counter
PWM_setClkDiv(PWMB, PWM_ClkDiv_by_1);
PWM_setHighSpeedClkDiv(PWMB, PWM_HspClkDiv_by_1); // Clock ratio to SYSCLKOUT
// Setup shadowing
PWM_setShadowMode_CmpA(PWMB, PWM_ShadowMode_Shadow);
PWM_setShadowMode_CmpB(PWMB, PWM_ShadowMode_Shadow);
PWM_setLoadMode_CmpA(PWMB, PWM_LoadMode_Zero);
PWM_setLoadMode_CmpB(PWMB, PWM_LoadMode_Zero);
PWM_write_CmpA(PWMB,1000); //Initial duty cycle
PWM_write_CmpB(PWMB,1000);
// Set actions
PWM_setActionQual_CntUp_CmpA_PwmA(PWMB, PWM_ActionQual_Set); // Set PWM2A on event A, up count
PWM_setActionQual_CntDown_CmpA_PwmA(PWMB, PWM_ActionQual_Clear); // Clear PWM2A on event A, down count
PWM_setActionQual_CntUp_CmpB_PwmB(PWMB, PWM_ActionQual_Clear); // Set PWM2B on event B, up count
PWM_setActionQual_CntDown_CmpB_PwmB(PWMB, PWM_ActionQual_Set); // Clear PWM2B on event B, down count
//Set DeadBand Control
PWM_setDeadBandOutputMode(PWMB, PWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling);
PWM_setDeadBandPolarity(PWMB, PWM_DeadBandPolarity_EPWMxB_Inverted);
PWM_setDeadBandInputMode(PWMB, PWM_DeadBandInputMode_EPWMxA_Rising_and_Falling);
PWM_setDeadBandRisingEdgeDelay(PWMB, DEADTIME_R);
PWM_setDeadBandFallingEdgeDelay(PWMB, DEADTIME_F);
//---------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------
//PWMC initialization
CLK_enablePwmClock(myClk, PWM_Number_3);
// Setup TBCLK
PWM_setCounterMode(PWMC,PWM_CounterMode_UpDown); // Count up-down
PWM_setPeriod(PWMC,EPWM1_TIMER_TBPRD); // Set timer period
PWM_enableCounterLoad(PWMC);
PWM_setPhaseDir(PWMC,PWM_PhaseDir_CountUp);
PWM_setSyncMode(PWMC,PWM_SyncMode_Disable);
PWM_setCount(PWMC, 0x0000); // Clear counter
PWM_setClkDiv(PWMC, PWM_ClkDiv_by_1);
PWM_setHighSpeedClkDiv(PWMC, PWM_HspClkDiv_by_1); // Clock ratio to SYSCLKOUT
// Setup shadowing
PWM_setShadowMode_CmpA(PWMC, PWM_ShadowMode_Shadow);
PWM_setShadowMode_CmpB(PWMC, PWM_ShadowMode_Shadow);
PWM_setLoadMode_CmpA(PWMC, PWM_LoadMode_Zero);
PWM_setLoadMode_CmpB(PWMC, PWM_LoadMode_Zero);
PWM_write_CmpA(PWMC,1000); //Initial duty cycle
PWM_write_CmpB(PWMC,1000);
// Set actions
PWM_setActionQual_CntUp_CmpA_PwmA(PWMC, PWM_ActionQual_Set); // Set PWM3A on event A, up count
PWM_setActionQual_CntDown_CmpA_PwmA(PWMC, PWM_ActionQual_Clear); // Clear PWM3A on event A, down count
PWM_setActionQual_CntUp_CmpB_PwmB(PWMC, PWM_ActionQual_Clear); // Set PWM3B on event B, up count
PWM_setActionQual_CntDown_CmpB_PwmB(PWMC, PWM_ActionQual_Set); // Clear PWM3B on event B, down count
//Set DeadBand Control
PWM_setDeadBandOutputMode(PWMC, PWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling);
PWM_setDeadBandPolarity(PWMC, PWM_DeadBandPolarity_EPWMxB_Inverted);
PWM_setDeadBandInputMode(PWMC, PWM_DeadBandInputMode_EPWMxA_Rising_and_Falling);
PWM_setDeadBandRisingEdgeDelay(PWMC, DEADTIME_R);
PWM_setDeadBandFallingEdgeDelay(PWMC, DEADTIME_F);
CLK_enableTbClockSync(myClk);
}

//PIE settings
void pie_init()
{
PIE_enable(myPie);
EALLOW;
EDIS;
PIE_registerPieIntHandler(myPie, PIE_GroupNumber_1, PIE_SubGroupNumber_7, (intVec_t)&cpu_timer0_isr);
EDIS;
}

//Timer settings
void timer0_init()
{
TIMER_stop(myTimer0);
TIMER_setPeriod(myTimer0,TTIMERREG);
TIMER_setPreScaler(myTimer0,0);
TIMER_reload(myTimer0);
TIMER_setEmulationMode(myTimer0, TIMER_EmulationMode_StopAfterNextDecrement);
TIMER_enableInt(myTimer0);
TIMER_start(myTimer0);
/********** Enable ADC iterrupts **********/
// Clear ADCINT1 flag reinitialize for next SOC
ADC_clearIntFlag(myAdc, ADC_IntNumber_1);
// Enables the specified ADC interrupt
PIE_enableAdcInt(myPie, ADC_IntNumber_1);

/********** Enable timer iterrupts **********/
// Enables a specified interrupt number
CPU_enableInt(myCpu, CPU_IntNumber_1); // CPU int1 which triggers on CPU-Timer 0
// Enables a specified interrupt number
// CPU_enableInt(myCpu, CPU_IntNumber_13); // CPU int13 which triggers on CPU-Timer 1
// Enables the Cpu Timer 0 interrupt
PIE_enableTimer0Int(myPie);

// Enables global interrupts
CPU_enableGlobalInts(myCpu);
}
// ADC initialization
void adc_init()
{
/********** Initialize ADC **********/

// Enables the ADC band gap circuit
ADC_enableBandGap(myAdc);
// Enables the ADC reference buffers circuit
ADC_enableRefBuffers(myAdc);
// Powers up the ADC
ADC_powerUp(myAdc);
// Enables the ADC
ADC_enable(myAdc);
// Sets the voltage reference source
// ADCCTL1 - ADC_ADCCTL1_ADCREFSEL_BITS
ADC_setVoltRefSrc(myAdc, ADC_VoltageRefSrc_Int);


// Clear ADCINT1 flag reinitialize for next SOC
ADC_clearIntFlag(myAdc, ADC_IntNumber_1);
// Enables the specified ADC interrupt
PIE_enableAdcInt(myPie, ADC_IntNumber_1);
// Enables the ADC interrupt
ADC_enableInt(myAdc, ADC_IntNumber_1);


// Sets the interrupt pulse generation mode
// ADCCTL1 - ADC_ADCCTL1_INTPULSEPOS_BITS
// param[in] adcHandle The ADC object handle
// param[in] pulseMode The pulse generation mode
ADC_setIntPulseGenMode(myAdc, ADC_IntPulseGenMode_Prior); //ADCINT1 trips after AdcResults latch

// Enables ADC interrupt
// INTSELxNy - ADC_INTSELxNy_INTE_BITS
// param[in] adcHandle The ADC object handle
// param[in] intNumber The interrupt number
ADC_enableInt(myAdc, ADC_IntNumber_1);

// Sets the interrupt mode
// INTSELxNy - ADC_INTSELxNy_INTCONT_BITS
// param[in] adcHandle The ADC object handle
// param[in] intNumber The interrupt number
// param[in] intMode The interrupt mode
ADC_setIntMode(myAdc, ADC_IntNumber_1, ADC_IntMode_ClearFlag); // Disable ADCINT1 Continuous mode

// Sets the interrupt source
// INTSELxNy - ADC_INTSELxNy_INTSEL_BITS
// param[in] adcHandle The ADC object handle
// param[in] intNumber The interrupt number
// param[in] intSrc The interrupt source
ADC_setIntSrc(myAdc, ADC_IntNumber_1, ADC_IntSrc_EOC3); // Setup EOC3 to trigger ADCINT1

// Sets the start-of-conversion (SOC) channel number
// ADCSOCxCTL - ADC_ADCSOCxCTL_CHSEL_BITS
// param[in] adcHandle The ADC object handle
// param[in] socNumber The SOC number
// param[in] chanNumber The channel number
ADC_setSocChanNumber (myAdc, ADC_SocNumber_0, ADC_SocChanNumber_A0); // Set SOC0 channel select to ADCINA0
ADC_setSocChanNumber (myAdc, ADC_SocNumber_1, ADC_SocChanNumber_A1); // Set SOC1 channel select to ADCINA1
ADC_setSocChanNumber (myAdc, ADC_SocNumber_2, ADC_SocChanNumber_A2); // Set SOC2 channel select to ADCINA2
ADC_setSocChanNumber (myAdc, ADC_SocNumber_3, ADC_SocChanNumber_A3); // Set SOC3 channel select to ADCINA3

// Sets the start-of-conversion (SOC) trigger source
// ADCSOCxCTL - ADC_ADCSOCxCTL_TRIGSEL_BITS
// param[in] adcHandle The ADC object handle
// param[in] socNumber The SOC number
// param[in] chanNumber The channel number
ADC_setSocTrigSrc(myAdc, ADC_SocNumber_0, ADC_SocTrigSrc_CpuTimer_0); // Set SOC0 start trigger on CpuTimer_0, due to round-robin SOC0 converts first then SOC1
ADC_setSocTrigSrc(myAdc, ADC_SocNumber_1, ADC_SocTrigSrc_CpuTimer_0); // Set SOC1 start trigger on CpuTimer_0, due to round-robin SOC1 converts first then SOC2
ADC_setSocTrigSrc(myAdc, ADC_SocNumber_2, ADC_SocTrigSrc_CpuTimer_0); // Set SOC2 start trigger on CpuTimer_0, due to round-robin SOC2 converts first then SOC3
ADC_setSocTrigSrc(myAdc, ADC_SocNumber_3, ADC_SocTrigSrc_CpuTimer_0); // Set SOC4 start trigger on CpuTimer_0


// Sets the start-of-conversion (SOC) sample delay
// ADCSOCxCTL - ADC_ADCSOCxCTL_ACQPS_BITS
// param[in] adcHandle The ADC object handle
// param[in] socNumber The SOC number
// param[in] sampleDelay The sample delay
ADC_setSocSampleWindow(myAdc, ADC_SocNumber_0, ADC_SocSampleWindow_7_cycles); // Set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
ADC_setSocSampleWindow(myAdc, ADC_SocNumber_1, ADC_SocSampleWindow_7_cycles); // Set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
ADC_setSocSampleWindow(myAdc, ADC_SocNumber_2, ADC_SocSampleWindow_7_cycles); // Set SOC2 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
ADC_setSocSampleWindow(myAdc, ADC_SocNumber_3, ADC_SocSampleWindow_7_cycles); // Set SOC3 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

/************************************************************************************************************************/

// Wait for ADC interrupt
while(1)
{
while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0){} // Wait until ADCINT1 is tripped

ADC0 = AdcResult.ADCRESULT0;
ADC1 = AdcResult.ADCRESULT1;
ADC2 = AdcResult.ADCRESULT2;
ADC3 = AdcResult.ADCRESULT3;

AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Clear ADCINT1

// Clear ADCINT1 flag reinitialize for next SOC
//ADC_clearIntFlag(myAdc, ADC_IntNumber_1);
}
}
void main()
{
setup_handles();
init_system();
gpio_init();
pwma_init();
pie_init();
timer0_init();

//Enables the CPU interrupt
CPU_enableInt(myCpu, CPU_IntNumber_1);
//Enables the interrupt of the Timer0 for the PIE module
PIE_enableTimer0Int(myPie);
CPU_enableGlobalInts(myCpu);
CPU_enableDebugInt(myCpu);
adc_init();

//Forever Loop to see the results
for(;;)
{
__asm("nop");

// update_compare();
}
}
interrupt void cpu_timer0_isr(void)
{
mean = (ADC0 + ADC1 + ADC2)/3;
error = sp - mean;
integral = error + integral;
ma = (kp*error) + (ki*integral);
update_compare();
// Acknowledge this interrupt to receive more interrupts from group 1
PIE_clearInt(myPie, PIE_GroupNumber_1);
}
void update_compare(void)
{
PWM_setCmpA(PWMA,_IQsat(_IQ30mpy((sine_table[index]+_IQ30(0.9999))/2,EPWM1_TIMER_TBPRD),EPWM1_TIMER_TBPRD,0));
PWM_setCmpB(PWMA,_IQsat(_IQ30mpy((sine_table[index]+_IQ30(0.9999))/2,EPWM1_TIMER_TBPRD),EPWM1_TIMER_TBPRD,0));

PWM_setCmpA(PWMB,_IQsat(_IQ30mpy((sine_table[index2]+_IQ30(0.9999))/2,EPWM1_TIMER_TBPRD),EPWM1_TIMER_TBPRD,0));
PWM_setCmpB(PWMB,_IQsat(_IQ30mpy((sine_table[index2]+_IQ30(0.9999))/2,EPWM1_TIMER_TBPRD),EPWM1_TIMER_TBPRD,0));

PWM_setCmpA(PWMC,_IQsat(_IQ30mpy((sine_table[index3]+_IQ30(0.9999))/2,EPWM1_TIMER_TBPRD),EPWM1_TIMER_TBPRD,0));
PWM_setCmpB(PWMC,_IQsat(_IQ30mpy((sine_table[index3]+_IQ30(0.9999))/2,EPWM1_TIMER_TBPRD),EPWM1_TIMER_TBPRD,0));
if (index++ >511) index = 0;
if (index2++ >511) index2 = 0;
if (index3++ >511) index3 = 0;
}

Thank you in advance