串口溢出中断如何处理ORE

发布于:2024-07-26 ⋅ 阅读:(149) ⋅ 点赞:(0)

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);
	}
}


网站公告

今日签到

点亮在社区的每一天
去签到