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.

A problem with TMS320f28335 Internal ADC interfacing

Other Parts Discussed in Thread: TMS320F28335

Hi,

I am  facing a problem with TMS320f28335 Internal ADC interfacing. When we are injecting AC signal (Voltage) on pin 47 then the value of ADC output (ac current , injected on pin 48) is increasing up to 2%.

Input Voltage (pin 47): 2.6Vpp

Input current (pin 48) :  0.2789 Vpp

 

Case-1:

Input current (pin 48) :  0.2789 Vpp

And then with Input Voltage (pin 47): 2.6Vpp ,read value of ADC output at pin 48

 

 

Case-2:

Input current (pin 48) :  0.2789 Vpp

And without any  Input Voltage (pin 47): 0V  , read value of ADC output at pin 48

 

In both cases , output is varying up to 2%.

 

Please suggest me any solution.

  • Hi Anil,
    Can you please confirm that none of the voltages on any ADC input exceed VDDA by more than 0.3V or VSSA by -0.3V? Even overshoot/undershoot? Can you also ensure the AC signals are not injecting noise onto the REFM/REFP pins?
    Regards,
    Joe
  • Hi Joe,

    Thank you very much for reply.

    Before injecting the current or voltage to ADC channel , I am clamping the signal from 1.5 V DC. . Current and voltage are injecting from ideal source OMICRON. same results are verified from function generator also. So there is no any possibility of noise. AC Voltage label is also greater then zero and less then 3V.  So there is no any possibility of overshoot/undershoot.

    Also verified that AC signals are not injecting noise onto the REFM/REFP pins


    Regards,
    Joe

  • Anil,
    Is there error measured by an ADC conversion or at the pin with a DMM?

    If DMM are there any conversions done by the ADC on channel B1 or B2 prior or during the measurements?

    Since these channels share the same S/H cap we will see some charge/RC effects if they are sampled one after the other.

    If this is DMM on a pin and there is no sampling, that shouldn't happen if pin voltages don't violate the DS.

    Matt
  • Dear Matt,

    I am attaching source code of ADC initialization. I am running processor on 100M Hz.

    // TI File $Revision: 1.1 $
    // Checkin $Date: 2011/11/29 10:45:06 $
    //###########################################################################
    //
    // FILE: DSP2833x_Adc.c
    //
    // TITLE: DSP2833x ADC Initialization & Support Functions.
    //
    //###########################################################################
    // $TI Release: 2833x/2823x Header Files V1.32 $
    // $Release Date: June 28, 2010 $
    //###########################################################################

    #include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
    #include "DSP2833x_Examples.h" // DSP2833x Examples Include File

    #define ADC_usDELAY 5000L
    #define ADC_CKPS 0x1 // ADC module clock = HSPCLK/2*ADC_CKPS = 25.0MHz/(1*2) = 12.5MHz
    #define ADC_SHCLK 0xf // S/H width in ADC module periods = 16 ADC clocks
    void WaitForADC(Uint16 count);

    //---------------------------------------------------------------------------
    // InitAdc:
    //---------------------------------------------------------------------------
    // This function initializes ADC to a known state.
    //
    void InitAdc(void)
    {
    extern void DSP28x_usDelay(Uint32 Count);

    // To powerup the ADC the ADCENCLK bit should be set first to enable
    // clocks, followed by powering up the bandgap and reference circuitry.
    // After a 5ms delay the rest of the ADC can be powered up. After ADC
    // powerup, another 20us delay is required before performing the first
    // ADC conversion. Please note that for the delay function below to
    // operate correctly the CPU_CLOCK_SPEED define statement in the
    // DSP28_Examples.h file must contain the correct CPU clock period in
    // nanoseconds. For example:

    AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3; // Power up bandgap/reference circuitry
    WaitForADC (0xffff);
    WaitForADC (0xffff);
    WaitForADC (0xffff);
    WaitForADC (0xffff);

    // DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC
    AdcRegs.ADCTRL3.bit.ADCPWDN = 1; // Power up rest of ADC
    WaitForADC (0xfff0);
    WaitForADC (0xffff);
    WaitForADC (0xffff);

    // DELAY_US(ADC_usDELAY2); // Delay after powering up ADC


    // Specific ADC setup for this example:
    AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; // Sequential mode: Sample rate = 1/[(2+ACQ_PS)*ADC clock in ns]
    WaitForADC (0xffff);
    // = 1/(3*40ns) =8.3MHz
    // If Simultaneous mode enabled: Sample rate = 1/[(3+ACQ_PS)*ADC clock in ns]

    AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 0 Cascaded mode two 8 Sequencer
    WaitForADC (0xffff);

    AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Setup Start Stop mode not continuous run
    WaitForADC (0xffff);

    AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0; // Disable Sequencer override feature
    WaitForADC (0xffff);
    AdcRegs.ADCTRL1.bit.CPS=1; // ADCCLK =HSPCLK /2 after that ADCTRL3 will decide the remaining prescalling
    WaitForADC (0xffff);

    AdcRegs.ADCTRL2.all=0x0000;

    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //Selecting the Result in ADCRESULT register
    AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;
    AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;
    AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;

    AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4;
    AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5;
    AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6;
    AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7;

    AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x0; //Selecting the Result in ADCRESULT register
    AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x1;
    AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0x2;
    AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x3;

    AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x4;
    AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0x5;
    AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0x6;
    AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0x7;

    //AdcRegs.ADCCHSELSEQ3.all = 0xBA98;
    // AdcRegs.ADCCHSELSEQ4.all = 0xFEDC;

    AdcRegs.ADCMAXCONV.all = 0x000F; // 8 double conversion convert and store in 8 results registers

    AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS; //CLOCK : HSPCLK /8
    WaitForADC (0xffff);

    AdcRegs.ADCTRL3.bit.SMODE_SEL=1; // Setup Simultaneous Sampling Mode

    // Start SEQ1 & SEQ2
    AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // SOC enable
    AdcRegs.ADCTRL2.bit.SOC_SEQ2 = 1; // SOC enable
    }

    void WaitForADC(Uint16 count)
    {
    while((count--));
    }

    //===========================================================================
    // End of file.
    //===========================================================================
    Answer of your Questions:

    Is there error measured by an ADC conversion or at the pin with a DMM? : Error is measured final after ADC conversion.

    If DMM are there any conversions done by the ADC on channel B1 or B2 prior or during the measurements?

    #define CURR_R_PHASE_LOW AdcRegs.ADCRESULT1
    #define VOLT_Y_PHASE AdcRegs.ADCRESULT3
    #define CURR_Y_PHASE_LOW AdcRegs.ADCRESULT5
    #define CURR_B_PHASE_LOW AdcRegs.ADCRESULT7
    #define CURR_N_PHASE_HIGH AdcRegs.ADCRESULT11
    #define CURR_N_PHASE_LOW AdcRegs.ADCRESULT10
    #define CURR_REF_PHASE_HIGH AdcRegs.ADCRESULT13
    #define CURR_REF_PHASE_LOW AdcRegs.ADCRESULT15

    // This task is polling in each 312.5 micro seconds
    void ADC_Reading_Task_312us(void)
    {
    g_iADCBuffer[ADC_CRNT_R_H]=((CURR_R_PHASE_HIGH)>>4);
    g_iADCBuffer[ADC_CRNT_R_L]=((CURR_R_PHASE_LOW)>>4);
    g_iADCBuffer[ADC_CRNT_Y_H]=((CURR_Y_PHASE_HIGH)>>4);
    g_iADCBuffer[ADC_CRNT_Y_L]=((CURR_Y_PHASE_LOW)>>4);
    g_iADCBuffer[ADC_CRNT_B_H]=((CURR_B_PHASE_HIGH)>>4);
    g_iADCBuffer[ADC_CRNT_B_L]=((CURR_B_PHASE_LOW)>>4);
    g_iADCBuffer[ADC_VOLT_R]=((VOLT_R_PHASE)>>4);
    g_iADCBuffer[ADC_VOLT_Y]=((VOLT_Y_PHASE)>>4);
    g_iADCBuffer[ADC_VOLT_B]=((VOLT_B_PHASE)>>4);

    AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // Start Of Conversion
    AdcRegs.ADCTRL2.bit.SOC_SEQ2 = 1; // Start Of Conversion
    }

    Since these channels share the same S/H cap we will see some charge/RC effects if they are sampled one after the other.
    : What should be solution of this problem.?

    Thanks,
    Anil Garg
  • Anil,

    Looking through your code snippet, it appears you are running in simultaneous sampling mode and stepping through A0/B0 => A1/B1 => A2/B2, etc.  Can you specify what the value of HISPCLK prescaler is?  At SYSCLK=100MHz, ADCLKPS=1, and CPS=1, any value of HISPCLK should be valid, but if it is 0, I want to make sure you review the device erratum entitled ADC: Simultaneous Sampling Latency.  Also if the above is true, then as Matt pointed out there could be some residual effect from B1 on the sampling cap when you sample B2 so you may need to increase the sample window to allow the cap to properly stabilize.  At least you could try this as a debug experiment.  Another good experiment would be to see if the presence of the AC signal on B1 changes the conversion results of B2 even when B1 is not sampled.  If so then we are probably looking at some type of cross-talk or coupling and will need to debug that further.

    Regards,

    Joe

  • Dear  All,

    Could you kindly tell me how the ADC analog input signal can be conditioned for TMS320F28335? I am quite new in TI.

    In case of my project I have 2 DC voltage and current component and one 3.3v reference voltage. 

    Is it  MUX type input ? How to process with buffer?

    How do you defined ...?

    g_iADCBuffer[ADC_CRNT_R_H]=((CURR_R_PHASE_HIGH)>>4);
    g_iADCBuffer[ADC_CRNT_R_L]=((CURR_R_PHASE_LOW)>>4)

    Is there any way to   conditioning input signal in this ATmel style?

    / Mux input
    int16_t adc_read(uint8_t mux)
    {
    #if defined(__AVR_AT90USB162__)
    return 0;
    #else
    uint8_t low;

    ADCSRA = (1<<ADEN) | ADC_PRESCALER; // enable ADC
    ADCSRB = (1<<ADHSM) | (mux & 0x20); // high speed mode
    ADMUX = aref | (mux & 0x1F); // configure mux input
    ADCSRA = (1<<ADEN) | ADC_PRESCALER | (1<<ADSC); // start the conversion
    while (ADCSRA & (1<<ADSC)) ; // wait for result
    low = ADCL; // must read LSB first
    return (ADCH << 8) | low; // must read MSB only once!
    #endif
    }

    Kindly help me.

  • Hi MD,

    This post is pretty old.  You will have better results starting a new post where you detail the issue that you have, and then link to any other posts with similar issues, but that may not completely resolve your issue.

  • Thank you sir.
    I will do so.