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.

ADC conversion problem in TMS320F28069 control stick

Other Parts Discussed in Thread: TMS320F28069, CONTROLSUITE

          HI 

I got struck at ADC conversion process. After sensing the output voltage for the purpose of feedback and gave it to corresponding ADC pin (TMS320F28069) for example pin2. In the watch window when i observe the converted values, the problem is that the converted values are varying (which should not be).To stabilize this value i hused digital low pass filter, but still i couldn't stabilize.Can any one help ???

Following is the code i used for ADC conversion process.

        Voltage_ADC2 = AdcResult.ADCRESULT0;    //add Voltage_ADC2 to watch window
            Voltage_New = (Voltage_ADC2) * (3.3/4095)*25; // convert to the new value
            filter_input=Voltage_New;
             filter_feedback=((1-0.5)*filter_feedback)+(0.5*filter_input);
             Voltage_New=filter_feedback;
            EPwm1Regs.CMPA.half.CMPA = duty_cycle_A;

  • Hi Tarakanath,

    Tarakanath Kobaku said:
    In the watch window when i observe the converted values, the problem is that the converted values are varying (which should not be).To stabilize this value i hused digital low pass filter, but still i couldn't stabilize.Can any one help ???

    Yup, this is the first observation of every embedded engineer working on C2000 controllers. I used filters, did averaging for results to stabilize and increased acquisition window etc.

    I would like you to refer these links;

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

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

    Regards,

    Gautam

  • hi gautam ..thanks alot....i could figure the problem ...but i am not sure this is right.....and the problem is coming from analog signal , when i checked in DSO, it has noise ...may be this is effecting the ADC. Do have any idea  or can you suggest why noise is coming at sensing point???

  • Tarakanath Kobaku said:
    and the problem is coming from analog signal

    Ohh... Check your power board thoroughly for ground noise etc. The easiest way to eliminate them is using RC filter at ADC but then this slows down your processing. For the best design; as for what experts say, "Power board layout has to be perfect!"

    Isolating of Analog and digital signals have to be taken care of. Design of Isolated Power supplies (analog and digital) have to be taken care of.

    Do go through this doc: http://www.ti.com/lit/ml/sloa089/sloa089.pdf

    Regards,

    Gautam

  • Hi Tarakanath,

    Some things to look at to get good ADC conversion results:

    *Read the errata for any ADC related issues.  In particular, look at the first-sample issue erratum.

    *Check if your kit has static trim (it probably does if it is symbolized TMX): http://e2e.ti.com/support/microcontrollers/c2000/f/171/p/295877/1032650.aspx#1032650

    *In addition to what Gautam mentioned about adding an RC filter, sometimes increasing the S+H window duration (ACQPS setting in SOC configuration) can help.  This may also be necessary if you have a high impedance signal source (or a high R in the RC filter).  Not every ACQPS is valid, so check the ACQPS register description in the TRM: it will tell you which ones are valid.

  • Thank you Gautam , Devin Cottier ....

  • I want to sense "one" analog signal  for an ADC conversion in f28069 to do voltage mode control of dc dc converter.

    Can you suggest what all  are necessary  and how to configure ADC for one signal sensing. I tried but couldn't get the things done.

  • Tarakanath Kobaku said:
    Can you suggest what all  are necessary  and how to configure ADC for one signal sensing. I tried but couldn't get the things done.

    If you're referring adc_soc example from controlSuite then take care that, you edit as below:

    AdcRegs.INTSEL1N2.bit.INT1SEL 	= 0;    // setup EOC0 to trigger ADCINT1 to fire

    Remove SOC1 based lines. Go through the ePWM section in TRM and configure TRIGSEL accordingly

    Regards,

    Gautam

  • // Configure ADC
        EALLOW;
        AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;    // Enable non-overlap mode
        AdcRegs.ADCCTL1.bit.INTPULSEPOS    = 1;    // ADCINT1 trips after AdcResults latch
        AdcRegs.INTSEL1N2.bit.INT1E     = 1;    // Enabled ADCINT1
        AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;    // Disable ADCINT1 Continuous mode
        AdcRegs.INTSEL1N2.bit.INT1SEL     = 0;    // setup EOC1 to trigger ADCINT1 to fire
        AdcRegs.ADCSOC0CTL.bit.CHSEL     = 4;    // set SOC0 channel select to ADCINA4
        AdcRegs.ADCSOC0CTL.bit.TRIGSEL     = 5;    // set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        AdcRegs.ADCSOC0CTL.bit.ACQPS     = 6;    // set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
        
        EDIS;


  • That's Great!

    Goodluck & Regards,

    Gautam

  • thanks gautam .......i am trying to configure epwm part ....then i will post full code so that i will get your feedback....

  • // TI File $Revision: /main/2 $
    // Checkin $Date: January 4, 2011   10:02:04 $
    //###########################################################################
    //
    // FILE:    Example_2806xCpuTimer.c
    //
    // TITLE:   F2806x Device Getting Started Program.
    //
    // ASSUMPTIONS:
    //
    //    This program requires the F2806x header files.
    //
    //    Other then boot mode configuration, no other hardware configuration
    //    is required.
    //
    //
    //    As supplied, this project is configured for "boot to SARAM"
    //    operation.  The F2806x Boot Mode table is shown below.
    //
    //    $Boot_Table:
    //
    //    While an emulator is connected to your device, the TRSTn pin = 1,
    //    which sets the device into EMU_BOOT boot mode. In this mode, the
    //    peripheral boot modes are as follows:
    //
    //      Boot Mode:       EMU_KEY        EMU_BMODE
    //                       (0xD00)         (0xD01)
    //      ---------------------------------------
    //      Wait             !=0x55AA        X
    //      I/O              0x55AA             0x0000
    //      SCI              0x55AA             0x0001
    //      Wait             0x55AA             0x0002
    //      Get_Mode         0x55AA             0x0003
    //      SPI              0x55AA             0x0004
    //      I2C              0x55AA             0x0005
    //      OTP              0x55AA             0x0006
    //      ECANA            0x55AA             0x0007
    //      SARAM            0x55AA             0x000A      <-- "Boot to SARAM"
    //      Flash            0x55AA             0x000B
    //      Wait             0x55AA          Other
    //
    //   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
    //   according to the Boot Mode Table above. Build/Load project,
    //   Reset the device, and Run example
    //
    //   $End_Boot_Table
    //
    //
    // Description:
    //
    //    This example configures CPU Timer0, 1, and 2 and increments
    //    a counter each time the timer asserts an interrupt.
    //
    //       Watch Variables:
    //          CpuTimer0.InterruptCount
    //          CpuTimer1.InterruptCount
    //          CpuTimer2.InterruptCount
    //
    //###########################################################################
    // $TI Release: 2806x C/C++ Header Files V1.10 $
    // $Release Date: April 7, 2011 $
    //###########################################################################

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    #define period 2000  //assymetric PWM for switching frequency=40KHz

    // Prototype statements for functions found within this file.
    interrupt void cpu_timer0_isr(void);
    interrupt void cpu_timer1_isr(void);
    interrupt void cpu_timer2_isr(void);
    void configADC(void);
    void InitEpwm2example(void);
    Uint16 AdcResults[16];
    Uint16 LoopCount;
    float32 Voltage_ADC,Voltage_actual;
    float32 filter_input_k,filter_feedback_k,filter_feedback_k_1,filter_input_k_1;
    float32 e_k,e_k_1,e_k_2,vc_k,vc_k_1,vc_k_2,V0ref;

    void main(void)
    {
    //    Uint16  i = 0;    
    filter_feedback_k_1=0; filter_input_k_1=0;
    e_k_1=0;e_k_2=0;// initialize the past samples of error values to zero
    vc_k=0.0; //Assigning no duty cycle
    vc_k_1=0;vc_k_2=0;// initialize the past samples of control siganl values to zero
    V0ref=37.8215;// corresponds to input voltage of converter=25 Volts with D=0.33904

    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2806x_SysCtrl.c file.
       InitSysCtrl();

    // Step 2. Initalize GPIO:
    // This example function is found in the F2806x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
        
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;

    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2806x_PieCtrl.c file.
       InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2806x_DefaultIsr.c.
    // This function is found in F2806x_PieVect.c.
           InitPieVectTable();
           EALLOW;
           SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
           EDIS;

       configADC();
       InitEpwm2example();

    // 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.TINT0 = &cpu_timer0_isr;
       PieVectTable.TINT1 = &cpu_timer1_isr;
       PieVectTable.TINT2 = &cpu_timer2_isr;
       EDIS;    // This is needed to disable write to EALLOW protected registers
       
     
    // Step 4. Initialize the Device Peripheral. This function can be
    //         found in F2806x_CpuTimers.c
     InitCpuTimers();   // For this example, only initialize the Cpu Timers
     
     
    // Configure CPU-Timer  1, and 2 to interrupt every second:80MHz CPU Freq, 1 second Period (in uSeconds)
    //Configure CPU-Timer 0 to generate interrupt every 25 Microseconds:80MHz CPU Freq, 25 Microsecond Period (in uSeconds)

       ConfigCpuTimer(&CpuTimer0, 80, 25);
       ConfigCpuTimer(&CpuTimer1, 80, 1000000);
       ConfigCpuTimer(&CpuTimer2, 80, 1000000);

    // To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any
    // of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in F2806x_CpuTimers.h), the
    // below settings must also be updated.

       CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
       CpuTimer1Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
       CpuTimer2Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0

    // Step 5. User specific code, enable interrupts:
        EALLOW;
        GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;  // GPIO2 ->1 means Epwm-2A output
        
        EDIS;
        // Configure GPIO34 as a GPIO output pin so that LED for F2806x USB dongle
       EALLOW;
       GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
       GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
       EDIS;

    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
       IER |= M_INT1;
       IER |= M_INT13;
       IER |= M_INT14;

    // Enable TINT0 in the PIE: Group 1 interrupt 7
       PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

    // Enable global Interrupts and higher priority real-time debug events:
       EINT;   // Enable Global interrupt INTM
       ERTM;   // Enable Global realtime interrupt DBGM
       

    // Step 6. IDLE loop. Just sit and loop forever (optional):
       for(;;);

    }


    interrupt void cpu_timer0_isr(void)
    {
       CpuTimer0.InterruptCount++;
       Voltage_ADC = AdcResult.ADCRESULT0;    //add Voltage_ADC to watch window
       Voltage_actual = (Voltage_ADC) * (3.3/4095)*25; // convert to the new value, 25 is gain factor of sensing circuit
       filter_input_k=Voltage_actual;// do this for digital low pass filter
       filter_feedback_k=filter_feedback_k_1+1.25e-5*filter_input_k_1+1.25e-5*filter_input_k; //digital first order low pass filter    with sampling frequency=40KHZ    ;
       Voltage_actual=filter_feedback_k;
       e_k=V0ref - Voltage_actual;
       vc_k=1.7*vc_k_1 - 0.7005*vc_k_2 + 0.04337*e_k - 0.08502*e_k_1 + 0.04166*e_k_2; //PID controller in digital form using "tustin" transformation
       vc_k_1=vc_k;
       vc_k_2=vc_k_1;
       e_k_1=e_k;
       e_k_2=e_k_1;
       if (vc_k > 0.7) // Anti-wind up design
          vc_k = 0.7;
       else if (vc_k < 0.1)
          vc_k = 0.1;
       else
          vc_k=vc_k;  
          
       EPwm2Regs.CMPA.half.CMPA = (vc_k)* period;

       // Acknowledge this interrupt to receive more interrupts from group 1
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
    }

    void configADC(void)
    {
    // Configure ADC
        EALLOW;
        AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;    // Enable non-overlap mode
        AdcRegs.ADCCTL1.bit.INTPULSEPOS    = 1;    // ADCINT1 trips after AdcResults latch
        AdcRegs.INTSEL1N2.bit.INT1E     = 1;    // Enabled ADCINT1
        AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;    // Disable ADCINT1 Continuous mode
        AdcRegs.INTSEL1N2.bit.INT1SEL     = 0;    // setup EOC1 to trigger ADCINT1 to fire
        AdcRegs.ADCSOC0CTL.bit.CHSEL     = 4;    // set SOC0 channel select to ADCINA4
        AdcRegs.ADCSOC0CTL.bit.TRIGSEL     = 5;    // set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        AdcRegs.ADCSOC0CTL.bit.ACQPS     = 6;    // set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
        
        EDIS;

    //AdcRegs.ADCSOCFRC1.all = 0x1000;      // kick start ADC by causing a SOC12 event

        
    }
    void InitEpwm2example(void)
    {
    // Time-base registers

           EPwm2Regs.TBPRD = period;    // Set timer period, PWM frequency = 1 / period
           EPwm2Regs.TBPHS.all = 0;    // Time-Base Phase Register
           EPwm2Regs.TBCTR = 0;        // Time-Base Counter Register    
        EPwm2Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;  // Set Immediate load, #define    TB_IMMEDIATE    0x1
        EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count-up mode: used for asymmetric PWM, #define    TB_COUNT_UP        0x0
        EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;       // Disable phase loading, #define    TB_DISABLE        0x0
        EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//#define TB_SYNC_DISABLE    0x3
        EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;//#define TB_DIV1 0x0
        EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;   //#define TB_DIV1 0x0

           // Setup shadow register load on ZERO

           EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
               //EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
           EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;          // load on CTR=Zero
               //EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;  // load on CTR=Zero

           // Set Compare values

               //EPwm2Regs.CMPA.half.CMPA = vc_k;    // Set duty 50% initially
               //EPwm2Regs.CMPB = duty_cycle_B;        // Set duty 50% initially

           // Set actions

           EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM2A on Zero
           EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM2A on event A, up count

                //EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR;          // Set PWM2B on Zero
                //EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;            // Clear PWM2B on event B, up count
        
    }

    interrupt void cpu_timer1_isr(void)
    {
       CpuTimer1.InterruptCount++;
       // The CPU acknowledges the interrupt.
       EDIS;
    }

    interrupt void cpu_timer2_isr(void)
    {  EALLOW;
       CpuTimer2.InterruptCount++;
       // The CPU acknowledges the interrupt.
       EDIS;
    }

    //===========================================================================
    // No more.
    //===========================================================================

  • The above code is compiling without any error . and I am using ADC_A2 (pin2 )in f28069 for giving analog signal and EPWM-2A(pin27) in f28069 to give to Gate Driver. Is it correct or do i need to rectify any changes??? please suggest.

    Thanks

    Tarakanath.

  • Tarakanath, I'm unable to see the EPWM1a initializations for ADC triggering. Can you just refer the example code and implement it accordingly?

    Regards,

    Gautam

  • AdcRegs.ADCSOC0CTL.bit.TRIGSEL     = 5;    // set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

    i used this in ADC intialisation

  • Tarakanath Kobaku said:

    AdcRegs.ADCSOC0CTL.bit.TRIGSEL     = 5;    // set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

    i used this in ADC intialisation

    That's fine but you need to initialize EPWM1a as SOC for triggering ADC. Somewhat like this:

    // Assumes ePWM1 clock is already enabled in InitSysCtrl();
       EPwm1Regs.ETSEL.bit.SOCAEN	= 1;		// Enable SOC on A group
       EPwm1Regs.ETSEL.bit.SOCASEL	= 4;		// Select SOC from CMPA on upcount
       EPwm1Regs.ETPS.bit.SOCAPRD 	= 1;		// Generate pulse on 1st event
       EPwm1Regs.CMPA.half.CMPA 	= 0x0080;	// Set compare A value
       EPwm1Regs.TBPRD 				= 0xFFFF;	// Set period for ePWM1
       EPwm1Regs.TBCTL.bit.CTRMODE 	= 0;		// count up and start

    Regards,
    Gautam

  • Thanks gautam i did ...

    // TI File $Revision: /main/2 $
    // Checkin $Date: January 4, 2011   10:02:04 $
    //###########################################################################
    //
    // FILE:    Example_2806xCpuTimer.c
    //
    // TITLE:   F2806x Device Getting Started Program.
    //
    // ASSUMPTIONS:
    //
    //    This program requires the F2806x header files.
    //
    //    Other then boot mode configuration, no other hardware configuration
    //    is required.
    //
    //
    //    As supplied, this project is configured for "boot to SARAM"
    //    operation.  The F2806x Boot Mode table is shown below.
    //
    //    $Boot_Table:
    //
    //    While an emulator is connected to your device, the TRSTn pin = 1,
    //    which sets the device into EMU_BOOT boot mode. In this mode, the
    //    peripheral boot modes are as follows:
    //
    //      Boot Mode:       EMU_KEY        EMU_BMODE
    //                       (0xD00)         (0xD01)
    //      ---------------------------------------
    //      Wait             !=0x55AA        X
    //      I/O              0x55AA             0x0000
    //      SCI              0x55AA             0x0001
    //      Wait             0x55AA             0x0002
    //      Get_Mode         0x55AA             0x0003
    //      SPI              0x55AA             0x0004
    //      I2C              0x55AA             0x0005
    //      OTP              0x55AA             0x0006
    //      ECANA            0x55AA             0x0007
    //      SARAM            0x55AA             0x000A      <-- "Boot to SARAM"
    //      Flash            0x55AA             0x000B
    //      Wait             0x55AA          Other
    //
    //   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
    //   according to the Boot Mode Table above. Build/Load project,
    //   Reset the device, and Run example
    //
    //   $End_Boot_Table
    //
    //
    // Description:
    //
    //    This example configures CPU Timer0, 1, and 2 and increments
    //    a counter each time the timer asserts an interrupt.
    //
    //       Watch Variables:
    //          CpuTimer0.InterruptCount
    //          CpuTimer1.InterruptCount
    //          CpuTimer2.InterruptCount
    //
    //###########################################################################
    // $TI Release: 2806x C/C++ Header Files V1.10 $
    // $Release Date: April 7, 2011 $
    //###########################################################################

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    #define period 2000  //assymetric PWM for switching frequency=40KHz

    // Prototype statements for functions found within this file.
    interrupt void cpu_timer0_isr(void);
    interrupt void cpu_timer1_isr(void);
    interrupt void cpu_timer2_isr(void);
    void configADC(void);
    void InitEpwm2example(void);
    Uint16 AdcResults[16];
    Uint16 LoopCount;
    float32 Voltage_ADC,Voltage_actual;
    float32 filter_input_k,filter_feedback_k,filter_feedback_k_1,filter_input_k_1;
    float32 e_k,e_k_1,e_k_2,vc_k,vc_k_1,vc_k_2,V0ref;

    void main(void)
    {
    //    Uint16  i = 0;    
    filter_feedback_k_1=0; filter_input_k_1=0;
    e_k_1=0;e_k_2=0;// initialize the past samples of error values to zero
    vc_k=0.0; //Assigning no duty cycle
    vc_k_1=0;vc_k_2=0;// initialize the past samples of control siganl values to zero
    V0ref=37.8215;// corresponds to input voltage of converter=25 Volts with D=0.33904

    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2806x_SysCtrl.c file.
       InitSysCtrl();

    // Step 2. Initalize GPIO:
    // This example function is found in the F2806x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
        
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;

    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2806x_PieCtrl.c file.
       InitPieCtrl();

    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2806x_DefaultIsr.c.
    // This function is found in F2806x_PieVect.c.
           InitPieVectTable();
           EALLOW;
           SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
           EDIS;

       configADC();
       InitEpwm2example();

    // 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.TINT0 = &cpu_timer0_isr;
       PieVectTable.TINT1 = &cpu_timer1_isr;
       PieVectTable.TINT2 = &cpu_timer2_isr;
       EDIS;    // This is needed to disable write to EALLOW protected registers
       
     
    // Step 4. Initialize the Device Peripheral. This function can be
    //         found in F2806x_CpuTimers.c
     InitCpuTimers();   // For this example, only initialize the Cpu Timers
     
     
    // Configure CPU-Timer  1, and 2 to interrupt every second:80MHz CPU Freq, 1 second Period (in uSeconds)
    //Configure CPU-Timer 0 to generate interrupt every 25 Microseconds:80MHz CPU Freq, 25 Microsecond Period (in uSeconds)

       ConfigCpuTimer(&CpuTimer0, 80, 25);
       ConfigCpuTimer(&CpuTimer1, 80, 1000000);
       ConfigCpuTimer(&CpuTimer2, 80, 1000000);

    // To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any
    // of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in F2806x_CpuTimers.h), the
    // below settings must also be updated.

       CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
       CpuTimer1Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
       CpuTimer2Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0

    // Step 5. User specific code, enable interrupts:
        EALLOW;
        GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;  // GPIO2 ->1 means Epwm-2A output
        
        EDIS;
        // Configure GPIO34 as a GPIO output pin so that LED for F2806x USB dongle
       EALLOW;
       GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
       GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
       EDIS;

    // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
    // which is connected to CPU-Timer 1, and CPU int 14, which is connected
    // to CPU-Timer 2:
       IER |= M_INT1;
       IER |= M_INT13;
       IER |= M_INT14;

    // Enable TINT0 in the PIE: Group 1 interrupt 7
       PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

    // Enable global Interrupts and higher priority real-time debug events:
       EINT;   // Enable Global interrupt INTM
       ERTM;   // Enable Global realtime interrupt DBGM
       

    // Step 6. IDLE loop. Just sit and loop forever (optional):
       for(;;);

    }


    interrupt void cpu_timer0_isr(void)
    {
       CpuTimer0.InterruptCount++;
       Voltage_ADC = AdcResult.ADCRESULT0;    //add Voltage_ADC to watch window
       Voltage_actual = (Voltage_ADC) * (3.3/4095)*25; // convert to the new value, 25 is gain factor of sensing circuit
       filter_input_k=Voltage_actual;// do this for digital low pass filter
       filter_feedback_k=filter_feedback_k_1+1.25e-5*filter_input_k_1+1.25e-5*filter_input_k; //digital first order low pass filter    with sampling frequency=40KHZ    ;
       Voltage_actual=filter_feedback_k;
       e_k=V0ref - Voltage_actual;
       vc_k=1.7*vc_k_1 - 0.7005*vc_k_2 + 0.04337*e_k - 0.08502*e_k_1 + 0.04166*e_k_2; //PID controller in digital form using "tustin" transformation
       vc_k_1=vc_k;
       vc_k_2=vc_k_1;
       e_k_1=e_k;
       e_k_2=e_k_1;
       if (vc_k > 0.7) // Anti-wind up design
          vc_k = 0.7;
       else if (vc_k < 0.1)
          vc_k = 0.1;
       else
          vc_k=vc_k;  
          
       EPwm2Regs.CMPA.half.CMPA = (vc_k)* period;

       // Acknowledge this interrupt to receive more interrupts from group 1
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
    }

    void configADC(void)
    {
    // Configure ADC
        EALLOW;
        AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;    // Enable non-overlap mode
        AdcRegs.ADCCTL1.bit.INTPULSEPOS    = 1;    // ADCINT1 trips after AdcResults latch
        AdcRegs.INTSEL1N2.bit.INT1E     = 1;    // Enabled ADCINT1
        AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;    // Disable ADCINT1 Continuous mode
        AdcRegs.INTSEL1N2.bit.INT1SEL     = 0;    // setup EOC1 to trigger ADCINT1 to fire
        AdcRegs.ADCSOC0CTL.bit.CHSEL     = 4;    // set SOC0 channel select to ADCINA4
        AdcRegs.ADCSOC0CTL.bit.TRIGSEL     = 5;    // set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
        AdcRegs.ADCSOC0CTL.bit.ACQPS     = 6;    // set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
        
        EDIS;

    //AdcRegs.ADCSOCFRC1.all = 0x1000;      // kick start ADC by causing a SOC12 event
    // Assumes ePWM1 clock is already enabled in ADC-TriggeredADC-DevInit.C;
    // Configure start of conversion event
       EPwm1Regs.ETSEL.bit.SOCAEN    = 1;        // Enable SOC on A group
       EPwm1Regs.ETSEL.bit.SOCASEL    = 4;        // Select SOC from from CPMA on upcount
       EPwm1Regs.ETPS.bit.SOCAPRD     = 1;        // Generate pulse on 1st event
       EPwm1Regs.CMPA.half.CMPA         = 678;        // Set compare A value, duty cycle 50% initially
       EPwm1Regs.TBPRD                 = 2000;        // Set period, 80kHz when PLL is set to 0x10 (80MHz)
       EPwm1Regs.TBCTL.bit.CTRMODE     = 0;        // count up and start

        
    }
    void InitEpwm2example(void)
    {
    // Time-base registers

           EPwm2Regs.TBPRD = period;    // Set timer period, PWM frequency = 1 / period
           EPwm2Regs.TBPHS.all = 0;    // Time-Base Phase Register
           EPwm2Regs.TBCTR = 0;        // Time-Base Counter Register    
        EPwm2Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;  // Set Immediate load, #define    TB_IMMEDIATE    0x1
        EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count-up mode: used for asymmetric PWM, #define    TB_COUNT_UP        0x0
        EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;       // Disable phase loading, #define    TB_DISABLE        0x0
        EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//#define TB_SYNC_DISABLE    0x3
        EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;//#define TB_DIV1 0x0
        EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;   //#define TB_DIV1 0x0

           // Setup shadow register load on ZERO

           EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
               //EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
           EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;          // load on CTR=Zero
               //EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;  // load on CTR=Zero

           // Set Compare values

               //EPwm2Regs.CMPA.half.CMPA = vc_k;    // Set duty 50% initially
               //EPwm2Regs.CMPB = duty_cycle_B;        // Set duty 50% initially

           // Set actions

           EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM2A on Zero
           EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM2A on event A, up count

                //EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR;          // Set PWM2B on Zero
                //EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;            // Clear PWM2B on event B, up count
        
    }

    interrupt void cpu_timer1_isr(void)
    {
       CpuTimer1.InterruptCount++;
       // The CPU acknowledges the interrupt.
       EDIS;
    }

    interrupt void cpu_timer2_isr(void)
    {  EALLOW;
       CpuTimer2.InterruptCount++;
       // The CPU acknowledges the interrupt.
       EDIS;
    }

    //===========================================================================
    // No more.
    //===========================================================================

  • i have some doubts about this, which are

    EPwm1Regs.CMPA.half.CMPA         = 678;        // Set compare A value, duty cycle 50% initially
    EPwm1Regs.TBPRD                 = 2000;        // Set period, 80kHz when PLL is set to 0x10 (80MHz)

    (1).I want to operate the converter system with duty cycle at D=0.33904 and with up-count its value : 678 with a period=2000. is it right ??

    (2). how to know that , after how many switching cycles, control value is updated ? and how to know about the computation time that causes the delay ? can you tell me this ..

     

     

     

  • Seems fine now.

  • can you suggest some idea about my doubts....

  • Tarakanath Kobaku said:
    (1).I want to operate the converter system with duty cycle at D=0.33904 and with up-count its value : 678 with a period=2000. is it right ??

    Yup, very true.

    Tarakanath Kobaku said:
    (2). how to know that , after how many switching cycles, control value is updated ? and how to know about the computation time that causes the delay ? can you tell me this ..

    Toggling a GPIO is the easiest way to achieve this. Observe the same on DSO.

    Regards,

    Gautam

  • I want  to see that the output voltage is tracked to reference value in DSO. how to do this?

    Any suggestions???

    Thanks

    Tarakanath.

  • Tarakanath Kobaku said:

    I want  to see that the output voltage is tracked to reference value in DSO. how to do this?

    Any suggestions???

    Can you be more specific on what you're planning to achieve?

    Regards,

    Gautam