//example_uart_rxIdleIrq.c
#include "example.h"
//类似idle中断的使用方式:
//以 UART_INT_RX(收中断)和 UART_INT_RT(收超时中断)配合来实现idle中断的功能。
//串口的FIFO只有16个字节,通过UART_SetRxIntFifoLevel配置为UART_INT_FIFO_HALF时,每收8个字节会来一次UART_INT_RX中断。
//如果收取的长度不足8个字节时,会触发UART_INT_RT中断。
//数据处理时,如果接收不定长数据超过8个以上的,要通过UART_INT_RX中断8个8个来收取;最后零碎的,通过UART_INT_RT来收取。
//全部收取完以后,由UART_INT_RT中断标记来判定 idle完整的一包。
volatile char isRecvEnd = 0; //是否收取idle完整一包
volatile char rcvLen = 0; //rx收取的包的长度
char rxbuf[64]; //rx收取的缓存buff
void UART0_isr()
{
if (UART_IsRawIntActive(UART0, UART_INT_RX)) {
UART_ClearInt(UART0, UART_INT_RX);
//注意:这时FIFO里有8个字节长度,但特意不全部收取。
//这么做,是为了保证传输数据刚好是8的整数倍时,仍然会触发下边的UART_INT_RT中断。
UART_Receive(UART0, rxbuf + rcvLen, 7, 0); //half: 16/2=8。
rcvLen += 7;
} else if (UART_IsRawIntActive(UART0, UART_INT_RT)) {
UART_ClearInt(UART0, UART_INT_RT);
rcvLen += UART_Receive(UART0, rxbuf + rcvLen, 8, 1); //最后一个参数不能为0,为0时UART_Receive是不会超时退出的
isRecvEnd = 1; //idle一包收满
}
}
void TestUartRxIdleIqr(void)
{
GPIO_AF_ENABLE(UART0_UARTRXD)
GPIO_AF_ENABLE(UART0_UARTTXD);
SYS_EnableAPBClock(APB_MASK_UART0);
UART_Init(UART0, 115200, UART_LCR_DATABITS_8, UART_LCR_STOPBITS_1, UART_LCR_PARITY_NONE, UART_LCR_FIFO_16);
UART_EnableInt(UART0, UART_INT_RT); //配置 收超时中断
UART_EnableInt(UART0, UART_INT_RX); //配置 收中断
UART_SetRxIntFifoLevel(UART0, UART_INT_FIFO_HALF); //配置FIFO收多少字节时产生收中断
INT_EnableIRQ(UART0_IRQn, UART_PRIORITY);
UART_Send(UART0, "test idleIrq\r\n", strlen("test idleIrq\r\n"));
//test
while(1)
{
UTIL_IdleUs(500e3);
if (isRecvEnd == 1)
{
UART_Send(UART0, rxbuf, rcvLen);
rcvLen = 0;
isRecvEnd = 0;
}
}
}