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.

ADC failure to work

Other Parts Discussed in Thread: TM4C123GH6PM

Hi, basically for my program it is to receive input from voltage supply (3.0V) for ADC test. UARTBufferFlag is used for further uses but right now I need to get my ADC to work. 

This is my main: 

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/adc.h"
#include "driverlib/uart.h"
#include "driverlib/interrupt.h"
#include "utils/ustdlib.h"
#include "driverlib/timer.h"
#include "UART.h"
#include "ADC.h"
#include "Timer.h"

int UARTBufferFlag = 0; // UARTBufferFlag intialise to '0' at start

/*void delay(int count){
int i, j;
for (i=0;i<count;i++)
{ for (j=0;j<1000;j++);}
}
*/

void UARTIntHandler(void)
{
uint32_t ui32Status;
ui32Status = UARTIntStatus(UART0_BASE, true); //get interrupt status
UARTIntClear(UART0_BASE, ui32Status); //clear the asserted interrupts

while(UARTCharsAvail(UART0_BASE)) //loop while there are chars
{
UARTCharPutNonBlocking(UART0_BASE, UARTCharGetNonBlocking(UART0_BASE)); //echo character
SysCtlDelay(SysCtlClockGet() / (1000 * 3)); //delay ~1 msec
}
}

int main(void) {

SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_5);
GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_5);
//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);

Timer_Init(); // initialization of Timer
ADC_Init(); // intialization of ADC
UART_Init(); // initialization of UART

while (1)
{
if (UARTBufferFlag){// if UARTBufferFlag true
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
send_uart(); // print converted ADC results through UART
UARTBufferFlag= 0; // clear UARTBufferFlag
}
//delay(100);
}

}

// end 

This is my ADC.c 

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/adc.h"
#include "ADC.h"

void ADC_Init (void) //initialization of ADC
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);

ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH11);
ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH11);
ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH11);
ADCSequenceStepConfigure(ADC0_BASE,1,3,ADC_CTL_CH11|ADC_CTL_IE|ADC_CTL_END);

ADCSequenceEnable(ADC0_BASE, 1);
}

void ADCIntHandler (void) //ADC conversion
{
ADCIntClear(ADC0_BASE, 1);
ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
ui32ADC0Avg = (ui32ADC0Value[0] + ui32ADC0Value[1] + ui32ADC0Value[2] + ui32ADC0Value[3] + 2)/4;
UARTBufferFlag = 1;
}

// end 

This is my timer.c 

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

void Timer_Init (void) // initialization of Timer
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
ui32Period = (SysCtlClockGet() / 10) / 2;
TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period -1);
IntEnable(INT_TIMER0A);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
IntMasterEnable();
TimerEnable(TIMER0_BASE, TIMER_A);

}

void Timer0IntHandler (void) // clear interrupt and start ADC conversion
{
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
ADCProcessorTrigger(ADC0_BASE, 1);

}

// end 

I have even set a breakpoint on ADC.c on the "ADCIntClear(ADC0_BASE, 1);" line to test whether it will jump to the line. 

  • Domenic Pang said:
    I have even set a breakpoint on ADC.c on the "ADCIntClear(ADC0_BASE, 1);" line to test whether it will jump to the line. 

    Indeed you've done that - yet we are "left to guess" that your breakpoint was not, "hit!"   Is that wise?

    You provide the key/critical/extensive issue description, "Failure to Work!"   How does that help those here - assist?   Only those "paid" are likely to "wade thru" your long code listing - with so little guidance/assistance - from you!   (that's perhaps the "real" failure - not so much the ADC)

    Did your code hit (any) breakpoints?   Where/when did it "miss?"   (Some) detail is required - is it not?  

  • Hello Domenic,

    It seems that the IntEnable for ADC0 Sample Sequencer is not enabled. No wonder the interrupt will not be generated on Conversion Completion.

    Regards
    Amit
  • My apologies.
  • Hello Amit,

    Sorry for my poor post of addressing my problem. What you mean was I have to include "IntEnable(INT_ADC0SS0);" line to enable ADC0Sample Sequencer?
  • Is this what I should do? 

    ADC.c 

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/adc.h"
    #include "ADC.h"

    int ADCIntHandler (void);

    void ADC_Init (void) //initialization of ADC
    {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH11);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH11);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH11);
    ADCSequenceStepConfigure(ADC0_BASE,1,3,ADC_CTL_CH11|ADC_CTL_IE|ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, 1);

    IntEnable(INT_ADC0SS0);

    ADCIntEnable(ADC0_BASE, 0); 

    }

    int ADCIntHandler (void) //ADC conversion
    {
    ADCIntClear(ADC0_BASE, 1);
    ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
    ui32ADC0Avg = (ui32ADC0Value[0] + ui32ADC0Value[1] + ui32ADC0Value[2] + ui32ADC0Value[3] + 2)/4;
    return ui32ADC0Avg;
    }

     

  • Hi Domenic,

    IntEnable(INT_ADC0SS0);

     

    Perhaps you missed the use of SS1 in above post and you have interrupt enabled SS0.

    Also there is no interrupt priority set for ADC0, always a good thing to consider.

    Do take a look at the ADC clock sources and divisor settings in the datasheet.

    ADCClockConfigSet()

    Best of luck :)

     

  • Hi BP101,

    Thank you for the reminder. May I know the reason whats the purpose of including: 

    IntEnable(INT_ADC0SS1) 


    When I have already called the ADCIntHandler in ADC Sequence 1 in the tm4c123gh6pm_startup_ccs.c in my project. 

  • Each sequencer has and interrupt mask bit and you set it with ADC_CTL_IE|ADC_CTL_END. When polling Timer1 of TriggerProcessor0 the interrupt vector need be enabled to service the data from the sample sequence at end.
  • Thank you for the explanation. I am having trouble now because I do not know how to test for my program...there is no output that I expected and I do not know where went wrong...
  • Hello Domenic,

    To clarify the point the interrupt process is a multi point enabled.

    1. The ADCIntEnable enables the Interrupt Generation from the ADC peripheral to the CPU Sub System's NVIC Module
    2. The IntEnable enables the Interrupt recognition in the NVIC so that it can inform the CPU of an interrupt event

    Regards
    Amit