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.

tms320f28335 ADC doesn't work.

Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE

I working on adc-f28335 but it doesn't work, please help me. this is my code.

#include "DSP2833x_Device.h"
#include "math.h"
extern void InitAdc(void);
extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
interrupt void adc_isr(void);
unsigned int ap;
unsigned int dong;
float Loopcount;
void main (void)
{
Loopcount = 0;
InitSysCtrl();
EALLOW;
EDIS;
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.ADCINT = &adc_isr;
EDIS;
InitAdc();
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;
AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
AdcRegs.ADCTRL1.bit.ACQ_PS = 7; //1
AdcRegs.ADCTRL1.bit.CPS = 0;

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0;

AdcRegs.ADCTRL3.bit.ADCCLKPS = 0;
AdcRegs.ADCTRL3.bit.SMODE_SEL = 1;
AdcRegs.ADCMAXCONV.all = 1;
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0000;
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0001;

EPwm6Regs.ETSEL.bit.SOCAEN = 1;
EPwm6Regs.ETSEL.bit.SOCASEL = 4;
EPwm6Regs.ETPS.bit.SOCAPRD = 1;
EPwm6Regs.CMPA.half.CMPA = 0x0080;
EPwm6Regs.TBPRD = 0xFFFF;
EPwm6Regs.TBCTL.bit.CTRMODE = 0;

PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= 0x0001;
EINT;
ERTM;
for(;;)
{
Loopcount++;
}
}
interrupt void adc_isr(void)
{
ap = (AdcRegs.ADCRESULT0)*3/65520;
dong = (AdcRegs.ADCRESULT1)*3/65520;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
return;
}

  • Bui Tien,

    Can you describe the behavior that you see and how it deviates from your expectations?

    Does the adc_soc example from C2000Ware or ControlSUITE work?

    -Tommy
  • Sorry because i'm reply late.
    I'm modify code from example in ControlSUITE. I'm read datasheet adc and configure resgisters of adc. I want to read voltage of sensor. The in put of adc range from 0 to 2 voltage. I see value of voltage in Expression but the value incorrect, value i see : -200,xxx or 2.xxxe-12 (i don't remember correct the value).
    Please help me. Thank you.
  • Here code i try modify, but it's doesn't work.
    main.c:
    #include "DSP28x_Project.h"
    #include "math.h"
    extern void InitSysCtrl(void);
    extern void InitAdc(void);
    extern void InitPieCtrl(void);
    extern void InitPieVectTable(void);
    interrupt void adc_isr(void);
    Uint16 LoopCount;
    float Voltage1;
    float Voltage2;
    main()
    {
    LoopCount = 0;
    InitSysCtrl();
    EALLOW;
    #if (CPU_FRQ_150MHZ)
    #define ADC_MODCLK 0x3
    #endif
    EDIS;
    EALLOW;
    SysCtrlRegs.HISPCP.all = ADC_MODCLK;
    EDIS;
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
    EALLOW;
    PieVectTable.ADCINT = &adc_isr;
    EDIS;
    InitAdc();
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
    IER |= M_INT1;
    EINT;
    ERTM;
    // Assumes ePWM1 clock is already enabled in InitSysCtrl();
    EPwm1Regs.ETSEL.bit.SOCAEN = 1;
    EPwm1Regs.ETSEL.bit.SOCASEL = 4;
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;
    EPwm1Regs.CMPA.half.CMPA = 0x0080;
    EPwm1Regs.TBPRD = 0xFFFF;
    EPwm1Regs.TBCTL.bit.CTRMODE = 0;
    // for(;;)
    // {
    // LoopCount++;
    // }
    }
    interrupt void adc_isr(void)
    {
    Voltage1 = AdcMirror.ADCRESULT0;
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    return;
    }


    DSP2833x_Adc.c
    #include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
    #include "DSP2833x_Examples.h" // DSP2833x Examples Include File
    //
    // Defines
    //
    #define ADC_usDELAY 5000L

    void
    InitAdc(void)
    {
    extern void DSP28x_usDelay(Uint32 Count);
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
    ADC_cal();
    EDIS;
    AdcRegs.ADCTRL3.bit.ADCBGRFDN = 11;
    AdcRegs.ADCTRL3.bit.ADCPWDN = 1;
    AdcRegs.ADCTRL3.bit.ADCCLKPS = 1; // ADCLCK = HSPCLK/2*1
    AdcRegs.ADCTRL3.bit.SMODE_SEL = 1;
    /*
    AdcRegs.ADCTRL3.all = 0x00E0; // Power up bandgap/reference/ADC circuits
    */
    DELAY_US(ADC_usDELAY); // Delay before converting ADC channels
    AdcRegs.ADCMAXCONV.all = 0x0001;
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0000;

    AdcRegs.ADCTRL1.bit.ACQ_PS = 0;
    AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
    AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;
    AdcRegs.ADCTRL1.bit.CPS = 0;
    AdcRegs.ADCTRL1.bit.SUSMOD = 0;
    AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0;

    AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0; //SEQ1 to be started by SOCA from ePWM module
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; //Interrupt request by SEQ1 enabled for EOS
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 0x1; //Reset SEQ1 to initial pretrigerred state
    AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1; //Enable SOC from EPWMA trigger for SEQ1

    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //Clears the interrupt flag bit INT_SEQ1
    AdcRegs.ADCST.bit.INT_SEQ2_CLR = 1; //Clears the interrupt flag bit INT_SEQ2

    AdcRegs.ADCOFFTRIM.bit.OFFSET_TRIM = 0; // Set Offset Error Correction Value
    AdcRegs.ADCREFSEL.bit.REF_SEL =0;
    }
  • Bui Tien,

    I highly recommend that you first use an unmodified version of the ADC example in ControlSUITE because these examples are known to work so we can use it to make sure that your device and board are not faulty.

    I see that in your first example, you were trying to use the ADCRESULT0 value from AdcRegs directly without bit-shifting, but now you are using the AdcMirror, so you have identified one issue.

    Which pin are you applying the voltage to? At what point are you reading the value of Voltage1? It looks like your main() function will run to completion and exit your program as soon as the EPWM is configured.

    -Tommy
  • yes tlee, i use the adc example in ControlSUITE first, but it's doesn't work too. I see the code Adc_SOC in the ControlSUITE and regconize the code don't configure resgister ADCTRL2. why is it?
    I supply 1voltage at pin ADCINA0.
    I don't understand you said main() run to complete and exit as soon as epwm is configured. I configure epwm as same as in the example adc_soc in the ControlSUITE.
    Please help me. Thank you so much.
  • Bui Tien,

    The adc_soc example in controlSUITE (v142 attached) does configure  ADCTRL2.  Please confirm that your adc_soc example was not previously modified.

    //###########################################################################
    // Description
    //! \addtogroup f2833x_example_list
    //! <h1> ADC Start of Conversion (adc_soc)</h1>
    //!
    //! This ADC example uses ePWM1 to generate a periodic ADC SOC on SEQ1.
    //! Two channels are converted, ADCINA3 and ADCINA2.
    //!
    //! \b Watch \b Variables \n
    //! - Voltage1[10]	- Last 10 ADCRESULT0 values
    //! - Voltage2[10]	- Last 10 ADCRESULT1 values
    //! - ConversionCount	- Current result number 0-9
    //! - LoopCount		- Idle loop counter
    //
    //
    //###########################################################################
    // $TI Release: F2833x/F2823x Header Files and Peripheral Examples V142 $
    // $Release Date: November  1, 2016 $
    // $Copyright: Copyright (C) 2007-2016 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    // Prototype statements for functions found within this file.
    __interrupt void adc_isr(void);
    
    // Global variables used in this example:
    Uint16 LoopCount;
    Uint16 ConversionCount;
    Uint16 Voltage1[10];
    Uint16 Voltage2[10];
    
    main()
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
       InitSysCtrl();
    
       EALLOW;
       #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT
         #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz
       #endif
       #if (CPU_FRQ_100MHZ)
         #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz
       #endif
       EDIS;
    
       // Define ADCCLK clock frequency ( less than or equal to 25 MHz )
       // Assuming InitSysCtrl() has set SYSCLKOUT to 150 MHz
       EALLOW;
       SysCtrlRegs.HISPCP.all = ADC_MODCLK;
       EDIS;
    
    // Step 2. Initialize GPIO:
    // This example function is found in the DSP2833x_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 DSP2833x_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 DSP2833x_DefaultIsr.c.
    // This function is found in DSP2833x_PieVect.c.
       InitPieVectTable();
    
    // 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 register
       PieVectTable.ADCINT = &adc_isr;
       EDIS;    // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP2833x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       InitAdc();  // For this example, init the ADC
    
    // Step 5. User specific code, enable interrupts:
    
    // Enable ADCINT in PIE
       PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
       IER |= M_INT1; // Enable CPU Interrupt 1
       EINT;          // Enable Global interrupt INTM
       ERTM;          // Enable Global realtime interrupt DBGM
    
       LoopCount = 0;
       ConversionCount = 0;
    
    // Configure ADC
       AdcRegs.ADCMAXCONV.all = 0x0001;       // Setup 2 conv's on SEQ1
       AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // Setup ADCINA3 as 1st SEQ1 conv.
       AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
       AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
       AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)
    
    // 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 from CPMA 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
    
    // Wait for ADC interrupt
       for(;;)
       {
          LoopCount++;
       }
    }
    
    __interrupt void  adc_isr(void)
    {
      Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4;
      Voltage2[ConversionCount] = AdcRegs.ADCRESULT1 >>4;
    
      // If 40 conversions have been logged, start over
      if(ConversionCount == 9)
      {
         ConversionCount = 0;
      }
      else
      {
          ConversionCount++;
      }
    
      // Reinitialize for next ADC sequence
      AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
      AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
    
      return;
    }
    
    
    
    

    Also, take note of the comments at the top of the example stating which ADC channels are converted:

    //! This ADC example uses ePWM1 to generate a periodic ADC SOC on SEQ1.
    //! Two channels are converted, ADCINA3 and ADCINA2.

    Finally, you will see that the end of main() is an infinite for() loop that will keep the example program active.  Without this loop, the main() function will exit and your desired application will no longer be active.

    -Tommy

  • Hi tlee. This is the result when i use the example Adc_SOC in ControlSUITE. I just modify channel conversion to adcin3 from adcin0 and keep the code and supply 1voltage in adcin0. But the result i read is 17198. So the result false, right? Any suggestion about the problem. I look at the code and see the comment //Assumes ePWM1 clock is already enabled in InitSysCtrl(); . So the clock of epwm configured or not.
    Please help me. Thank you so much.

    #include "DSP28x_Project.h" // Device Headerfile and Examples Include File
    __interrupt void adc_isr(void);
    Uint16 LoopCount;
    // Uint16 ConversionCount;
    Uint16 Voltage1;
    Uint16 Voltage2;

    main()
    {
    InitSysCtrl();
    EALLOW;
    #if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT
    #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
    #endif
    #if (CPU_FRQ_100MHZ)
    #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz
    #endif
    EDIS;
    EALLOW;
    SysCtrlRegs.HISPCP.all = ADC_MODCLK;
    EDIS;
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
    EALLOW; // This is needed to write to EALLOW protected register
    PieVectTable.ADCINT = &adc_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers
    InitAdc(); // For this example, init the ADC
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
    IER |= M_INT1; // Enable CPU Interrupt 1
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM
    LoopCount = 0;
    // Configure ADC
    AdcRegs.ADCMAXCONV.all = 0x0001; // Setup 2 conv's on SEQ1
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA3 as 1st SEQ1 conv.
    AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup ADCINA2 as 2nd SEQ1 conv.
    AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

    // 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 from CPMA 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

    // Wait for ADC interrupt
    for(;;)
    {
    LoopCount++;
    }
    }

    __interrupt void adc_isr(void)
    {
    Voltage1 = AdcRegs.ADCRESULT0 >>4;
    Voltage2 = AdcRegs.ADCRESULT1 >>4;
    /* if(ConversionCount == 9)
    {
    ConversionCount = 0;
    }
    else
    {
    ConversionCount++;}
    */
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
    return;
    }
  • Bui Tien,

    It appears that you are again using a modified copy of the controlSUITE example beyond a simple change of channels. The original uses arrays to store ADC conversions, whereas your posted code has that removed. This is slowing down progress because we are unable to establish a reliable foundation for debug.

    When are you observing the Voltage1 value? Are you setting a breakpoint at the end of adc_isr() to observe the conversions?

    -Tommy
  • Bui Tien,

    It has been over two weeks since your last update. I assume that you were able to resolve your issue. If this isn’t the case, please reject this resolution and reply to this thread. If this thread is locked, please make a new thread describing the current status of your issue.

    -Tommy