Hi,
I am facing an issue with the Tiva TM4C123AE6PM ADC.
I have 8 different analog channels coming into the ADC.
Here is my configuration of the ADC and associated GPIO.
void InitGPIOD(void) { // Initialise all the inputs in GPIO Port D GPIO_PORTD_LOCK_R = 0x4C4F434B; //Enable writing to GPIOCR registers GPIO_PORTD_CR_R = 0x000000FF; GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); //Initialise the above input pins as ADC inputs on the GPIO D GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0); GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_1); GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_2); GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_3); }
void InitGPIOE(void) { // Initialise all the inputs in GPIO Port E // Pin 0 - MR Sensor 4 Input // Pin 1 - MR Sensor 3 Input // Pin 2 - MR Sensor 2 Input // Pin 3 - MR Sensor 1 Input // Pin 4 - 1V65 reference input GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4); //Initialise the above input pins as ADC inputs on the GPIO D GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_4); }
void InitADC(void) { // Enable the clock to the ADC 0 peripheral SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); SysCtlDelay(10); // COnfigure the ADC to use the internal oscillator for clocking ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 64); // Set the reference of the ADC to 3V ADCReferenceSet(ADC0_BASE, ADC_REF_EXT_3V); // Enable hardware oversampling for the ADC to increase accuracy // ADCHardwareOversampleConfigure(ADC0_BASE, 1); // Now start configuration of Sequence 0 to Read all the 8 MR sensors in one conversion // Disable the sequence first ADCSequenceDisable(ADC0_BASE, SQNC_0); // Configure the sequence to run at a processor trigger with the highest priority ADCSequenceConfigure(ADC0_BASE, SQNC_0, ADC_TRIGGER_PROCESSOR, PRIORITY_1); // Now configure all the steps of the sequencer to read from different channels // For the last channel, enable the interrupt for the channel and tell the ADC to end conversion ADCSequenceStepConfigure(ADC0_BASE, SQNC_0, STEP_0, ADC_CTL_CH0); ADCSequenceStepConfigure(ADC0_BASE, SQNC_0, STEP_1, ADC_CTL_CH1); ADCSequenceStepConfigure(ADC0_BASE, SQNC_0, STEP_2, ADC_CTL_CH2); ADCSequenceStepConfigure(ADC0_BASE, SQNC_0, STEP_3, ADC_CTL_CH3 ); ADCSequenceStepConfigure(ADC0_BASE, SQNC_0, STEP_4, ADC_CTL_CH4); ADCSequenceStepConfigure(ADC0_BASE, SQNC_0, STEP_5, ADC_CTL_CH5); ADCSequenceStepConfigure(ADC0_BASE, SQNC_0, STEP_6, ADC_CTL_CH6); ADCSequenceStepConfigure(ADC0_BASE, SQNC_0, STEP_7, ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END); // Enable conversion complete interrupt for the ADC ADCIntEnable(ADC0_BASE, SQNC_0); ADCIntRegister(ADC0_BASE, SQNC_0, ISR_ADC); // Finally Enable the sequence ADCSequenceEnable(ADC0_BASE, SQNC_0); }
Then I have the following ISR for the ADC.
void ISR_ADC(void) { ADC0_ISC_R |= 0x01; //write one to clear the interrupt g_stApolloParms.m_etConversionStatusMR = COMPLETE; }
The ADC is triggered in the while 1 loop.
while(1) { static U32 ulProcessStart = RESET; ADC_PARMS *stADC_Parms = &(g_stApolloParms.m_stADC_Parms); if(ulProcessStart == RESET) { ulProcessStart = SET; ADCProcessorTrigger(ADC0_BASE, SQNC_0); } else { if(g_stApolloParms.m_etConversionStatusMR == COMPLETE) { g_stApolloParms.m_etConversionStatusMR = INCOMPLETE; ulProcessStart = RESET; ADCSequenceDataGet(ADC0_BASE, SQNC_0, stADC_Parms->m_ulADC_RawValue); } } }
Following is what happens.
All ADC channels except channel 2 are at 0V. Channel 2 is at 1.2V (approx).
Conversion 1:
Conversion 2:
And so on...
The 1455 value is correct. The values above 4000 are certainly not correct.
The 1455 value is on channel 2. It flows into any channel. Also the other values randomly change the channels. What am I missing here, or doing something wrong?
Thanks in advance!
Makarand Deshmukh