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.

TM4C123 - ADC Oversampling

Other Parts Discussed in Thread: TM4C123GH6PM

Hello I am Sky.

I am struggling with implementation of a ADC oversampling issue in TM4C123.

When I am following a document named "ADC Oversampling Techniques for Stellaris® Family Microcontrollers" (spma001a.pdf),

I should add code on two parts: 1) setting part, 2) data acquisition part

1) In setting

//
// Initialize the ADC to oversample channel 1 by 8x using sequencer 0.
// Sequencer will be triggered by one of the general-purpose timers.
//
ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_TIMER, 0);
ADCSoftwareOversampleConfigure(ADC_BASE, 0, 8);
ADCSoftwareOversampleStepConfigure(ADC_BASE, 0, 0, (ADC_CTL_CH1 \
| ADC_CTL_IE | ADC_CTL_END));

2) In data acqusition part,

//
// Clear the ADC interrupt
//
ADCIntClear(ADC_BASE, 0);
//
// Get averaged data from the ADC
//
lStatus = ADCSoftwareOversampleDataGet(ADC_BASE, 0,&g_ulAverage);

Then, here is my problem.

When I refer to the datasheet of TM4C123GH6PM (tm4c123gh6pm.pdf),

ADCSAC register represents a status of oversampling setting.

I guess that it should return 0x3 as I set 8x oversampling, but it returns always 0 as belows:

ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_TIMER, 0);
ADCSoftwareOversampleConfigure(ADC0_BASE, 0, 8);
ADCSoftwareOversampleStepConfigure(ADC0_BASE, 0, 0, (ADC_CTL_CH1 | ADC_CTL_IE | ADC_CTL_END));
uint32_t val = HWREG(ADC0_BASE + ADC_O_SAC); //it returns 0!!!!!

Is there any additional settings to use ADC oversampling?

Please answer my question.

Thanks in advance.

+ Additionally. my desired specification is 

1) Read two ADC channel concurrently (ADC0, ADC1)

2) 1Mhz sampling rate / 8 samples = 125khz sampling rate

-Sky

  • Hello Sky,

    You are using software over sampling method. You need to use the Hardware over sampling to set ADC_SAC register.

    ADCHardwareOversampleConfigure(ADC_BASE, 8);
  • Tremendous Thanks to Amit Ashara!

    I was confused between software oversampling and hardware sampling.
    Hardware Oversampling command solves my problem perfectly.

    Here is full of my code.

    uint32_t ADCSequenceNumber = 3;
    uint16_t ADCSamplingRateKhz = 1000;
    uint32_t ADCNumOfSamples = 4096;
    uint32_t ADCOverSamplingNumber = 8;
    uint32_t data1[4096];
    uint32_t data2[4096];

    //Initialize ADC
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); //Pin for ADC input
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); //ADC peripheral
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1); //ADC peripheral
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

    //Pins used for ADC channels
    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0);
    ADCSequenceConfigure(ADC0_BASE, ADCSequenceNumber, ADC_TRIGGER_TIMER, 0); //sequencer 0
    ADCSequenceConfigure(ADC1_BASE, ADCSequenceNumber, ADC_TRIGGER_TIMER, 0); //sequencer 0

    ADCSequenceStepConfigure(ADC0_BASE, ADCSequenceNumber, 0, ADC_CTL_D | ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceStepConfigure(ADC1_BASE, ADCSequenceNumber, 0, ADC_CTL_D | ADC_CTL_CH2 | ADC_CTL_IE | ADC_CTL_END);
    ADCHardwareOversampleConfigure(ADC0_BASE, ADCOverSamplingNumber);
    ADCHardwareOversampleConfigure(ADC1_BASE, ADCOverSamplingNumber);

    uint32_t freq = SysCtlClockGet();
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet()/(1000*ADCSamplingRateKhz));
    TimerEnable(TIMER0_BASE, TIMER_A);
    TimerControlTrigger(TIMER0_BASE,TIMER_A,true);

    ADCSequenceEnable(ADC0_BASE, ADCSequenceNumber);
    ADCSequenceEnable(ADC1_BASE, ADCSequenceNumber);
    ADCIntEnable(ADC0_BASE, ADCSequenceNumber);
    ADCIntEnable(ADC1_BASE, ADCSequenceNumber);

    ADCIntClear(ADC0_BASE, ADCSequenceNumber);
    ADCIntClear(ADC1_BASE, ADCSequenceNumber);
    ADCIntEnable(ADC0_BASE, ADCSequenceNumber);
    ADCIntEnable(ADC1_BASE, ADCSequenceNumber);

    uint32_t ADCCurrentIndex = 0;

    for(ADCCurrentIndex=0; ADCCurrentIndex < ADCNumOfSamples; ADCCurrentIndex++)
    {
    ADCIntClear(ADC0_BASE, ADCSequenceNumber);
    ADCIntClear(ADC1_BASE, ADCSequenceNumber);
    while(!ADCIntStatus(ADC0_BASE, ADCSequenceNumber, 0));
    while(!ADCIntStatus(ADC1_BASE, ADCSequenceNumber, 0));

    data1[ADCCurrentIndex] = HWREG(ADC0_BASE + ADC_O_SSFIFO3);
    data2[ADCCurrentIndex] = HWREG(ADC1_BASE + ADC_O_SSFIFO3);
    }

    ADCIntDisable(ADC0_BASE, ADCSequenceNumber);
    ADCIntDisable(ADC1_BASE, ADCSequenceNumber);


    -Sky
  • Hello Sky

    Glad that it is working correctly for you. By the way there is a known issue on the software sampling method when using multiple ADCs. This is planned to be fixed in the next TivaWare release.