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.

EK-TM4C1294XL: ADC differential mode

Part Number: EK-TM4C1294XL


Hi,

I had set up my ADC in single-ended operation and it gave me accurate readings.

However when I changed it to differential mode I am getting values which do not make much sense. I followed the differential example, I am not sure what is happening; when I tie PE2 to ground and PE3 to 3.3V I get an ADC reading of 4095 which is correct. However if I tie both PE2 and PE3 to ground I get a reading of about 1900 and it jumps around a lot in this range +/- a few hundred readings. In single ended operation when I would tie PE3 to ground I would get the expected reading of 0 with a peak of 4 every once in a while.

I have a current sensor (HXS 20-NP by LEM) which gives a voltage output, the sensor has a reference voltage, I am trying to measure the difference between the reference voltage (around 2.5V) to the voltage output. if there is no current the sensor output and reference value give me me the same value of  2.5V. I was expecting when PE2 is tied to the voltage reference pin and PE3 is tied to the Vout pin, with no current passing through, I would get a 0 value for my ADC, however, I am getting the same type of values when both pins are tied to ground.

Here is my code, any help would be appreciated.

void ConfigureADC(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    GPIOPinTypeADC(GPIO_PORTE_BASE, (GPIO_PIN_3 | GPIO_PIN_2));
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0))
    {
    }
    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); 
    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, (ADC_CTL_D | ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END));
    ADCSequenceEnable(ADC0_BASE, 3);
    ADCIntClear(ADC0_BASE, 3);
}
void ADCGetValue (void)
{
    uint32_t ADCValues[1];
    uint32_t VoltageValue = 0;
    uint32_t AmperageValue = 0;
    TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    ADCProcessorTrigger(ADC0_BASE, 3);
    while(!ADCIntStatus(ADC0_BASE, 3, false))
    {
    }
    ADCIntClear(ADC0_BASE, 3);
    ADCSequenceDataGet(ADC0_BASE, 3, ADCValues);
    VoltageValue = (uint32_t)((float)(ADCValues[0]*3300)/4096);
    AmperageValue = (10000*((uint32_t)(ADCValues[0] - 3103)))/775;
    UARTprintf("ADC Value = %d\n", ADCValues[0]);
    UARTprintf("Voltage Value (mV): %3d\n", VoltageValue);
    UARTprintf("Current Value (mA): %3d\n", AmperageValue);
//    SysCtlDelay(10000000);
}

void ADCTimerConfig (void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
    TimerClockSourceSet(TIMER1_BASE, TIMER_CLOCK_SYSTEM);
    TimerLoadSet(TIMER1_BASE, TIMER_A, g_ui32SysClock);
    IntRegister(INT_TIMER1A, ADCGetValue);
    IntPrioritySet(INT_TIMER1A, 2); // change priorities
    TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    IntEnable(INT_TIMER1A);
    TimerEnable(TIMER1_BASE, TIMER_A);



}

  • One more observation, when in differential operation with PE2 tied to ground and PE3 tied to sensor output, with no current passing through the sensor, I am seeing 2.9V, where it is actually about 2.5V. When I reprogram my MCU with the single ended operation program, it is reading 2.5V, which is what it is supposed to read.
  • Hi,

    What are you driving on Vref+, Vref-, VIN+ and VIN-. What is the expected ADC value?

    Please make sure your two inputs are indeed in "differential mode" not two inputs referenced to the ground. Please refer to the ADC datasheet for details. Below is an excerpt.

    The voltage sampled in differential mode is the difference between the odd and even channels:
    ■ Input Positive Voltage: VIN+ = VIN_EVEN (even channel)
    ■ Input Negative Voltage: VIN- = VIN_ODD (odd channel)
    The input differential voltage is defined as: VIND = VIN+ - VIN-, therefore:
    ■ If VIND = 0, then the conversion result = 0x800
    ■ If VIND > 0, then the conversion result > 0x800 (range is 0x800–0xFFF)
    ■ If VIND < 0, then the conversion result < 0x800 (range is 0–0x800)
    When using differential sampling, the following definitions are relevant:
    ■ Input Common Mode Voltage: VINCM = (VIN+ + VIN-) / 2
    ■ Reference Positive Voltage: VREFP
    ■ Reference Negative Voltage: VREFN
    ■ Reference Differential Voltage: VREFD = VREFP - VREFN
    ■ Reference Common Mode Voltage: VREFCM = (VREFP + VREFN) / 2
    The following conditions provide optimal results in differential mode:
    ■ Both VIN_EVEN and VIN_ODD must be in the range of (VREFP to VREFN) for a valid conversion
    result
    ■ The maximum possible differential input swing, or the maximum differential range, is: -VREFDto
    +VREFD, so the maximum peak-to-peak input differential signal is (+VREFD - -VREFD) = 2 *
    VREFD= 2 * (VREFP - VREFN)
  • My bad, I should have read the data sheet more closely