Hi,
I'm doing some tests with EK-TM4C1294XL evaluation board using its ADC but the captured samples are too inaccurate, as you can see in the histogram bellow.
I would like to know what are your opinions about the possible reasons to this happening.
Bellow you can see the code I'm using and other related files.
The code is bellow :
#include <stdint.h> #include <stdbool.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/gpio.h" #include "driverlib/adc.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/timer.h" #include "driverlib/uart.h" #include "utils/uartstdio.h" void adc_init(void); void Timer0ISR(void); void ConfigureTimer(void); /*keep the value of clock */ uint32_t g_ui32SysClock; uint32_t adc0_values[10000]; typedef enum my_states{ SAMPLING, DISABLE_SAMPLING, END_FLAG, IDLE }State_t; int main(void) { /* control variables */ State_t current_state = SAMPLING; uint32_t amostra_adc_0[1]; uint32_t counter = 0; /* Set the clocking to run at 120MHz */ g_ui32SysClock= SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); adc_init(); ConfigureTimer(); while(1){ switch(current_state){ case SAMPLING: while(!ADCIntStatus(ADC0_BASE,3,false)); /* Cleaning after aquisition*/ ADCIntClear(ADC0_BASE,3); /* Taking the samples*/ ADCSequenceDataGet(ADC0_BASE, 3,amostra_adc_0); /* Cleaning the interruption flag*/ ADCIntClear(ADC0_BASE,3); //passing values through the variables adc0_values[counter] = amostra_adc_0[0]; counter++; if(counter == 10000){ current_state = DISABLE_SAMPLING; } else{ current_state = SAMPLING; } break; case DISABLE_SAMPLING: //the problem is here!!!! SysCtlPeripheralDisable(SYSCTL_PERIPH_TIMER0); current_state = END_FLAG; break; case END_FLAG: //here I'm turning on a led to flag the end SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1); GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, GPIO_PIN_1); current_state = IDLE; break; case IDLE: break; } } return 0; } void adc_init(void){ /* Enabling the Peripheral ADC0 */ SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); /* Enabling Port E in order to read the values in ADC0 */ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); /* Selecting the pins to read ADC0 Values */ GPIOPinTypeADC(GPIO_PORTE_BASE, (GPIO_PIN_0)); /* Configuring Sample Sequence 3 in ADC0 */ ADCSequenceConfigure(ADC0_BASE,3, ADC_TRIGGER_PROCESSOR, 0); /*Configure steps in ADC0*/ ADCSequenceStepConfigure(ADC0_BASE, 3, 0, (ADC_CTL_CH3 | ADC_CTL_IE | ADC_CTL_END)); /*END*/ /* Enable the sample sequence in ADC0 */ ADCSequenceEnable(ADC0_BASE, 3); /*cleaning the interrupt flag */ ADCIntClear(ADC0_BASE, 3); } void Timer0ISR(void){ /* cleaning the timer interruptions for timer 0 module in full-with mode */ TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); ADCProcessorTrigger(ADC0_BASE,3); } void ConfigureTimer(void){ /* enabling the timer 0 peripheral */ SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); /* Allow the use of the processor interrupts */ IntMasterEnable(); /* configurating the TIMER to use a 32bit periodic timer */ TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); /* setting the timer load value */ /* we're using only timer A cause we want a 32 bit timer */ /* here we've 1ms */ TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock/1000); /* here we're setting the ISR to timer 0 */ TimerIntRegister(TIMER0_BASE,TIMER_A,Timer0ISR); /* allowing interruptions for timer 0 */ /* we use only timera because we're using full-with mode */ IntEnable(INT_TIMER0A); /* enabling the interruptions for timer0 in full-with mode */ /* It appears when timeout situation is got */ /* again, using timer A because we're using full-with mode */ TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); /* Enabling Timer */ TimerEnable(TIMER0_BASE, TIMER_A); }