1、前言:出现的问题和现象
使用串口DMA接收4G模块的AT指令回复时,一开始还能够接收到数据,后来运行到某个AT指令发送的时候,后面就接收不到数据了。进入内部的状态寄存器查看,发现接收数据过程中出现了错误:ORE:过载错误。
当数据接收区或者FIFO区有数据或者满时,又有新数据进来,会导致发生溢出错误,一旦发生溢出错误,RX 移位寄存区虽然能有新数据不断的覆盖,但是数据不会到达RXR或FIFO(现象是:RXNE在ORE置位时不会被置位),导致程序中不能读到新的数据。只有通过ICR清除ORE才能使得RXNE在接收到新数据时置位。或者增大接收数组的容量,一般采用前者解决。
2、什么是ORE中断?为什么会产生?

产生原因如上所述。
ORE标志位在USART_SR寄存器,但值得注意的是
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);使能了接收中断,那么ORE中断也同时被开启了。
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);使能了接收中断,那么ORE中断也同时被开启了。
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);使能了接收中断,那么ORE中断也同时被开启了。
3、直接清楚ORE清楚失败的原因
因此如果先读寄存器里面的内容,让RXNE标志清除,那么溢出中断才可以清除
4、如何解决
stm32
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)== SET)//程序中断过多,主机的发送速度又快,很容易会造成溢出错误
{
USART_ClearFlag(USART1, USART_FLAG_ORE); //清除溢出中断
USART_ReceiveData(USART1);//必须要读,不然溢出中断清除不了
}
兆易创新
/*Erro flag*/
if(RESET != usart_interrupt_flag_get(UART7, USART_INT_FLAG_RBNE_ORERR))
{
usart_data_receive(UART7);
usart_interrupt_flag_clear(UART7,USART_INT_FLAG_RBNE_ORERR);
}
if(RESET != usart_interrupt_flag_get(UART7, USART_INT_FLAG_ERR_NERR))
{
usart_data_receive(UART7);
usart_interrupt_flag_clear(UART7,USART_INT_FLAG_ERR_NERR);
}
if(RESET != usart_interrupt_flag_get(UART7, USART_INT_FLAG_ERR_FERR))
{
usart_data_receive(UART7);
usart_interrupt_flag_clear(UART7,USART_INT_FLAG_ERR_FERR);
}
5、串口接收发送结构体定义
/*COM Received Data Structure*/
typedef struct
{
uint8_t ubr_EndFlag; //Received data end flag
uint8_t ubr_buffer[300]; //Received data buffer
uint8_t ubr_bufferTemp[300]; //Received data buffer temp
uint16_t ubr_Dindex; //Received data index
uint16_t ubr_DLen; //Received data len
}ComRevData;
/*COM Send Data Structure*/
typedef struct
{
uint8_t ubs_Index; //send index
uint8_t ubs_Len; //send len
uint8_t ubs_Buffer[255]; //Send data buffer
uint8_t ubs_BufferTemp[255]; //Send data buffer temp
}ComSendData;
6、串口中断定义
void USART5_IRQHandler(void)
{
BaseType_t xHigherPriorityTaskWoken = false;
volatile uint8_t Revdata = 0;
if(RESET != usart_interrupt_flag_get(USART5, USART_INT_FLAG_RBNE))
{
usart_interrupt_flag_clear(USART5,USART_INT_FLAG_RBNE);
Revdata = (uint8_t)usart_data_receive(USART5);
Usart5RevData.ubr_bufferTemp[Usart5RevData.ubr_Dindex++] = Revdata;
if(Usart5RevData.ubr_Dindex >= 300)
{
Usart5RevData.ubr_Dindex = 0;
}
}
if(RESET != usart_interrupt_flag_get(USART5, USART_INT_FLAG_IDLE))
{
usart_data_receive(USART5);
usart_interrupt_flag_clear(USART5, USART_INT_FLAG_IDLE);
if(判断数据内容是否是自己想接收的数据)
{
usart_receive_config(USART5, USART_RECEIVE_DISABLE);//失能接收中断
Usart5RevData.ubr_DLen = Usart5RevData.ubr_Dindex;
Usart5RevData.ubr_Dindex = 0;
Usart5RevData.ubr_EndFlag = 1;
}
else
{
Usart5RevData.ubr_Dindex = 0;
}
}
if(RESET != usart_interrupt_flag_get(USART5, USART_INT_FLAG_TBE))
{
usart_interrupt_flag_clear(USART5, USART_INT_FLAG_TBE);
usart_data_transmit(USART5, Usart5SendData.ubs_Buffer[Usart5SendData.ubs_Index++]);
if(Usart5SendData.ubs_Index >= Usart5SendData.ubs_Len)
{
Usart5SendData.ubs_Index = 0;
usart_interrupt_disable(USART5, USART_INT_TBE);
}
}
/*Erro flag*/
if(RESET != usart_interrupt_flag_get(USART5, USART_INT_FLAG_RBNE_ORERR))
{
usart_data_receive(USART5);
usart_interrupt_flag_clear(USART5,USART_INT_FLAG_RBNE_ORERR);
}
if(RESET != usart_interrupt_flag_get(USART5, USART_INT_FLAG_ERR_NERR))
{
usart_data_receive(USART5);
usart_interrupt_flag_clear(USART5,USART_INT_FLAG_ERR_NERR);
}
if(RESET != usart_interrupt_flag_get(USART5, USART_INT_FLAG_ERR_FERR))
{
usart_data_receive(USART5);
usart_interrupt_flag_clear(USART5,USART_INT_FLAG_ERR_FERR);
}
}