Other Parts Discussed in Thread: CONTROLSUITE
Tool/software: Code Composer Studio
Hello,
I am using F28027 dsp and i am working on an university project of making 3-ph SPWM closed-loop inverter.
i have reached upto the generation of SPWM signals on the DSP but i don't know how to implement ADC in the project (only coding not concept).
i have seen some examples of ADC programs and tried to add them in single program but it doesn't works.
My code in which i tried to implement the ADC program is below. i can't find what is wrong in this.
any help is appreciated.
The user sets the frequency of the SPWM by setting appropriately the // EPWM1_TIMER_TBPRD variable. The frequency of the PWM,up and down mode, // obeys the equations: TPWM=2xTBPRDxTTBCLK, TTBCLK=SYSCLKOUT/(HSPCLKDIVxCLKDIV). // By default: HSPCLKDIV=2, CLKDIV=1. // // The sine for the PWM is read by the chip ROM. The sine table consists of // 512 elements. // The frequency of sinusoidal PWM is defined by the period of the timer0 interrupt. // For 50Hz the sine table must be read, entirely in 20msec. This means that the // timer0 interrupt must occur in every 20/512 msec. // The general type for the is Ttimer=Tsin*Fcpu/index. // // The 120 degrees difference of the sine are set by the variables: // index = 0, zero degrees // index2= 170, 120 degrees // index3=340, for 240 degrees // // //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ #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]; //Interrupt prototype function for timer0 interrupt void cpu_timer0_isr(void); void update_compare(void); //Global PWM variables #define EPWM1_TIMER_TBPRD 14634 // Period register for 2050.2Hz #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.8; 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_setCmpA(PWMA,1000); //Initial duty cycle PWM_setCmpB(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); //-------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------- //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_setCmpA(PWMB,1000); //Initial duty cycle PWM_setCmpB(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_setCmpA(PWMC,1000); //Initial duty cycle PWM_setCmpB(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(;;) { } } 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; } //---------------------------------------------