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 problem in TMS320F28335. Please help, need urgent help.

Other Parts Discussed in Thread: TMS320F28335

Dear All,

I am presently working with TMS320F28335. I have suddenly got some problem with the digital values. I am getting the digital values on serial port (as shown in the code below).  I have implemented the low-pass filter for reducing the garbage values. Initially it was fine and I have seen the difference between with and without filter. But now both the values are same. I don't know why. Can anyone help me. I need to correct it urgently. Please help me. I am not understanding what's the problem.

Thanks a lot!

Here's the code below:

 

// TI File $Revision: /main/11 $
// Checkin $Date: April 21, 2008   15:41:01 $
//###########################################################################
//
// FILE:   Example_2833xAdc.c
//
// TITLE:  DSP2833x ADC Example Program.
//
// 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 signals to be converted to A2 and 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:
//
//   This example sets up the PLL in x10/2 mode.
//
//   For 150 MHz devices (default)
//   divides SYSCLKOUT by six to reach a 25.0Mhz HSPCLK
//   (assuming a 30Mhz XCLKIN).
//
//   For 100 MHz devices:
//   divides SYSCLKOUT by four to reach a 25.0Mhz HSPCLK
//   (assuming a 20Mhz XCLKIN).
//
//   Interrupts are enabled and the ePWM1 is setup to generate a periodic
//   ADC SOC on SEQ1. Two channels are converted, ADCINA3 and ADCINA2.
//
//   Watch Variables:
//
//         Voltage1[10]     Last 10 ADCRESULT0 values
//         Voltage2[10]     Last 10 ADCRESULT1 values
//         ConversionCount  Current result number 0-9
//         LoopCount        Idle loop counter
//
//
//###########################################################################
//
// Original Author: D.F.
//
// $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $
// $Release Date: August 4, 2009 $
//###########################################################################

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

// Global variables used in this example:
#define SZ_VOL   32
Uint16 LoopCount  = 0;
Uint16 Voltage1[SZ_VOL];
Uint16 Voltage2[SZ_VOL];
Uint16 Voltage3[SZ_VOL];
Uint16 Voltage4[SZ_VOL];
Uint16 filteredVoltage1 = 0;
Uint16 filteredVoltage2 = 0;
Uint16 filteredVoltage3 = 0;
Uint16 filteredVoltage4 = 0;
Uint16 VoltageOut1   = 0;
Uint16 VoltageOut2   = 0;
Uint16 VoltageOut3   = 0;
Uint16 VoltageOut4   = 0;

#define SZ_MSG   20
#define MAX_SZ_MSG  30

Uint16 ReceivedChar;
Uint16 flgSend   = 0;
char msg[SZ_MSG]  = "\r\nStart.\0";
char total_msg[MAX_SZ_MSG] = "";

interrupt void adc_isr(void);
Uint16   low_pass_lim(Uint16 new, Uint16 old, float alpha);
void   scia_fifo_init();
void   scia_init();
void   scia_xmit(int a);
void   scia_msg(char * msg);
void   d2asc(Uint16 in, char *asc);
void    nullify(char * msg);

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;

 // 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
 InitSciaGpio();

 // 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
 scia_fifo_init(); // Initialize the SCI FIFO
 scia_init();  // Initalize SCI for echoback
 ADC_cal();

 // 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;

 // Configure ADC
 AdcRegs.ADCTRL3.bit.SMODE_SEL  = 0x1;
 AdcRegs.ADCMAXCONV.all    = 0x0003; // Setup 2 conv's on SEQ1
 AdcRegs.ADCCHSELSEQ1.bit.CONV00  = 0x4; // Setup ADCINA3 as 1st SEQ1 conv.
 AdcRegs.ADCCHSELSEQ1.bit.CONV01  = 0x3; // Setup ADCINA2 as 2nd SEQ1 conv.
 AdcRegs.ADCCHSELSEQ1.bit.CONV02  = 0x2; // Setup ADCINA1 as 3rd SEQ1 conv.
 AdcRegs.ADCCHSELSEQ1.bit.CONV03  = 0x1; // Setup ADCINA0 as 4th 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)
 //AdcRegs.ADCTRL1.all=0x0710;
 // 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.TBPRD    = 600;
 EPwm1Regs.TBCTL.bit.CTRMODE = 0;  // count up and start 

 scia_msg(msg);

 // Wait for ADC interrupt
 for(;;)
 {
  if (flgSend == 0){
   scia_msg("\r");
   d2asc(VoltageOut1, msg);
   strcat(total_msg,msg);
   d2asc(VoltageOut2, msg);
   strcat(total_msg,msg);
   //scia_msg("hello world");
   d2asc(VoltageOut3, msg);
   strcat(total_msg,msg);
   d2asc(VoltageOut4, msg);
   strcat(total_msg,msg);
   scia_msg(total_msg);
   //scia_msg("\n");
   nullify(total_msg);
   //scia_msg("\n");
   flgSend = 1;
   scia_msg("\n");

  }
  
  LoopCount++;
 }

}


interrupt void adc_isr(void)
{
 static int i = 0;
 
 Voltage1[i]  = AdcRegs.ADCRESULT0>>4;
 Voltage2[i]  = AdcRegs.ADCRESULT1>>4;
 Voltage3[i]  = AdcRegs.ADCRESULT2>>4;
 Voltage4[i]  = AdcRegs.ADCRESULT3>>4;

 //Voltage1[i]  = AdcRegs.ADCRESULT1>>4;
 //Voltage2[i]  = AdcRegs.ADCRESULT5>>4;
 //Voltage3[i]  = AdcRegs.ADCRESULT7>>4;
 //Voltage4[i]  = AdcRegs.ADCRESULT3>>4;
 
 filteredVoltage1= low_pass_lim(Voltage1[i], filteredVoltage1, 0.15);
 filteredVoltage2= low_pass_lim(Voltage2[i], filteredVoltage2, 0.15);
 filteredVoltage3= low_pass_lim(Voltage3[i], filteredVoltage3, 0.15);
 filteredVoltage4= low_pass_lim(Voltage4[i], filteredVoltage4, 0.15);

 if (flgSend != 0){
  //VoltageOut1 = filteredVoltage1;
  //VoltageOut2 = filteredVoltage2;
  //VoltageOut3 = filteredVoltage3;
  //VoltageOut4 = filteredVoltage4;
  VoltageOut1 = Voltage1[i];
  VoltageOut2 = Voltage2[i];
  VoltageOut3 = Voltage3[i];
  VoltageOut4 = Voltage4[i];
  flgSend  = 0;
 }

 i++;
 if(i>=SZ_VOL) i = 0;

 // 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;
}

Uint16 low_pass_lim(Uint16 new, Uint16 old, float alpha)
{
 float tmp32_1  = 0.0;
 float tmp32_2  = 0.0;
 float tmp32_3  = 0.0;

 tmp32_1 = (float)(new);
 tmp32_2 = (float)(old);
 tmp32_3 = alpha * tmp32_1 + (1.0 - alpha) * tmp32_2;
 return (Uint16)(tmp32_3);
}

void scia_fifo_init()
{
    SciaRegs.SCIFFTX.all=0xE040;
    SciaRegs.SCIFFRX.all=0x204f;
    SciaRegs.SCIFFCT.all=0x0;

}

// Test 1,SCIA  DLB, 8-bit word, baud rate 0x000F, default, 1 STOP bit, no parity
void scia_init()
{
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function

  SciaRegs.SCICCR.all =0x0007;   // 1 stop bit,  No loopback
                                   // No parity,8 char bits,
                                   // async mode, idle-line protocol
 SciaRegs.SCICTL1.all =0x0003;  // enable TX, RX, internal SCICLK,
                                   // Disable RX ERR, SLEEP, TXWAKE
 SciaRegs.SCICTL2.all =0x0003;
 SciaRegs.SCICTL2.bit.TXINTENA =1;
 SciaRegs.SCICTL2.bit.RXBKINTENA =1;
 #if (CPU_FRQ_150MHZ)
       SciaRegs.SCIHBAUD    =0x0001;  // 9600 baud @LSPCLK = 37.5MHz.
       SciaRegs.SCILBAUD    =0x00E7;
          //SciaRegs.SCIHBAUD    =0x0000;  // 115,200 baud @LSPCLK = 37.5MHz.
       //SciaRegs.SCILBAUD    =0x0028;
 #endif
 #if (CPU_FRQ_100MHZ)
      SciaRegs.SCIHBAUD    =0x0001;  // 9600 baud @LSPCLK = 20MHz.
      SciaRegs.SCILBAUD    =0x0044;
 #endif
 SciaRegs.SCICTL1.all =0x0023;  // Relinquish SCI from Reset
}

void scia_xmit(int a)
{
    while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {}
    SciaRegs.SCITXBUF=a;

}

void scia_msg(char *in)
{
    int i;
    i = 0;
    while(in[i] != '\0')
    {
        scia_xmit(in[i]);
        i++;
    }
}

void d2asc(Uint16 in, char *asc)
{
 float tmp1, tmp2;
 char out, out_tmp;

 asc[0] = ' ';
 asc[1] = ' '; 

 tmp1  = (float)(in);

 tmp2 = (float)(tmp1) * 0.001;
 out_tmp = (char)(tmp2);
 out  = out_tmp + 0x30;
 asc[2] = out;
 tmp1 = tmp1 - (float)(out_tmp) * 1000.0;

 tmp2 = (float)(tmp1) * 0.01;
 out_tmp = (char)(tmp2);
 out  = out_tmp + 0x30;
 asc[3] = out;
 tmp1 = tmp1 - (float)(out_tmp) * 100.0;

 tmp2 = (float)(tmp1) * 0.1;
 out_tmp = (char)(tmp2);
 out  = out_tmp + 0x30;
 asc[4] = out;
 tmp1 = tmp1 - (float)(out_tmp) * 10.0;

 tmp2 = (float)(tmp1) * 1.0;
 out_tmp = (char)(tmp2);
 out  = out_tmp + 0x30;
 asc[5] = out;
 
 asc[6] = '\0';
}

void nullify( char * msg ) {
 int i;
 for ( i = 0; i < MAX_SZ_MSG; i++)
  msg[i] = '\0';
 
}

  • Do you mean to say your filters are no more working?

    Regards,

    Gautam

  • Dear Gautam,

    My problem is that the digital readings shown on the hyperterminal are same for both when the filter is on and when filter is off. These readings used to show proper change with and without filter before. But suddenly there are not showing any change. I mean I am not able to see the raw data as well as when I give external power, it does not change according to the given voltage. please help.

    The sample readings are:

  • Hi,

    There are few exercises I would recommend you to carry out:

    1. Use "adc_soc" sample code and check all the adc channels

    2. Change your workspace, create a new project and carry out the step 1

    7633.adc_soc.zip

    I've attached the project. Do inform your observations.

    Regards,

    Gautam

  • Hi Irfan!

    irfan rashed said:

     Initially it was fine and I have seen the difference between with and without filter. But now both the values are same. I don't know why. 

    I understand about futility of my answer, but at least it could not happen by itself without your intervention.

    Regards,

    Igor

  • Dear Sir,

    Yes I know something went wrong by me but I literally do not know what.

    It is that the pins are damaged in the worst case?

    Please let me know sir. I am worried.

    Regards,

    Irfan.

  • Hi gautam,

    Ok.  I will check. Just to verify, I wanted to ask that in the worst case, if nothing works, does it mean that the adc pins are damaged?

    Please let me know sir.

    Regards,

    Irfan.

  • hELLO GAUTAM,

    I tried everything you mentioned but nothing works.

    Still confused whats wrong. Is there anything wrong in code or the board?

    Regards,

    Irfan.

  • Feel your pain.   When all else fails - time for basics.

    Suggest that you:

    a) find or create a "clean"  DC Voltage - w/in the center of your ADC's voltage rating. 

    b) Apply this voltage to 2 separate - ideally different (than you past used) ADC channels.  (eliminate channel failure this way)

    c) Temporarily remove any "filtering" attempts - run a series of conversions - note the results

    Goal of this test is to verify that your set-up/config of ADC is proper.  A very consistent series of readings should result if your source signal is "clean" and your ADC set-up is correct.  This is mandatory - for anything else you do to have a chance to succeed.

    I'm concerned why you felt the need to "filter" - and you report "garbage."   This should be investigated - may be undue signal source variation or some incorrect ADC set-up or handling.

    KISS - start simple - make the most basic function work - and only then ADD - as/if required...  Take NO shortcuts...

    Bon chance - mon ami...

  • If none of the ADCs seem to respond then :

    1. Controllers has gone bad (Check for the overheating of the controller)

    2. ADC might have got damaged (If controller is not overheating and the supply for controller is maintained at 3.3V)

    Regards,

    Gautam