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,

This is our code for three phase voltage source inverter to generate  spwm. We are obtaining partial output. So, can you please suggest us which part of code is affecting and what are the changes required to be done.

#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 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.98;
float kp = 0.5;
float ki = 0.5;
//
//
//// 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.