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 in F28335

Hi community, I believe that my algorithm to perform 3 ADC in a F28335 is wrong.

I put the core code for any to reply and make any solution:

....

//Tomo lectura ADC
 while (AdcRegs.ADCST.bit.INT_SEQ1== 0) {} // Wait for interrupt
      
        AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
       
        ILsensed =((AdcRegs.ADCRESULT0>>4) );
        vi_11 =   ((AdcRegs.ADCRESULT1>>4) );
        vo_11 =   ((AdcRegs.ADCRESULT2>>4) );
 //fin lectura ADC

.....

I believe that this code perform 1 conversion and don't 3 is really in this way?

I need 3 conversions really  to make any operations.

guillermo

  • Guillermo,

    You'll need to attach or show the ADC register config.  The read you are doing is correct, but we need to see the ADC register settings to advise if you will get your 3 conversions.  For this ADC MAXCONV will dictate how many conversions happen for 1 ADC trigger.  In your case it should be set to value of 2(which gives 3 conversions per trigger).  I would also advise you to use the ADC Mirror result registers located at base addr 0xB00, these are already right justified and are in a 0WS section of the memory map.  Registers Adc space are 2WS reads, so you are incurring an additional time delay by reading from there.

    Best,

    Matthew

  • Hi Matthew, I put below the entire program, I follow the TI examples mode (for make a more readly the program):

    The program consist of the programming the ADC, timer0 and output ports (any for debugger purposes and fault I believe in the algorithm ).

    I make three conversions and need reprogram the timer0 thru any operations (division, case 2, 3)

     


    // TI File $Revision: /main/4 $
    // Checkin $Date: 9 septiembre 2010   23:29 $
    //###########################################################################
    //
    // FILE:   Example_2833xAdcSeqModeTest_7.c
    //
    // TITLE:  DSP2833x ADC Seq Mode Test.
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP2833x header files.
    //
    //    Make sure the CPU clock speed is properly defined in
    //    DSP2833x_Examples.h before compiling this example.
    //
    //    Connect the signal to be converted to channel A0, A1, A3.
    //
    //    As supplied, this project is configured for "boot to SARAM"
    //    operation.  The 2833x Boot Mode table is shown below.
    //    For information on configuring the boot mode of an eZdsp,
    //    please refer to the documentation included with the eZdsp,
    //
    //       $Boot_Table:
    //
    //         GPIO87   GPIO86     GPIO85   GPIO84
    //          XA15     XA14       XA13     XA12
    //           PU       PU         PU       PU
    //        ==========================================
    //            1        1          1        1    Jump to Flash
    //            1        1          1        0    SCI-A boot
    //            1        1          0        1    SPI-A boot
    //            1        1          0        0    I2C-A boot
    //            1        0          1        1    eCAN-A boot
    //            1        0          1        0    McBSP-A boot
    //            1        0          0        1    Jump to XINTF x16
    //            1        0          0        0    Jump to XINTF x32
    //            0        1          1        1    Jump to OTP
    //            0        1          1        0    Parallel GPIO I/O boot
    //            0        1          0        1    Parallel XINTF boot
    //            0        1          0        0    Jump to SARAM        <- "boot to SARAM"
    //            0        0          1        1    Branch to check boot mode
    //            0        0          1        0    Boot to flash, bypass ADC cal
    //            0        0          0        1    Boot to SARAM, bypass ADC cal
    //            0        0          0        0    Boot to SCI-A, bypass ADC cal
    //                                              Boot_Table_End$
    //
    // DESCRIPTION:
    //   
    //    Canal A0 es convertido para la corriente (ILensed)
    //    Canal A1 es convertido para la tension de entrada (vi_11)
    //    Canal A2 es convertido para la tension de salida (vo_11)
    //   
    //    Watch Variables:
    //                         ILensed, vi_11, vo_11.
    //
    //###########################################################################
    //
    // Original source by: S.S.
    // Modificado por: guillermo ruiz magaz
    // $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $
    // $Release Date: August 4, 2010 $
    //###########################################################################

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

    // ADC start parameters
    #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
    #define ADC_CKPS   0x0   // ADC module clock = HSPCLK/2*ADC_CKPS   = 25.0MHz/(1*2) = 12.5MHz
    #define ADC_SHCLK  0x1   // S/H width in ADC module periods        = 16 ADC clocks
    #define AVG        1  // Average sample limit
    #define ZOFFSET    0x00  // Average Zero offset
    #define BUF_SIZE   1  // Sample buffer size

    // Global variable for this example
    Uint16 ILsensed=0;  //corriente sensada del inductor
    Uint16 vi_11=0;     //voltage de entrada
    Uint16 vo_11=0;     //voltage de salida
    Uint16 ILsensed1=0; //variable intermedia para calcular el Ton
    float T=15;        //T es el periodo que deseamos mantener constante
                    //el T no hay que ponerlo en 15e-6, ya que los tiempos que calcularemos
                    //estan en esa base
    int control=0;
    float calculo_resto_ton=0;
    float calculo_toff=0;
    float IREF=2500;  //corresponde a 1.5 volts
    //como me da un error de compilacion pq me dice que n esta definida la funcion del timer
    //la pongo aqui abajo
    interrupt void cpu_timer0_isr(void);

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

    // Specific clock setting for this example:
       EALLOW;
       SysCtrlRegs.HISPCP.all = ADC_MODCLK;    // HSPCLK = SYSCLKOUT/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
    // Enable the pin GPIO34 as output
       EALLOW;
       GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;    // GPIO pin
       GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;     // Output pin
       //añado dos puertos mas de salida que seran para debugger
       GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;
       GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
       GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0;
       GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;
       //fin dos puertos añadidos
      
       //lineas añadidas guillermo
       //GpioDataRegs.GPBSET.bit.GPIO34 = 1;  //Set GPIO high   
       //fin lineas añadidas guillermo
       EDIS;

    // 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 registers
       PieVectTable.TINT0 = &cpu_timer0_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
       InitCpuTimers();
       InitAdc();  // For this example, init the ADC

    // Specific ADC setup for this example:
       AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
       AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
       AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;        // 1  Cascaded mode, lo pongo a cero sin modo cascada
       AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
       //codigo guillermo
       AdcRegs.ADCMAXCONV.all=0x2; // tres conversiones
       AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;   //añado dos conversiones mas la 1 y la 2
       AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;
       //fin codigo guillermo
       AdcRegs.ADCTRL1.bit.CONT_RUN = 1;       // Setup continuous run

    // Step 5. User specific code, enable interrupts:
    ////enable el timer
    // Enable CPU int1 which is connected to CPU-Timer 0
       IER |= M_INT1;
      
    // 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
    ////fin codigo enable timer
    ////inicio enable el ADC
       // Start SEQ1
       AdcRegs.ADCTRL2.all = 0x2000;
    ////fin enable el ADC

    // Step 6. inicializo el sistrema con el mosfet en OFF
    //control lo pongo a 0 para que entre en el case 0, es la condicion inicial
    control=0;
    //mosfet OFF
    GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;  //Set GPIO down
    //duracion timer 100ms para dar tiempo a cargar los condensadores Cin y Cout de la planta.
    ConfigCpuTimer(&CpuTimer0, 150, 10000000);
    CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0

       for(;;)
       {
       }
    }// fin de main
    ////////////////////////////////////////////////////////////////////////////
    //
    interrupt void cpu_timer0_isr(void)
    {
     
     //Tomo lectura ADC
     while (AdcRegs.ADCST.bit.INT_SEQ1== 0) {} // Wait for interrupt
          
            AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
           
            ILsensed =((AdcRegs.ADCRESULT0>>4) );
            vi_11 =   ((AdcRegs.ADCRESULT1>>4) );
            vo_11 =   ((AdcRegs.ADCRESULT2>>4) );
     //fin lectura ADC

    //toma de decisiones segun estemos en un tramo u otro de la corriente IL
            switch (control)
                {
                case 0:{  //esta es la condicion inicial
                        GpioDataRegs.GPBSET.bit.GPIO34 = 1;  //Set GPIO high
                        //pero estará en estado alto poco tiempo
                        ConfigCpuTimer(&CpuTimer0, 150, 1);
                        //CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
                        control=1;
                        break;               
                       }//fin caso 0   
                   
                case 1:{//estamos tramo a,b,c, y en concreto punto a.
                         GpioDataRegs.GPBSET.bit.GPIO34 = 1;  //Set GPIO high
                         ILsensed1=ILsensed;  //me guardo esta lectura, la necesitamos para cuandoe estemos en el case1
                         ConfigCpuTimer(&CpuTimer0, 150, 1);//duracion timer 1us
                         //CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
                         control =2;   
                              
                         break;  
                       }//fin caso 1
                case 2:{ //estamos tramo d,f y en concreto punto d.
                        //calculo resto TON
                        calculo_resto_ton=((IREF-ILsensed1)/(ILsensed-ILsensed1))    ;
                        //cargo timer0 con valor calculado
                        //pongo este poke yoke en caso de que la operacion anterior de casi 0
                        if (calculo_resto_ton<2||calculo_resto_ton>10) {
                                                 ConfigCpuTimer(&CpuTimer0, 150, 5);//fuerzo a 5 us por lo menos
                                                //pongo un toggle en un bit de debugger, para saber si entra esta parte del codigo
                                                GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1; // Toggle GPIO32
                                                }
                         else ConfigCpuTimer(&CpuTimer0, 150, calculo_resto_ton);//duracion timer calculo_resto_ton
                       
                        //CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
                        control =3;
                        GpioDataRegs.GPBSET.bit.GPIO34 = 1;  //Set GPIO high
                        break;
                        }//fin caso 2      
                case 3:{ //estamos en el punto g,h,i,j y en concreto punto h
                       
                        calculo_toff=T*vi_11/vo_11;
                        if (calculo_toff>10) {
                                    ConfigCpuTimer(&CpuTimer0, 150,7 );//fuerzo a 7 us por si acaso
                                    //pongo un toggle en un bit de debugger, para saber si entra esta parte del codigo
                                    GpioDataRegs.GPATOGGLE.bit.GPIO2 = 1; // Toggle GPIO32
                                    }
                        else ConfigCpuTimer(&CpuTimer0, 150,calculo_toff );
                        //CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
                           control=0;
                           GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;  //Set GPIO down
                           break;
                        }
               
                }//fin switch
    //interrupcion no reentrante
    ////este tramo final de considerar interrupcion reentrante o no.
    // Acknowledge this interrupt to receive more interrupts from group 1
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
       CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
    ////fin tramo final de considerar interrupcion no reentrante 

    }// fin interrupt void cpu_timer0_isr(void)

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