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, ¤t); // 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();
}