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.

PWM Duty Cycle Problem

Hello,

I am trying to set a PWM duty cycle with an ADC value on a C2000 Launchpad.

I am watching all of the registers and the ADC is reading properly however I am unable to write to the CMPA and CMPB registers to change the duty cycle. I can set the value initially at the start of the program but it becomes unchangeable after that point.

EPwm1Regs.CMPB = PWM;
//Tried directly writing to the register void update_compare(EPWM_INFO *epwm_info, unsigned int *PWM_PTR) { PWM_setCmpA(epwm_info->myPwmHandle, *PWM_PTR);
//And using the example from the PWM tutorials
PWM_setCmpB(epwm_info->myPwmHandle, *PWM_PTR); return; }

  • Hi Kyle,

    Which controller are you using? There seems be some initialization problems in your code.

    Regards,

    Gautam

  • Greetings Gautam,

    I am currently using the F28027 Launchpad.

    Here is my initialization routine stolen from a TI example. PWM count up mode.

    void InitEPwm1Example(PWM_Handle myPwm1, CLK_Handle myClk, EPWM_INFO *epwm1_info)
    {
    
        CLK_enablePwmClock(myClk, PWM_Number_1);
    
        // Setup TBCLK
        PWM_setCounterMode(myPwm1, PWM_CounterMode_Up);         // Count up
        PWM_setPeriod(myPwm1, EPWM_TIMER_TBPRD);               // Set timer period
        PWM_disableCounterLoad(myPwm1);                         // Disable phase loading
        PWM_setPhase(myPwm1, 0x0000);                           // Phase is 0
        PWM_setCount(myPwm1, 0x0000);                           // Clear counter
        PWM_setHighSpeedClkDiv(myPwm1, PWM_HspClkDiv_by_1);     // Clock ratio to SYSCLKOUT
        PWM_setClkDiv(myPwm1, PWM_ClkDiv_by_1);
    
        // Setup shadow register load on ZERO
        PWM_setShadowMode_CmpA(myPwm1, PWM_ShadowMode_Shadow);
        PWM_setShadowMode_CmpB(myPwm1, PWM_ShadowMode_Shadow);
        PWM_setLoadMode_CmpA(myPwm1, PWM_LoadMode_Zero);
        PWM_setLoadMode_CmpB(myPwm1, PWM_LoadMode_Zero);
    
        // Set Compare values
        PWM_setCmpA(myPwm1, EPWM_MIN_CMPA);    // Set compare A value
        PWM_setCmpB(myPwm1, EPWM_MIN_CMPB);    // Set Compare B value
    
        // Set actions
        PWM_setActionQual_Zero_PwmA(myPwm1, PWM_ActionQual_Clear);            // Set PWM1A on Zero
        PWM_setActionQual_CntUp_CmpA_PwmA(myPwm1, PWM_ActionQual_Set);    // Clear PWM1A on event A, up count
    
        PWM_setActionQual_Zero_PwmB(myPwm1, PWM_ActionQual_Clear);            // Set PWM1B on Zero
        PWM_setActionQual_CntUp_CmpB_PwmB(myPwm1, PWM_ActionQual_Set);    // Clear PWM1B on event B, up count
    
        // Interrupt where we will change the Compare Values
        PWM_setIntMode(myPwm1, PWM_IntMode_CounterEqualZero);   // Select INT on Zero event
        PWM_enableInt(myPwm1);                                  // Enable INT
        PWM_setIntPeriod(myPwm1, PWM_IntPeriod_ThirdEvent);     // Generate INT on 3rd event
    
        // Information this example uses to keep track
        // of the direction the CMPA/CMPB values are
        // moving, the min and max allowed values and
        // a pointer to the correct ePWM registers
        epwm1_info->EPwm_CMPA_Direction = EPWM_CMP_UP;   // Start by increasing CMPA & CMPB
        epwm1_info->EPwm_CMPB_Direction = EPWM_CMP_UP;
        epwm1_info->EPwmTimerIntCount = 0;               // Zero the interrupt counter
        epwm1_info->myPwmHandle = myPwm1;                // Set the pointer to the ePWM module
        epwm1_info->EPwmMaxCMPA = EPWM_MAX_CMPA;        // Setup min/max CMPA/CMPB values
        epwm1_info->EPwmMinCMPA = EPWM_MIN_CMPA;
        epwm1_info->EPwmMaxCMPB = EPWM_MAX_CMPB;
        epwm1_info->EPwmMinCMPB = EPWM_MIN_CMPB;
    
    }
    

  • Then In my ISR I have tried these two methods of writing to the registers.  My ADC value is stored in "PWM" and declared globally.

    unsigned int PWM;
    interrupt void epwm_isr(void)
    {
        EPwm1Regs.CMPA = PWM;//Tried directly writing to the register
        EPwm1Regs.CMPB = PWM;
        // Clear INT flag for this timer
        PWM_clearIntFlag(myPwm1);
        // Acknowledge this interrupt to receive more interrupts from group 3
        PIE_clearInt(myPie, PIE_GroupNumber_3);
    
        EPwm2Regs.CMPA = PWM;
        EPwm2Regs.CMPB = PWM;
        // Clear INT flag for this timer
        PWM_clearIntFlag(myPwm2);
        // Acknowledge this interrupt to receive more interrupts from group 3
        PIE_clearInt(myPie, PIE_GroupNumber_3);
    
        EPwm3Regs.CMPA = PWM;
        EPwm3Regs.CMPB = PWM;
        // Clear INT flag for this timer
        PWM_clearIntFlag(myPwm3);
        // Acknowledge this interrupt to receive more interrupts from group 3
        PIE_clearInt(myPie, PIE_GroupNumber_3);
    }
    

    interrupt void epwm_isr(void)
    {
        // Update the CMPA and CMPB values
        update_compare(&epwm1_info, &PWM);
        // Clear INT flag for this timer
        PWM_clearIntFlag(myPwm1);
        // Acknowledge this interrupt to receive more interrupts from group 3
        PIE_clearInt(myPie, PIE_GroupNumber_3);
    
        // Update the CMPA and CMPB values
        update_compare(&epwm2_info, &PWM);
        // Clear INT flag for this timer
        PWM_clearIntFlag(myPwm2);
        // Acknowledge this interrupt to receive more interrupts from group 3
        PIE_clearInt(myPie, PIE_GroupNumber_3);
    
    
        // Update the CMPA and CMPB values
        update_compare(&epwm3_info, &PWM);
        // Clear INT flag for this timer
        PWM_clearIntFlag(myPwm3);
        // Acknowledge this interrupt to receive more interrupts from group 3
        PIE_clearInt(myPie, PIE_GroupNumber_3);
    
    
    }
    

  • Hi Kyle,

    Here's my attached code, I did work on this combination a way back!

    //#############################################################################
    // Code: ADC and PWM Integrated for TMS320FF28027
    // Name: Gautam G. Iyer
    // Location: Bangalore, India
    //#############################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    #include "f2802x_common/include/adc.h"
    #include "f2802x_common/include/clk.h"
    #include "f2802x_common/include/flash.h"
    #include "f2802x_common/include/gpio.h"
    #include "f2802x_common/include/pie.h"
    #include "f2802x_common/include/pll.h"
    #include "f2802x_common/include/pwm.h"
    #include "f2802x_common/include/wdog.h"
    
    // Prototype statements for functions found within this file.
    #define PWM1_TIMER_TBPRD   0x00C8			//TBPRD = 200 == 150Khz
    
    void InitEPwm1(void);
    // Global variables used in this example:
    uint16_t LoopCount;
    uint16_t ConversionCount;
    uint16_t V1, V2, V3;
    uint16_t V4, V5, V6;
    
    ADC_Handle myAdc;
    CLK_Handle myClk;
    FLASH_Handle myFlash;
    GPIO_Handle myGpio;
    PIE_Handle myPie;
    PWM_Handle myPwm1, myPwm2;
    
    void main(void)
    {
    
        CPU_Handle myCpu;
        PLL_Handle myPll;
        WDOG_Handle myWDog;
    
        // Initialize all the handles needed for this application
        myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj));
        myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_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));
        myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
        myPwm2 = PWM_init((void *)PWM_ePWM2_BASE_ADDR, sizeof(PWM_Obj));
        myPwm1 = PWM_init((void *)PWM_ePWM1_BASE_ADDR, sizeof(PWM_Obj));
        myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));
    
        // Perform basic system initialization
        WDOG_disable(myWDog);
        CLK_enableAdcClock(myClk);
        (*Device_cal)();
    
        //Select the internal oscillator 1 as the clock source
        CLK_setOscSrc(myClk, CLK_OscSrc_Internal);
    
        // Setup the PLL for x12 /2 which will yield 60Mhz = 10Mhz * 12 / 2
        PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2);
    
        // Disable the PIE and all interrupts
        PIE_disable(myPie);
        PIE_disableAllInts(myPie);
        CPU_disableGlobalInts(myCpu);
        CPU_clearIntFlags(myCpu);
    
    // If running from flash copy RAM only functions to RAM
    #ifdef _FLASH
        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif
    
        // Setup a debug vector table and enable the PIE
        PIE_setDebugIntVectorTable(myPie);
        PIE_enable(myPie);
    
        InitEPwm1();
    
        // Initialize the ADC
        ADC_enableBandGap(myAdc);
        ADC_enableRefBuffers(myAdc);
        ADC_powerUp(myAdc);
        ADC_enable(myAdc);
        ADC_setVoltRefSrc(myAdc, ADC_VoltageRefSrc_Int);
    
        LoopCount = 0;
        ConversionCount = 0;
    
        // Configure ADC
        //Note: Channel ADCINA4  will be double sampled to workaround the ADC 1st sample issue for rev0 silicon errata
        ADC_setIntPulseGenMode(myAdc, ADC_IntPulseGenMode_Prior);               //ADCINT1 trips after AdcResults latch
        ADC_enableInt(myAdc, ADC_IntNumber_1);                                  //Enabled ADCINT1
        ADC_setIntMode(myAdc, ADC_IntNumber_1, ADC_IntMode_ClearFlag);          //Disable ADCINT1 Continuous mode
        ADC_setIntSrc(myAdc, ADC_IntNumber_1, ADC_IntSrc_EOC4);                 //setup EOC2 to trigger ADCINT1 to fire
        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
        ADC_setSocChanNumber (myAdc, ADC_SocNumber_4, ADC_SocChanNumber_A4);    //set SOC4 channel select to ADCINA4
    
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_0, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_1, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_2, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_3, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_4, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
    
        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 SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
        ADC_setSocSampleWindow(myAdc, ADC_SocNumber_3, ADC_SocSampleWindow_7_cycles);   //set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
        ADC_setSocSampleWindow(myAdc, ADC_SocNumber_4, ADC_SocSampleWindow_7_cycles);   //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
    
        // Enable PWM clock
        CLK_enablePwmClock(myClk, PWM_Number_2);
    
        // Setup PWM
        PWM_enableSocAPulse(myPwm2);                                         // Enable SOC on A group
        PWM_setSocAPulseSrc(myPwm2, PWM_SocPulseSrc_CounterEqualCmpAIncr);   // Select SOC from from CPMA on upcount
        PWM_setSocAPeriod(myPwm2, PWM_SocPeriod_FirstEvent);                 // Generate pulse on 1st event
        PWM_setCmpA(myPwm2, 0x0000);                                         // Set compare A value
        PWM_setPeriod(myPwm2, 0x05DC);                                       // Period = 1500 for 20Khz Sampling Frequency
        PWM_setCounterMode(myPwm2, PWM_CounterMode_Up);                      // count up and start
        CLK_enableTbClockSync(myClk);
    
        /*GPIO_setPullUp(myGpio, GPIO_Number_2, GPIO_PullUp_Disable);
        GPIO_setMode(myGpio, GPIO_Number_2, GPIO_2_Mode_EPWM2A);
    
            // Setup Sync
        PWM_setSyncMode(myPwm2, PWM_SyncMode_EPWMxSYNC);
    
           // Allow each timer to be sync'ed
        PWM_enableCounterLoad(myPwm2);
        PWM_setActionQual_Period_PwmA(myPwm2, PWM_ActionQual_Set);
      	PWM_setActionQual_CntUp_CmpA_PwmA(myPwm2, PWM_ActionQual_Clear);*/
    
    
        // Wait for ADC interrupt
        for(;;)
        {
        	while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0){}
        	AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1
        	V1  = AdcResult.ADCRESULT0; 				//Panel Voltage
        	V2 = AdcResult.ADCRESULT1; 				//Battery Voltage
        	V3  = AdcResult.ADCRESULT2; 				//Charger Voltage
        	V4  = AdcResult.ADCRESULT3; 				//Panel Current
        	V5 = AdcResult.ADCRESULT4; 				//Battery Current
        	PWM_setCmpA(myPwm1, 100);					//TBPRD = 200
    
    
        }
    
    }
    
    
    void InitEPwm1()
    {
    
        CLK_disableTbClockSync(myClk);
        CLK_enablePwmClock(myClk, PWM_Number_1);
        GPIO_setPullUp(myGpio, GPIO_Number_0, GPIO_PullUp_Disable);
         GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_EPWM1A);
    
         // Setup Sync
        PWM_setSyncMode(myPwm1, PWM_SyncMode_EPWMxSYNC);
    
        // Allow each timer to be sync'ed
        PWM_enableCounterLoad(myPwm1);
    
        // Set the phase
       /* PWM_setPhase(myPwm1, 100);
        PWM_setPhase(myPwm1, 200);
        PWM_setPhase(myPwm1, 300);*/
    
        PWM_setPeriod(myPwm1, PWM1_TIMER_TBPRD);
        PWM_setCounterMode(myPwm1, PWM_CounterMode_Up);         // Count up
        PWM_setIntMode(myPwm1, PWM_IntMode_CounterEqualZero);   // Select INT on Zero event
        PWM_enableInt(myPwm1);                                  // Enable INT
        PWM_setIntPeriod(myPwm1, PWM_IntPeriod_FirstEvent);     // Generate INT on 1st event
    
        PWM_setActionQual_Period_PwmA(myPwm1, PWM_ActionQual_Set);
        PWM_setActionQual_CntUp_CmpA_PwmA(myPwm1, PWM_ActionQual_Clear);
        //PWM_setActionQual_Period_PwmB(myPwm1, PWM_ActionQual_Set);
        //PWM_setActionQual_CntUp_CmpA_PwmB(myPwm1, PWM_ActionQual_Clear);
    
    
        CLK_enableTbClockSync(myClk);
    
    }
    
    

    Regards,

    Gautam

  • Gautam,

    Am I misreading your code?

    The ADC value are never actually used to change the PWM.

    The PWM is set to stay at 100/200 or 50%, right?

    // Wait for ADC interrupt
        for(;;)
        {
        	while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0){}
        	AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1
        	V1  = AdcResult.ADCRESULT0; 				//Panel Voltage
        	V2 = AdcResult.ADCRESULT1; 				//Battery Voltage
        	V3  = AdcResult.ADCRESULT2; 				//Charger Voltage
        	V4  = AdcResult.ADCRESULT3; 				//Panel Current
        	V5 = AdcResult.ADCRESULT4; 				//Battery Current
        	PWM_setCmpA(myPwm1, 100);					//TBPRD = 200
    
    
        }

  • Kyle, this is not the exact code you're looking for. It has working ADC and PWM modules together, you can customize them according to your wish.

    Let me know how it goes.

    Regards,

    Gautam

  • Unfortunately, everything in your code functions perfectly just like my existing code except for the last piece of loading an ADC value into the comparator registers to change the PWM duty cycle.

    I am at a loss for an answer at this point, I must be doing some silly little mistake but am unable to locate it for the life of me. :/

    I am not using DSP bios but this thread describes my problem with writing to the compare registers to change the PWM duty cycle.

    http://e2e.ti.com/support/microcontrollers/c2000/f/171/t/310506.aspx

  • Hi Kyle,

    Can you please brief me, how're you trying to achieve this?

    except for the last piece of loading an ADC value into the comparator registers to change the PWM duty cycle.

    Is it something like this:

    V1  = AdcResult.ADCRESULT0;
    PWM_setCmpA(myPwm1, V1);

    Also what is your PWM TBPRD?

    Regards,

    Gautam

  • Gautam,

    You are correct. On your example I am trying exactly that.

    I have not changes anything else in the example so the PWM time period is still 0x00C8.

    In my code I am using 2000 as a PWM time period. So I limit my ADC values to no higher than 1800 to ensure that I am not loading a value too large.

    ADC_VAL1 = ADC_readResult(myAdc, ADC_ResultNumber_1);
    	ADC_VAL2 = ADC_readResult(myAdc, ADC_ResultNumber_2);
    
    
    	if(ADC_VAL2 > 1800)
    	{
    		ADC_VAL2 = 1800;
    	}
    
    	countUntilComm = ADC_VAL1;
    	PWM = ADC_VAL2;
    
    







    void update_compare(EPWM_INFO *epwm_info)
    {
    	PWM_setCmpA(epwm_info->myPwmHandle, PWM);//And using the example from the PWM tutorials
    	PWM_setCmpB(epwm_info->myPwmHandle, PWM);
        return;
    }
    

  • Kyle, here is a working code:

    //#############################################################################
    // Code: ADC and PWM Integrated for TMS320FF28027
    // Name: Gautam G. Iyer
    // Location: Bangalore, India
    //#############################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    #include "f2802x_common/include/adc.h"
    #include "f2802x_common/include/clk.h"
    #include "f2802x_common/include/flash.h"
    #include "f2802x_common/include/gpio.h"
    #include "f2802x_common/include/pie.h"
    #include "f2802x_common/include/pll.h"
    #include "f2802x_common/include/pwm.h"
    #include "f2802x_common/include/wdog.h"
    
    // Prototype statements for functions found within this file.
    #define PWM1_TIMER_TBPRD   0x07D0			//TBPRD = 2000
    
    void InitEPwm1(void);
    // Global variables used in this example:
    uint16_t LoopCount;
    uint16_t ConversionCount;
    uint16_t V1, V2, V3;
    uint16_t V4, V5, V6;
    
    ADC_Handle myAdc;
    CLK_Handle myClk;
    FLASH_Handle myFlash;
    GPIO_Handle myGpio;
    PIE_Handle myPie;
    PWM_Handle myPwm1, myPwm2;
    
    void main(void)
    {
    
        CPU_Handle myCpu;
        PLL_Handle myPll;
        WDOG_Handle myWDog;
    
        // Initialize all the handles needed for this application
        myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj));
        myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_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));
        myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
        myPwm2 = PWM_init((void *)PWM_ePWM2_BASE_ADDR, sizeof(PWM_Obj));
        myPwm1 = PWM_init((void *)PWM_ePWM1_BASE_ADDR, sizeof(PWM_Obj));
        myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));
    
        // Perform basic system initialization
        WDOG_disable(myWDog);
        CLK_enableAdcClock(myClk);
        (*Device_cal)();
    
        //Select the internal oscillator 1 as the clock source
        CLK_setOscSrc(myClk, CLK_OscSrc_Internal);
    
        // Setup the PLL for x12 /2 which will yield 60Mhz = 10Mhz * 12 / 2
        PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2);
    
        // Disable the PIE and all interrupts
        PIE_disable(myPie);
        PIE_disableAllInts(myPie);
        CPU_disableGlobalInts(myCpu);
        CPU_clearIntFlags(myCpu);
    
    // If running from flash copy RAM only functions to RAM
    #ifdef _FLASH
        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif
    
        // Setup a debug vector table and enable the PIE
        PIE_setDebugIntVectorTable(myPie);
        PIE_enable(myPie);
    
        InitEPwm1();
    
        // Initialize the ADC
        ADC_enableBandGap(myAdc);
        ADC_enableRefBuffers(myAdc);
        ADC_powerUp(myAdc);
        ADC_enable(myAdc);
        ADC_setVoltRefSrc(myAdc, ADC_VoltageRefSrc_Int);
    
        LoopCount = 0;
        ConversionCount = 0;
    
        // Configure ADC
        //Note: Channel ADCINA4  will be double sampled to workaround the ADC 1st sample issue for rev0 silicon errata
        ADC_setIntPulseGenMode(myAdc, ADC_IntPulseGenMode_Prior);               //ADCINT1 trips after AdcResults latch
        ADC_enableInt(myAdc, ADC_IntNumber_1);                                  //Enabled ADCINT1
        ADC_setIntMode(myAdc, ADC_IntNumber_1, ADC_IntMode_ClearFlag);          //Disable ADCINT1 Continuous mode
        ADC_setIntSrc(myAdc, ADC_IntNumber_1, ADC_IntSrc_EOC4);                 //setup EOC2 to trigger ADCINT1 to fire
        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
        ADC_setSocChanNumber (myAdc, ADC_SocNumber_4, ADC_SocChanNumber_A4);    //set SOC4 channel select to ADCINA4
    
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_0, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_1, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_2, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_3, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        ADC_setSocTrigSrc(myAdc, ADC_SocNumber_4, ADC_SocTrigSrc_EPWM2_ADCSOCA);    //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
    
        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 SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
        ADC_setSocSampleWindow(myAdc, ADC_SocNumber_3, ADC_SocSampleWindow_7_cycles);   //set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
        ADC_setSocSampleWindow(myAdc, ADC_SocNumber_4, ADC_SocSampleWindow_7_cycles);   //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
    
        // Enable PWM clock
        CLK_enablePwmClock(myClk, PWM_Number_2);
    
        // Setup PWM
        PWM_enableSocAPulse(myPwm2);                                         // Enable SOC on A group
        PWM_setSocAPulseSrc(myPwm2, PWM_SocPulseSrc_CounterEqualCmpAIncr);   // Select SOC from from CPMA on upcount
        PWM_setSocAPeriod(myPwm2, PWM_SocPeriod_FirstEvent);                 // Generate pulse on 1st event
        PWM_setCmpA(myPwm2, 0x0000);                                         // Set compare A value
        PWM_setPeriod(myPwm2, 0x05DC);                                       // Period = 1500 for 20Khz Sampling Frequency
        PWM_setCounterMode(myPwm2, PWM_CounterMode_Up);                      // count up and start
        CLK_enableTbClockSync(myClk);
    
        /*GPIO_setPullUp(myGpio, GPIO_Number_2, GPIO_PullUp_Disable);
        GPIO_setMode(myGpio, GPIO_Number_2, GPIO_2_Mode_EPWM2A);
    
            // Setup Sync
        PWM_setSyncMode(myPwm2, PWM_SyncMode_EPWMxSYNC);
    
           // Allow each timer to be sync'ed
        PWM_enableCounterLoad(myPwm2);
        PWM_setActionQual_Period_PwmA(myPwm2, PWM_ActionQual_Set);
      	PWM_setActionQual_CntUp_CmpA_PwmA(myPwm2, PWM_ActionQual_Clear);*/
    
    
        // Wait for ADC interrupt
        for(;;)
        {
        	while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0){}
        	AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1
        	V1  = AdcResult.ADCRESULT0; 				//Panel Voltage
        	//V2 = AdcResult.ADCRESULT1; 				//Battery Voltage
        	//V3  = AdcResult.ADCRESULT2; 				//Charger Voltage
        	//V4  = AdcResult.ADCRESULT3; 				//Panel Current
        	//V5 = AdcResult.ADCRESULT4; 				//Battery Current
    		if(V1 > 1800)
    			V1=1800;
        	PWM_setCmpA(myPwm1, V1);					//TBPRD = 2000
        }
    
    }
    
    
    void InitEPwm1()
    {
    
        CLK_disableTbClockSync(myClk);
        CLK_enablePwmClock(myClk, PWM_Number_1);
        GPIO_setPullUp(myGpio, GPIO_Number_0, GPIO_PullUp_Disable);
         GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_EPWM1A);
    
         // Setup Sync
        PWM_setSyncMode(myPwm1, PWM_SyncMode_EPWMxSYNC);
    
        // Allow each timer to be sync'ed
        PWM_enableCounterLoad(myPwm1);
    
        // Set the phase
       /* PWM_setPhase(myPwm1, 100);
        PWM_setPhase(myPwm1, 200);
        PWM_setPhase(myPwm1, 300);*/
    
        PWM_setPeriod(myPwm1, PWM1_TIMER_TBPRD);
        PWM_setCounterMode(myPwm1, PWM_CounterMode_Up);         // Count up
        PWM_setIntMode(myPwm1, PWM_IntMode_CounterEqualZero);   // Select INT on Zero event
        PWM_enableInt(myPwm1);                                  // Enable INT
        PWM_setIntPeriod(myPwm1, PWM_IntPeriod_FirstEvent);     // Generate INT on 1st event
    
        PWM_setActionQual_Period_PwmA(myPwm1, PWM_ActionQual_Set);
        PWM_setActionQual_CntUp_CmpA_PwmA(myPwm1, PWM_ActionQual_Clear);
        //PWM_setActionQual_Period_PwmB(myPwm1, PWM_ActionQual_Set);
        //PWM_setActionQual_CntUp_CmpA_PwmB(myPwm1, PWM_ActionQual_Clear);
    
    
        CLK_enableTbClockSync(myClk);
    
    }
    
    

    Regards,

    Gautam

  • It works!!!!

    I really appreciate your help!

    Now I need to spend a few hours trying to unravel all of my mistakes and understand exactly where I am going wrong.

    Thank you!

  • That's great!

    Kyle, I would insist you to please go through the sample codes and peripheral user guides thoroughly. Its very important to not skip any steps while configuring peripherals or faulty configuration; that I found in your case.

    Good luck and Regards,
    Gautam