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.

CCS/TM4C123GH6PM: Multiple channel ADC

Part Number: TM4C123GH6PM

Tool/software: Code Composer Studio

Hi,

I am having difficulties configuring the ADC, Here is my code:

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/tm4c123gh6pm.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/timer.h"
#include "driverlib/adc.h"

int FsSensor = 125000;
int FsPotA = 40000;
int FsPotB = 20000;

volatile float Pot_A;
volatile float Pot_B;
const float conv = 3.3/4096; //0 - 3.3

volatile uint32_t avgTemp;
volatile uint32_t TempC;
volatile uint32_t TempF;

void ObtMuestra(void);

void TimerTemp(){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_A_PERIODIC);
    TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet()/FsSensor - 1); //40MHz / 125KHz
    TimerControlTrigger(TIMER0_BASE, TIMER_A, true);

    TimerEnable(TIMER0_BASE, TIMER_A);
}

void TimerPot(){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);

    TimerPot1();
    TimerPot2();
}

void TimerPot1(){
    TimerConfigure(TIMER1_BASE, TIMER_CFG_A_PERIODIC);
    TimerLoadSet(TIMER1_BASE, TIMER_A, SysCtlClockGet()/FsPotA - 1); //40MHz / 40KHz
    TimerControlTrigger(TIMER1_BASE, TIMER_A, true);

    TimerEnable(TIMER1_BASE, TIMER_A);
}

void TimerPot2(){
    TimerConfigure(TIMER1_BASE, TIMER_CFG_B_PERIODIC);
    TimerLoadSet(TIMER1_BASE, TIMER_B, SysCtlClockGet()/FsPotB - 1); //40MHz / 20KHz
    TimerControlTrigger(TIMER1_BASE, TIMER_B, true);

    TimerEnable(TIMER1_BASE, TIMER_B);
}

//ADC Config
void ADCconfig(){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_1); //CH2
    GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_2); //CH1

    ADCSequenceConfigure(ADC0_BASE, 0,ADC_TRIGGER_TIMER,0);

    ADCSequenceStepConfigure(ADC0_BASE,0,0,ADC_CTL_CH2); //PotA
    ADCSequenceStepConfigure(ADC0_BASE,0,1,ADC_CTL_CH2); //PotA
    ADCSequenceStepConfigure(ADC0_BASE,0,2,ADC_CTL_CH1); //PotB
    ADCSequenceStepConfigure(ADC0_BASE,0,3,ADC_CTL_CH1); //PotB
    ADCSequenceStepConfigure(ADC0_BASE,0,4,ADC_CTL_TS);  //Sensor
    ADCSequenceStepConfigure(ADC0_BASE,0,5,ADC_CTL_TS);  //Sensor
    ADCSequenceStepConfigure(ADC0_BASE,0,6,ADC_CTL_TS);  //Sensor
    ADCSequenceStepConfigure(ADC0_BASE,0,7,ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END);  //Sensor

    ADCSequenceEnable(ADC0_BASE,0);

    ADCIntEnable(ADC0_BASE,0);

    ADCIntRegister(ADC0_BASE,0,ObtMuestra);

    IntEnable(INT_ADC0SS0);
    IntMasterEnable();
}

int main(void){

    SysCtlClockSet(SYSCTL_XTAL_16MHZ|SYSCTL_SYSDIV_5); //40MHz

    TimerTemp();
    TimerPot();

    ADCconfig();
}

void ObtMuestra(){
    unsigned long ulADC0Value[8];
    ADCIntClear(ADC0_BASE,0); 

    ADCSequenceDataGet(ADC0_BASE,0,ulADC0Value);

    Pot_A = conv*(ulADC0Value[0]+ulADC0Value[1])/2;
    Pot_B = conv*(ulADC0Value[2]+ulADC0Value[3])/2;

    avgTemp = (ulADC0Value[4] + ulADC0Value[5] + ulADC0Value[6] + ulADC0Value[7])/4;
    TempC = (1475 - (2475*avgTemp)/4096)/10;
    TempF = (9*TempC)/5 + 32;

}

I need 2 samples for each Potentiometer and 4 samples for temperature sensor, my issue is in the DataGet for the variable ulADC0Value:

The two Pot be in 0v and the samples of the sensor was 2000 (for example), so the array in the first interrupt was: [0,0,0,0,2000,2000,2000,2000], when I resume for the next interrupt I get the values move in the array like: [2000,2000,0,0,0,0,2000,2000], in every interrupt I get the values move in the array, so the convertions for the values of Pot_A, Pot_B, TempC and TempF change radically. What's going on?

I thought the [0] and [1] of the array was assigned to the values in channel 2. [2] and [3] to channel 1, and [4] ... [7] for the sensor.

  • Each ADC conversion takes 1uS. You are doing 8 conversions, so 8us. You need some time to read the results, but are triggering the ADC again at 125KHz or exactly every 8uS. So you are trying to read the FIFO while the next conversion has already started. Reduce your timer frequency or reduce the number of conversions in the sequence.