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.

TM4C1294NCPDT: UART reading and writing issues for power converter nextion HMI

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: TM4C123GH6PM

Tool/software:

I am sampling voltage and current at 100 ksps and sending this data to the Nextion HMI every second using Timer 1. However, when I attempt to display these values every second, the system enters the UART handler, which is used to receive set values from the microcontroller. As a result, the UART send command causes an interrupt conflict, preventing the data transmission from executing properly.

code are written below

#include "stdbool.h"
#include "stdint.h"
#include "stdio.h"
#include "stdlib.h"
#include "utils/ustdlib.h"
#include "driverlib/uart.h"
#include "math.h"
#include "driverlib/ssi.h"
#include "driverlib/timer.h"
#include "driverlib/rom_map.h"
#include "string.h"

#include "driverlib/gpio.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "inc/hw_memmap.h"
#include "driverlib/pin_map.h"
#include "driverlib/emac.h"
#include "driverlib/systick.h"
#include "drivers/pinout.h"
#include "utils/ustdlib.h"
#include "driverlib/adc.h"
#include "math.h"
#include "driverlib/ssi.h"
#include "inc/tm4c123gh6pm.h"
#include "driverlib/uart.h"
#include "driverlib/rom.h"
#include "driverlib/udma.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/fpu.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#define UPDATE_THRESHOLD 100  // Minimum ADC change required to update Nextion
#define GPIO_PE4_U5RX           0x00041001
#define SAMPLE_RATE 100000 // 100 ksps

#define GPIO_PE5_U5TX           0x00041401
// Global Variables
 bool isRemoteMode = false;
 volatile bool flag=0;
volatile uint32_t adc_result_0, adc_result_1;
// Function Prototypes
void UART_Enable(void);
void UARTSend(const char *pucBuffer);
void SysTickIntHandler(void);
void delay_ms(uint32_t milliseconds);
uint8_t lucData[10],lucLoopCounter,vol_eth;
  char data;
  char dacdata[20];
  float voltage,scaledvoltage,current,scaledcurrent;
  float x1;

  void system_setup(void);

   int i;
   uint32_t dac_update_count,ui32SysClock,munDelaycount;
   uint16_t gunCounter;
#define SYS_TICK_DELAY 10000
char buffer[9],buffer1[9];
volatile float voltage_out = 0, current_out = 0;
uint32_t ui32Status,frac,frac_curr;
 uint32_t adc_voltage_raw,timer_load ;
 uint32_t adc_current_raw ;
 float adc_voltage ;
 float adc_current;
 int intScaledVoltage,intScaledCurrent,update_flag=0;
void Parse_Data(char *buffer, float *voltage_out, float *current_out) ;
void Format_Value(char *input, char *output);
            void ADC1IntHandler(void)
                    {
                       //     GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_2, GPIO_PIN_2); // Set PP2 HIGH (ISR start)
                            ADCIntClear(ADC1_BASE, 3);
                            ADCSequenceDataGet(ADC1_BASE, 3, &adc_current_raw);
                            adc_current = ((float)adc_current_raw * 22) / 4095.0f;
                            intScaledCurrent = (int)adc_current;
                            frac_curr=(adc_current-intScaledCurrent)*100;

                      //      GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_2, 0); // Set PP2 LOW (ISR end)
                    }
            void ADC0IntHandler(void)
                    {
                            ADCIntClear(ADC0_BASE, 3);
                            ADCIntClear(ADC0_BASE, 3);
                            ADCSequenceDataGet(ADC0_BASE, 3, &adc_voltage_raw);
                            adc_voltage = (adc_voltage_raw * 33) / 4095.0f;
                            intScaledVoltage = (int)adc_voltage;
                            frac=(adc_voltage-intScaledVoltage)*100;
                            update_flag=1;
                    }


            void MT_SysTick_Set()
                    {
                            SysTickPeriodSet(((ui32SysClock / 1000000) * SYS_TICK_DELAY));  // load count
                            SysTickIntRegister(SysTickIntHandler);  // int handler Register
                            SysTickIntEnable();             // Enable Systick interrupt
                            SysTickEnable();                // Enable Systick
                    }


            void SysTickIntHandler()
                    {
         /* ------------ LwIP Timer  ----------------------------- */
       //   lwIPTimer(5);
                            if(++munDelaycount>=100)
                            {
                                    munDelaycount=0;
                                    if(++gunCounter>=100)
                                            {
                                                gunCounter=0;
                                            }
                            }
                    }

            void ADC0_Init(void)
                    {
                            SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
                            SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
                            while (!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0));
                            while (!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC1));
                            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
                            while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE));
                            GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1 | GPIO_PIN_2 );
                            ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_TIMER, 0);
                            ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH2 | ADC_CTL_IE | ADC_CTL_END);
                            ADCSequenceEnable(ADC0_BASE, 3);
                            ADCIntClear(ADC0_BASE, 3);
                            ADCIntRegister(ADC0_BASE, 3, ADC0IntHandler);
                            ADCIntEnable(ADC0_BASE, 3);
                            ADCSequenceConfigure(ADC1_BASE, 3, ADC_TRIGGER_TIMER, 0);
                            ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH1 | ADC_CTL_IE | ADC_CTL_END);
                            ADCSequenceEnable(ADC1_BASE, 3);
                            ADCIntClear(ADC1_BASE, 3);
                            ADCIntRegister(ADC1_BASE, 3, ADC1IntHandler);
                            ADCIntEnable(ADC1_BASE, 3);
                            IntEnable(INT_ADC1SS3);
                            IntEnable(INT_ADC0SS3);
                    }

            void Timer0A_Handler(void)
                    {
                            TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);


                    }
            void Timer0A_Init(void)
            {
                // Enable peripherals
                SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
                SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);

                while (!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0));
                while (!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER1));

                // Disable timers before configuring
                TimerDisable(TIMER0_BASE, TIMER_A);
                TimerDisable(TIMER1_BASE, TIMER_A);

                // Configure Timer 0 for periodic mode (10 µs interval)
                TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
                TimerLoadSet(TIMER0_BASE, TIMER_A, 1200); // 10 µs at 120MHz
                TimerControlTrigger(TIMER0_BASE, TIMER_A, true); // Enable ADC trigger
                TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
                IntEnable(INT_TIMER0A);

                // Configure Timer 1 for periodic mode (1 second interval)
                TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
                TimerLoadSet(TIMER1_BASE, TIMER_A, 120000000); // 1 sec at 120MHz
                TimerClockSourceSet(TIMER1_BASE, TIMER_CLOCK_SYSTEM); // Explicitly set system clock
                TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
                IntEnable(INT_TIMER1A);

                // Set interrupt priorities to prevent Timer 0 from blocking Timer 1
              //  IntPrioritySet(INT_TIMER0A, 0x20); // Lower priority for Timer 0
              //  IntPrioritySet(INT_TIMER1A, 0x00); // Highest priority for Timer 1

                // Enable timers
                TimerEnable(TIMER0_BASE, TIMER_A);
                TimerEnable(TIMER1_BASE, TIMER_A);

                // Enable global interrupts **LAST**

            }


int main(void)
    {

       ui32SysClock =SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
       MT_SysTick_Set();
       system_setup();
       Timer0A_Init();
       UART_Enable();
       ADC0_Init();

                   while (1)
                           {

                           }
    }

                void delay_ms(uint32_t milliseconds)
                    {
                            SysTickPeriodSet(SysCtlClockGet()/1000);
                            SysTickEnable();
                            while(SysTickValueGet()>0);

                    }

                void UART_Enable()
                    {
                            SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
                            SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
                            GPIOPinConfigure(GPIO_PA0_U0RX);
                            GPIOPinConfigure(GPIO_PA1_U0TX);
                            GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
                            UARTConfigSetExpClk(UART0_BASE, ui32SysClock, 9600,
                            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                             UART_CONFIG_PAR_NONE));

                            IntEnable(INT_UART0);
                            UARTEnable (UART0_BASE);
                            UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

                            UARTIntDisable(UART0_BASE, UART_INT_TX);
                            UARTFIFODisable(UART0_BASE);
                            IntMasterEnable();
                    }


                 void UARTSend(const char *pucBuffer)
                    {

                             while (*pucBuffer)
                                 {
                                     UARTCharPut(UART0_BASE, *pucBuffer++);

                                 }
                            UARTCharPut(UART0_BASE, 0xFF);
                            UARTCharPut(UART0_BASE, 0xFF);
                            UARTCharPut(UART0_BASE, 0xFF);

                    }

                 void Timer1IntHandler(void)
                     {

                             TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT); // Clear the interrupt
                             snprintf(buffer, sizeof(buffer), "t9.txt=%d", intScaledVoltage);
                             UARTSend(buffer);
                          ////   snprintf(buffer1, sizeof(buffer1), "t5.txt=\"%d\"", intScaledCurrent);
                         //    UARTSend(buffer1);


                     }

                 void UARTIntHandler(void)
                     {
                             uint8_t k = 0;
                             uint32_t ui32Status;

                             if(flag==0)
                                                                                                                                                                                 {
                                                                                                                                                                                     flag=1;
                                                                                                                                                                                     GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_2, GPIO_PIN_2);
                                                                                                                                                                                 }
                                                                                                                                                                                 else if(flag==1)
                                                                                                                                                                                 {
                                                                                                                                                                                     flag=0;
                                                                                                                                                                                     GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_2, 0);
                                                                                                                                                                                 }
                             ui32Status = ROM_UARTIntStatus(UART0_BASE, true);
                             ROM_UARTIntClear(UART0_BASE, ui32Status);// & UART_INT_RX);
                             if (ui32Status & UART_INT_RX || ui32Status & UART_INT_RT) // Only process RX
                                         {

                                                 while (UARTCharsAvail(UART0_BASE))
                                                         {
                                                                 data = UARTCharGet(UART0_BASE);
                                                                 if (data == 0x07)
                                                                         {
                                                                                 k = 0;  // Reset buffer index
                                                                         }

                                                                 if (k < 13)
                                                                         {
                                                                                 dacdata[k++] = data;
                                                                         }

                                                                 if (k >= 13)
                                                                         {
                                                                                 k = 0;  // Reset index for next reception
//                                                                               Parse_Data((char *)dacdata, &voltage, &current);  // Process data inside interrupt
                                                                         }
                                                         }
                                             }
                     }

                 void system_setup()
                     {
                         SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOP);
                         while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOP)); // Wait for stabilization

                         // Configure PP2 as output
                         GPIOPinTypeGPIOOutput(GPIO_PORTP_BASE, GPIO_PIN_2);
                         FPUEnable();
                         FPULazyStackingEnable();
                     }

  • Hi,

      If you look at the interrupt vector table, the UART0 has higher priority than Timer0. I will recommend that in the Timer ISR, you only set a flag and not call UART_send inside the Timer ISR. Use that flag in the main() to decide when to call UART_send. After UART_send is called, clear the flag. Basically, keep the ISR as short as possible which is the preferred method. What you can also try is to disable UART0 interrupt when you are inside the Timer0 ISR.