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.

TM4C123GH6PM: I am curious about when the uart Interrupt start to work,is it after UARTCharPut() finishes?

Part Number: TM4C123GH6PM

I use uart3(uses PC 6 & 7) rx interrupt and think of its interrupt will start to work when the UARTCharPut(UART3_BASE, send[i]) finish,so in ISR  ,I  use a same index i that used in Send[i],

when I run the code in one time,the receive array are all '0x00',but when I set breakpoint and run the code step by step,I can get what I send,but exist a dislocation ,just like send array is ['h','i','m',........],

receive array become ['0x00','h','i','m',.....],I tried to change my receive Index from i to i-1,this time ,when I run the code in one time,the receive array is partly correct,but some character is missing,but when I set breakpoint again and run the code step by step,I can get all correct characters.

so i get puzzled about When did the code enter the interrupt service function?

if it is after UARTCharPut(),i is no need to minus 1,but if I don't ,it will become all '0x00' or exist a dislocation

here is my code :(chinese is my comment) I use PB2 to lit the LED1,when receive correctly

//使用除uart0以外的任何uart模块,都无法进行与PC的通信,可以使用回环LOOPBACK模式进行测试
//使用PC7发送数据,PC6接收数据,内部进行回环,如果接收到的数据与发送的数据相同,则将PB2状态反转,
//PB2在外部与PF1链接,反转LED1

//PB2,3复位后的默认状态为I2C,需要手动配置为GPIO
//在回环模式里,接收中断和发送中断是等效的
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_uart.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"


void Uart_Init(void);
void UARTIntHandler(void);
void GPIOF_Init(void);
void GPIOB23_Init(void);

char send[100] = "hi man this is tiva\r\n";//"hi man this is tiva\r\n"
char receive[100]  ;

uint8_t B2Status = GPIO_PIN_2;

uint8_t length = 0;
uint8_t ret = 0;
uint8_t sendIndex = 0;
uint8_t receIndex = 0;

uint8_t i=0;
int main(void)
{

    SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_XTAL_16MHZ| SYSCTL_OSC_MAIN);

    GPIOF_Init();
    GPIOB23_Init();
    Uart_Init();

    while(1)
    {

        SysCtlDelay(SysCtlClockGet()/3);     //隔一秒钟发送一次数据

        //sprintf(send,"hi man this is tiva\r\n"); //将数据存入send[]

        length  = strlen(send);                 //统计send[]有效字符的长度

        /*sendIndex = 0;

        while(send[sendIndex]!='\0')
        {
            UARTCharPut(UART3_BASE, send[sendIndex]);      //将send[]的有效字符发送出去
            sendIndex++;
        }*/

        i = 0;

        while(send[i]!='\0')
        {
            UARTCharPut(UART3_BASE, send[i]);      //将send[]的有效字符发送出去
            i++;
        }


        ret = strcmp(send,receive);

        if(ret == 0)                             //如果接收与发送相同,PB2反转
        {
            GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,B2Status);
            B2Status = ~B2Status;
        }

    }

}

void Uart_Init(void)
{
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);

        HWREG(UART3_BASE+UART_O_CTL) |= 0x0080;//使能回环

        GPIOPinConfigure(GPIO_PC6_U3RX);
        GPIOPinConfigure(GPIO_PC7_U3TX);
        GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);


        UARTConfigSetExpClk(UART3_BASE, SysCtlClockGet(), 115200,
                            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE));

        UARTEnable(UART3_BASE);

        //使能中断
        IntMasterEnable();
        //使能串口中断
        IntEnable(INT_UART3);
        UARTIntEnable(UART3_BASE, UART_INT_RX | UART_INT_RT);   //使能接收中断和接收超时中断
                                                                //接到一个字符,产生一次中断
}

//串口接收中断服务程序
void UARTIntHandler(void)
{
    uint32_t ulStatus;
    //获取中断状态
    ulStatus = UARTIntStatus(UART3_BASE, true);
    //清除中断标志
    UARTIntClear(UART3_BASE, ulStatus);
    //直到串口FIFO中没有数据时才退出循环

    //uint8_t  j = 0;
   /* while(UARTCharsAvail(UART3_BASE))   //当接收缓冲区仍有数据,进入循环
    {
      //读串口接收的字符并回发
       // UARTCharPut(UART3_BASE,UARTCharGet(UART3_BASE));
        receive[receIndex] = UARTCharGet(UART3_BASE);
        receIndex++;
        receIndex %= length;
    }*/

     while(UARTCharsAvail(UART3_BASE))   //当接收缓冲区仍有数据,进入循环
    {
      //读串口接收的字符并回发
       // UARTCharPut(UART3_BASE,UARTCharGet(UART3_BASE));
        receive[i-1] = UARTCharGet(UART3_BASE);

    }

 }

void GPIOF_Init(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);    //F1与红灯相连,不要上拉
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1,0);
}

void GPIOB23_Init(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_2);

    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2,0);       //检测GPIO2是否配置成GPIO
}


 

  • Hello Liguo,

    If you are using a global variable in the ISR, you must declare it as a volatile variable for it to update properly.

    So: 

    volatile uint8_t i=0;

    Also as a general comment, I would recommend using a more descriptive name than 'i'. Index is a better one. Best programming practices also indicate the type in the name, so ui8Index would be even better. Just some general programming advice as far as variable naming goes.

  • Hi,Ralph.

    Thank you for your kind help,I will remember your advice in the future. name is an important point that I am not good at.