关于stm32不断进入串口中断的问题
2016-10-12 12:44 小竹心语 阅读(8215) 评论(0) 编辑 收藏 举报问题说明:比如说我串口中断函数执行时间是2s,在2s内再次发生串口中断,就会造成无法进入接收中断
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
led_toggle();
delay_ms(1000);
delay_ms(1000);
}
}
具体现象就是串口发送数据给单片机,led灯不会闪烁,但是用示波器观察单片机的RX脚,每次触发都有信号,说明串口是有把信号给单片机的。
于是做了下面这样的测试
void USART2_IRQHandler(void) { led_toggle(); delay_ms(1000); delay_ms(1000); }
当进入串口中断后在2s内再次通过串口给单片机发送数据,则led灯会一直闪烁(每隔2s)即使没有再给单片机发送数据,led灯也会一直闪烁,是什么原因造成单片机一直进入串口中断呢?
于是做了下面这样的测试
void USART2_IRQHandler(void) { led_toggle(); delay_ms(1000); delay_ms(1000); if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_RXNE); UART_RxBuf[0] = USART_ReceiveData( USART2 ); } if(USART_GetITStatus(USART2,USART_IT_ORE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_ORE); UART_RxBuf[0] = USART_ReceiveData( USART2 ); } if(USART_GetITStatus(USART2,USART_IT_PE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_PE); } if(USART_GetITStatus(USART2,USART_IT_TXE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_TXE); } if(USART_GetITStatus(USART2,USART_IT_TC) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_TC); } if(USART_GetITStatus(USART2,USART_IT_IDLE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_IDLE); } if(USART_GetITStatus(USART2,USART_IT_LBD) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_LBD); } if(USART_GetITStatus(USART2,USART_IT_CTS) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_CTS); } if(USART_GetITStatus(USART2,USART_IT_ERR) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_ERR); } if(USART_GetITStatus(USART2,USART_IT_NE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_NE); } if(USART_GetITStatus(USART2,USART_IT_FE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_FE); } }
发现触发中断的条件一种都不满足,但还是一直进入中断,查资料后发现
stm32中文参考手册541业
ORE:过载错误 (Overrun error) 当RXNE仍然是’1’的时候,当前被接收在移位寄存器中的数据,需要传送至RDR寄存器时,硬 件将该位置位。如果USART_CR1中的RXNEIE为’1’的话,则产生中断。由软件序列将其清零 (先读USART_SR,然后读USART_CR)。 0:没有过载错误; 1:检测到过载错误。 注意:该位被置位时, RDR寄存器中的值不会丢失,但是移位寄存器中的数据会被覆盖。如果 设置了EIE位,在多缓冲器通信模式下, ORE标志置位会产生中断的 |
解决方法,在串口初始化配置时,打开ORE溢出中断
USART_Init(USART2, &USART_InitStructure); //初始化串口4 USART_ClearFlag(USART2, USART_FLAG_RXNE);//防止配置完就进入中断 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_ITConfig(USART2, USART_IT_ORE, ENABLE);//开启串口溢出中断 USART_Cmd(USART2, ENABLE);
void USART2_IRQHandler(void) { led_toggle(); delay_ms(1000); delay_ms(1000); if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_RXNE); UART_RxBuf[0] = USART_ReceiveData( USART2 ); } if(USART_GetITStatus(USART2,USART_IT_ORE) != RESET) { USART_ClearITPendingBit(USART2,USART_IT_ORE); UART_RxBuf[0] = USART_ReceiveData( USART2 ); //这步一定要有的,相当于清空缓存区 } }