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.

TM4C129ENCPDT: ADC read more than one pins

Part Number: TM4C129ENCPDT

Hello Everyone!

I'm trying to read ADC values from my TM4c129encpdt launchpad.
The single ended sample I found from TI's own examples seems to be suitable for this job. This example works for a single pin, but I want to measure from more than one pin at the same time.
my code is as follows:

//*****************************************************************************
//
// single_ended.c - Example demonstrating how to configure the ADC for
//                  single ended operation.
//
// Copyright (c) 2010-2020 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
//   Redistribution and use in source and binary forms, with or without
//   modification, are permitted provided that the following conditions
//   are met:
// 
//   Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the  
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 
// This is part of revision 2.2.0.295 of the Tiva Firmware Development Package.
//
//*****************************************************************************

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

//*****************************************************************************
//
//! \addtogroup adc_examples_list
//! <h1>Single Ended ADC (single_ended)</h1>
//!
//! This example shows how to setup ADC0 as a single ended input and take a
//! single sample on AIN0/PE3.
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - ADC0 peripheral
//! - GPIO Port E peripheral (for AIN0 pin)
//! - AIN0 - PE3
//!
//! The following UART signals are configured only for displaying console
//! messages for this example.  These are not required for operation of the
//! ADC.
//! - UART0 peripheral
//! - GPIO Port A peripheral (for UART0 pins)
//! - UART0RX - PA0
//! - UART0TX - PA1
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - None.
//
//*****************************************************************************

//*****************************************************************************
//
// This function sets up UART0 to be used for a console to display information
// as the example is running.
//
//*****************************************************************************
void
InitConsole(void)
{
    //
    // Enable GPIO port A which is used for UART0 pins.
    // TODO: change this to whichever GPIO port you are using.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Configure the pin muxing for UART0 functions on port A0 and A1.
    // This step is not necessary if your part does not support pin muxing.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);

    //
    // Enable UART0 so that we can configure the clock.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    //
    // Select the alternate (UART) function for these pins.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Initialize the UART for console I/O.
    //
    UARTStdioConfig(0, 115200, 16000000);
}

//*****************************************************************************
//
// Configure ADC0 for a single-ended input and a single sample.  Once the
// sample is ready, an interrupt flag will be set.  Using a polling method,
// the data will be read then displayed on the console via UART0.
//
//*****************************************************************************
int
main(void)
{
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
    uint32_t ui32SysClock;
#endif

    //
    // This array is used for storing the data read from the ADC FIFO. It
    // must be as large as the FIFO for the sequencer in use.  This example
    // uses sequence 3 which has a FIFO depth of 1.  If another sequence
    // was used with a deeper FIFO, then the array size must be changed.
    //
    uint32_t pui32ADC0Value[1];

    //
    // Set the clocking to run at 20 MHz (200 MHz / 10) using the PLL.  When
    // using the ADC, you must either use the PLL or supply a 16 MHz clock
    // source.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal on your board.
    //
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
    //
    // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and
    // later to better reflect the actual VCO speed due to SYSCTL#22.
    //
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                       SYSCTL_OSC_MAIN |
                                       SYSCTL_USE_PLL |
                                       SYSCTL_CFG_VCO_240), 20000000);
#else
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_16MHZ);
#endif

    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for ADC operation.
    //
    InitConsole();

    //
    // Display the setup on the console.
    //
    UARTprintf("ADC ->\n");
    UARTprintf("  Type: Single Ended\n");
    UARTprintf("  Samples: One\n");
    UARTprintf("  Update Rate: 250ms\n");
    UARTprintf("  Input Pin: AIN0/PE3\n\n");

    //
    // The ADC0 peripheral must be enabled for use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    //
    // For this example ADC0 is used with AIN0 on port E7.
    // The actual port and pins used may be different on your part, consult
    // the data sheet for more information.  GPIO port E needs to be enabled
    // so these pins can be used.
    // TODO: change this to whichever GPIO port you are using.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);

    //
    // Select the analog ADC function for these pins.
    // Consult the data sheet to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using.
    //
    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);
    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_5);
    
    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);
    GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_4);
    GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_5);
    GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_6);
    GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7);
    
    GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);
    GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_5);
    
    GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_2);
    GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_3);
    
    

    //
    // Enable sample sequence 3 with a processor signal trigger.  Sequence 3
    // will do a single sample when the processor sends a signal to start the
    // conversion.  Each ADC module has 4 programmable sequences, sequence 0
    // to sequence 3.  This example is arbitrarily using sequence 3.
    //
    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

    //
    // Configure step 0 on sequence 3.  Sample channel 0 (ADC_CTL_CH0) in
    // single-ended mode (default) and configure the interrupt flag
    // (ADC_CTL_IE) to be set when the sample is done.  Tell the ADC logic
    // that this is the last conversion on sequence 3 (ADC_CTL_END).  Sequence
    // 3 has only one programmable step.  Sequence 1 and 2 have 4 steps, and
    // sequence 0 has 8 programmable steps.  Since we are only doing a single
    // conversion using sequence 3 we will only configure step 0.  For more
    // information on the ADC sequences and steps, reference the datasheet.
    //
    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE |
                             ADC_CTL_END);

    //
    // Since sample sequence 3 is now configured, it must be enabled.
    //
    ADCSequenceEnable(ADC0_BASE, 3);

    //
    // Clear the interrupt status flag.  This is done to make sure the
    // interrupt flag is cleared before we sample.
    //
    ADCIntClear(ADC0_BASE, 3);

    //
    // Sample AIN0 forever.  Display the value on the console.
    //
    while(1)
    {
        //
        // Trigger the ADC conversion.
        //
        ADCProcessorTrigger(ADC0_BASE, 3);

        //
        // Wait for conversion to be completed.
        //
        while(!ADCIntStatus(ADC0_BASE, 3, false))
        {
        }

        //
        // Clear the ADC interrupt flag.
        //
        ADCIntClear(ADC0_BASE, 3);

        //
        // Read ADC Value.
        //
        ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);

        //
        // Display the AIN0 (PE3) digital value on the console.
        //
        UARTprintf("AIN0 = %4d\r", pui32ADC0Value[0]);

        //
        // This function provides a means of generating a constant length
        // delay.  The function delay (in cycles) = 3 * parameter.  Delay
        // 250ms arbitrarily.
        //
#if defined(TARGET_IS_TM4C129_RA0) ||                                         \
    defined(TARGET_IS_TM4C129_RA1) ||                                         \
    defined(TARGET_IS_TM4C129_RA2)
        SysCtlDelay(ui32SysClock / 12);
#else
        SysCtlDelay(SysCtlClockGet() / 12);
#endif
    }
}

I add the other pins as the guide in the code showed me but I can only see the value on the PE_3 (AIN0) pin.

however, I also need to see value from other analog inputs.
PE_0 (AIN3), PE_1 (AIN2), PE_2 (AIN1), PD_0 (AIN15), PD_1 (AIN14), PD_2 (AIN13), PD_3 (AIN12), PD_4 (AIN11) etc...

how do i need to update this code?

  • Hello Batuhan,

    You would use additional ADCSequenceStepConfigure APIs to configure each channel. So you start with the ADCSequenceConfigure as you have done, then use ADCSequenceStepConfigure for each ADC channel, and then you get it running with ADCSequenceEnable.

    To retrieve the samples, you use ADCSequenceDataGet which you can pass a buffer into to get multiple samples:

    ADCSequenceDataGet(uint32_t ui32Base, uint32_t ui32SequenceNum,
                       uint32_t *pui32Buffer)
                       
    //! Gets the captured data for a sample sequence.
    //!
    //! \param ui32Base is the base address of the ADC module.
    //! \param ui32SequenceNum is the sample sequence number.
    //! \param pui32Buffer is the address where the data is stored.
    //!
    //! This function copies data from the specified sample sequencer output FIFO
    //! to a memory resident buffer.  The number of samples available in the
    //! hardware FIFO are copied into the buffer, which is assumed to be large
    //! enough to hold that many samples.  This function only returns the samples
    //! that are presently available, which may not be the entire sample sequence
    //! if it is in the process of being executed.
    //!
    //! \return Returns the number of samples copied to the buffer.

    You can see the majority of this setup reflected in this E2E post, just make sure to give enough time for all your samples to convert: https://e2e.ti.com/support/microcontrollers/other/f/other-microcontrollers-forum/944043/ccs-tm4c123gh6pm-multiple-channel-adc

  • Hello Ralph!

    I made some changes in the code. I made adjustments to read Value from 8 different channels. I chose Sample Sequencer 0.

    ADCSequenceDataGet (ADC0_BASE, 0, pui32ADC0Value);
    With this code, I assigned the values to the pui32ADC0Value.

    Things got complicated after that, when I want to print these values ​​with UARTPrintf, these are the values ​​I see.

    In this situation there are only one pin is connected to the 3.3V. and this is the PE3(AIN0). other channels should be low, but as you see it is not..

    The strange part is; Only PE3 (AIN0) works from the pins I have defined, and it looks the same as pui32ADC0Value [0] and pui32ADC0Value [1]. When I give 3.3V to the other pins, nothing changes.
    Even when I don't define PE3 (AIN0) pin, it still reads value from that pin.

    Earlier, I read a post saying there was a glitch in the PE3 pin, but now I can't find it. Could my problem be related to this?

    You also said that I should reduce the Timer Frequency but I don't know how to do it.
    Can you please check my code and tell me where I might have made mistakes? My deadline for the project is approaching and I really need a hand.

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/adc.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"
    #include "driverlib/timer.h"
    
    void
    InitConsole(void)
    {
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTStdioConfig(0, 115200, 16000000);
    }
    
    int
    main(void)
    {
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        uint32_t ui32SysClock;
    #endif
    
        uint32_t pui32ADC0Value[8];
    
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
    
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_PLL |
                                           SYSCTL_CFG_VCO_240), 20000000);
    #else
        SysCtlClockSet(SYSCTL_SYSDIV_16 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
    #endif
    
    
        InitConsole();
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_6);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_5);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_4);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_3);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_2);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_1);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_5);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_4);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);
    
        ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
    
        ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END); // PE3
        ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH1 | ADC_CTL_IE | ADC_CTL_END); // PE2
        ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH2 | ADC_CTL_IE | ADC_CTL_END); // PE1
        ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH3 | ADC_CTL_IE | ADC_CTL_END); // PE0
        ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END); // PD7
        ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END); // PD6
        ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH6 | ADC_CTL_IE | ADC_CTL_END); // PD5
        ADCSequenceStepConfigure(ADC0_BASE, 0, 8, ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END); // PD4
    
        ADCSequenceEnable(ADC0_BASE, 0);
        ADCIntClear(ADC0_BASE, 0);
    
        while(1)
        {
    
            ADCProcessorTrigger(ADC0_BASE, 0);
    
            while(!ADCIntStatus(ADC0_BASE, 0, false))
            {
            }
    
            ADCIntClear(ADC0_BASE, 0);
    
            ADCSequenceDataGet(ADC0_BASE, 0, pui32ADC0Value);
    
            UARTprintf("AIN0 = %4d\r\n", pui32ADC0Value[0]);
            UARTprintf("AIN1 = %4d\r\n", pui32ADC0Value[1]);
            UARTprintf("AIN2 = %4d\r\n", pui32ADC0Value[2]);
            UARTprintf("AIN3 = %4d\r\n", pui32ADC0Value[3]);
            UARTprintf("AIN4 = %4d\r\n", pui32ADC0Value[4]);
            UARTprintf("AIN5 = %4d\r\n", pui32ADC0Value[5]);
            UARTprintf("AIN6 = %4d\r\n", pui32ADC0Value[6]);
            UARTprintf("AIN7 = %4d\r\n", pui32ADC0Value[7]);
    
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
            SysCtlDelay(ui32SysClock / 12);
    #else
            SysCtlDelay(SysCtlClockGet() / 12);
    #endif
        }
    }

  • Hello Batuhan,

    The way you have this configured, the sequence is ending right away instead of continuing for your channels.

    Also, you are skipping over Step 0 so I revised that too.

    Try the following setup:

        ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0); // PE3
        ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1); // PE2
        ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH2); // PE1
        ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH3); // PE0
        ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH4); // PD7
        ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH5); // PD6
        ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH6); // PD5
        ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END); // PD4
    

  • Hello Ralph!
    I tried the setup you said and finally all channels are working properly. There is also a slight increase in the values of the pins near the 3.3V pin, but I guess this is due to the isolation.
    I really thank you for your help.
    I need to read values from 20 channels in the circuit that I'll set up. For this reason, I upgraded the code and it works. I'll leave the code here, maybe it'll be useful to someone else later.
    Thank you again Ralph !!!

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/adc.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "utils/uartstdio.c"
    #include "driverlib/timer.h"
    
    void
    InitConsole(void)
    {
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTStdioConfig(0, 115200, 16000000);
    }
    
    int
    main(void)
    {
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
        uint32_t ui32SysClock;
    #endif
    
        uint32_t pui32ADC0Value[8];
        uint32_t pui32ADC0Value1[8];
        uint32_t pui32ADC0Value2[8];
        uint32_t pui32ADC1Value1[8];
    
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
    
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_PLL |
                                           SYSCTL_CFG_VCO_240), 20000000);
    #else
        SysCtlClockSet(SYSCTL_SYSDIV_16 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);
    #endif
    
    
        InitConsole();
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_6);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_5);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_4);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_3);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_2);
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_1);
    
        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_5);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_4);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1);
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);
    
        GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_3);
        GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_2);
        GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_1);
        GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_0);
    
        GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_5);
        GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);
    
        ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
        ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
        ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PROCESSOR, 0);
        ADCSequenceConfigure(ADC1_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
    
    
        ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0); // PE3
        ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1); // PE2
        ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH2); // PE1
        ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH3); // PE0
        ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH4); // PD7
        ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH5); // PD6
        ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH6); // PD5
        ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END); // PD4
    
        ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH12); // PD3
        ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH13); // PD2
        ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH14); // PD1
        ADCSequenceStepConfigure(ADC0_BASE, 1, 3, ADC_CTL_CH15 | ADC_CTL_IE | ADC_CTL_END); // PD0
    
        ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH9); // PE4
        ADCSequenceStepConfigure(ADC0_BASE, 2, 1, ADC_CTL_CH8); // PE5
        ADCSequenceStepConfigure(ADC0_BASE, 2, 2, ADC_CTL_CH10); // PB4
        ADCSequenceStepConfigure(ADC0_BASE, 2, 3, ADC_CTL_CH11 | ADC_CTL_IE | ADC_CTL_END); // PB5
    
        ADCSequenceStepConfigure(ADC1_BASE, 1, 0, ADC_CTL_CH16); // PK0
        ADCSequenceStepConfigure(ADC1_BASE, 1, 1, ADC_CTL_CH17); // PK1
        ADCSequenceStepConfigure(ADC1_BASE, 1, 2, ADC_CTL_CH18); // PK2
        ADCSequenceStepConfigure(ADC1_BASE, 1, 3, ADC_CTL_CH19 | ADC_CTL_IE | ADC_CTL_END); // PK3
    
    
    
        ADCSequenceEnable(ADC0_BASE, 0);
        ADCSequenceEnable(ADC0_BASE, 1);
        ADCSequenceEnable(ADC0_BASE, 2);
        ADCSequenceEnable(ADC1_BASE, 1);
        ADCIntClear(ADC0_BASE, 0);
        ADCIntClear(ADC0_BASE, 1);
        ADCIntClear(ADC0_BASE, 2);
        ADCIntClear(ADC1_BASE, 1);
    
        while(1)
        {
    
            ADCProcessorTrigger(ADC0_BASE, 0);
            ADCProcessorTrigger(ADC0_BASE, 1);
            ADCProcessorTrigger(ADC0_BASE, 2);
            ADCProcessorTrigger(ADC1_BASE, 1);
    
            while(!ADCIntStatus(ADC0_BASE, 0, false))
            {
            }
            while(!ADCIntStatus(ADC0_BASE, 1, false))
            {
            }
            while(!ADCIntStatus(ADC0_BASE, 2, false))
            {
            }
            while(!ADCIntStatus(ADC1_BASE, 1, false))
            {
            }
    
            ADCIntClear(ADC0_BASE, 0);
            ADCIntClear(ADC0_BASE, 1);
            ADCIntClear(ADC0_BASE, 2);
            ADCIntClear(ADC1_BASE, 1);
    
            ADCSequenceDataGet(ADC0_BASE, 0, pui32ADC0Value);
            ADCSequenceDataGet(ADC0_BASE, 1, pui32ADC0Value1);
            ADCSequenceDataGet(ADC0_BASE, 2, pui32ADC0Value2);
            ADCSequenceDataGet(ADC1_BASE, 1, pui32ADC1Value1);
    
    
    
            UARTprintf("AIN0 = PE3 = %4d\r\n", pui32ADC0Value[0]);
            UARTprintf("AIN1 = PE2 = %4d\r\n", pui32ADC0Value[1]);
            UARTprintf("AIN2 = PE1 = %4d\r\n", pui32ADC0Value[2]);
            UARTprintf("AIN3 = PE0 = %4d\r\n", pui32ADC0Value[3]);
            UARTprintf("AIN4 = PD7 = %4d\r\n", pui32ADC0Value[4]);
            UARTprintf("AIN5 = PD6 = %4d\r\n", pui32ADC0Value[5]);
            UARTprintf("AIN6 = PD5 = %4d\r\n", pui32ADC0Value[6]);
            UARTprintf("AIN7 = PD4 = %4d\r\n", pui32ADC0Value[7]);
    
            UARTprintf("AIN8 = PE5 = %4d\r\n", pui32ADC0Value2[1]);
            UARTprintf("AIN9 = PE4 = %4d\r\n", pui32ADC0Value2[0]);
            UARTprintf("AIN10 = PB4 = %4d\r\n", pui32ADC0Value2[2]);
            UARTprintf("AIN11 = PB5 = %4d\r\n", pui32ADC0Value2[3]);
    
            UARTprintf("AIN12 = PD3 = %4d\r\n", pui32ADC0Value1[0]);
            UARTprintf("AIN13 = PD2 = %4d\r\n", pui32ADC0Value1[1]);
            UARTprintf("AIN14 = PD1 = %4d\r\n", pui32ADC0Value1[2]);
            UARTprintf("AIN15 = PD0 = %4d\r\n", pui32ADC0Value1[3]);
    
            UARTprintf("AIN16 = PK0 = %4d\r\n", pui32ADC1Value1[0]);
            UARTprintf("AIN17 = PK1 = %4d\r\n", pui32ADC1Value1[1]);
            UARTprintf("AIN18 = PK2 = %4d\r\n", pui32ADC1Value1[2]);
            UARTprintf("AIN19 = PK3 = %4d\r\n", pui32ADC1Value1[3]);
    
    
    #if defined(TARGET_IS_TM4C129_RA0) ||                                         \
        defined(TARGET_IS_TM4C129_RA1) ||                                         \
        defined(TARGET_IS_TM4C129_RA2)
            SysCtlDelay(ui32SysClock / 12);
    #else
            SysCtlDelay(SysCtlClockGet() / 12);
    #endif
        }
    }
    

  • Hello again Ralph!

    When I use the code, I see increases in channels which I do not give voltage. For example, if I give 3.3V to the PE1 pin, the values in the following channels such as PE2, PE3, PD7, PD6, etc., increase suddenly. Okay, I don't expect them to be zero, but the increase is really too much. What is the reason of this and how can I avoid it and read more precisely?

  • Hi Batuhan,

    Based on your description, it sounds like the sampling frequency is set in a way that the capacitor CADC isn't able to fully discharge before the next samples are being read. See Figure 18-7. ADC Input Equivalency of the device datasheet to understand this internal topology. What you would need to do is extend the time between samples to allow CADC to properly discharge. 

    This post from Charles may also be helpful: https://e2e.ti.com/support/microcontrollers/other/f/other-microcontrollers-forum/993089/tm4c1294ncpdt-multiple-adc-channels-issue/3671735#3671735