问题解决了!
首先,串口不停地进中断是由ORE(overrun error溢出错误)中断引起的。ORE产生的官方描述如下:This bit is set by hardware when the word currently being received in the shift register is ready to be transferred into the RDR register while RXNE=1. An interrupt is generated if RXNEIE=1 in the USART_CR1 register. It is cleared by a software sequence (An read to the USART_SR register followed by a read to the USART_DR register).
大意为:该中断由硬件产生,当移位寄存器中有数据可以发送到RDR寄存器,且RDR寄存器里的数据未被读走时,ORE中断产生,并且ORE标志位置1(前提是USART_CR1中的RXNEIE使能,即使能接收中断)。该中断由软件序列清零(先读USART_SR,再读USART_DR)。
那么,串口溢出是怎么产生的呢?这个主要因为我的外部中断没设计好。。。
UART3有数据进来,产生RXNE中断,当准备读取RSART_RDR时,来了一个优先级更高的外部中断,软件立即跳到外部中断函数中处理中断,然而,这个过程是相当耗时的,大约需要50us。UART3的baudrate为115200,在此期间,串口又来了50/100000*115200/10=0.576个字节,随着时间的推移,总会出现一次处理外部中断时,UART3又来了一个新的字节的情况,从而产生了串中溢出。
串口溢出后,如果不将溢出中断清零,串口就无法再接收闲的数据!
按照STM32F407的datasheet所说,产生溢出后按照前面说的软件序列操作USART_SR和USART_DR就能清零溢出中断,然而,bsp_uart_fifo.c里串口中断函数是这样写的:
if(USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)
{
uint8_t ch;
ch=USART_ReceiveData(_pUart->uart);
..........
}
可是,一旦出现 溢出中断,RXNE就再也不会置位了,也就无法读USART_RDR,导致无法清零ORE中断,从而产生了这个问题。
所以,只要在串口中断函数里加上ORE产生时,你分别读USART_SR和USART_RDR就可以了。
问题解决,安富莱的中断函数是不是应该考虑也加上我说的功能。