实践场景:
提示:这里简述项目相关背景:
STM32板子型号:STM32F103RBT6
内容:将RTC的初值设置为23:59:55,并将时间显示在LCD屏上,通过串口发送"XX:XX:XX",XX分别表示时、分、秒,可以完成时钟的重新配置。若发送数据不符合规定,则不做更改。
使用的串口类型:蓝桥杯比赛的串口
AccessPort
问题描述
串口接收中断出现的问题:
1、串口只能执行第一次接收中断,并在LCD屏幕上成功显示
2、第二次通过串口发送数据时,debug查看发现接收时数据出现错误,表现为接收数据第二位开始才是有效值,之后再进行发送则不再进入接收中断
3、(作者也不知道的问题)在通过对1和2的问题进行修改之后(方法在后面),重新注释掉修改的代码进行编译,发现问题也不会重新出现,如果有知道原因的朋友,欢迎评论区探讨。
一、有问题的串口配置:
u8 uart_buf[8];
u8 uart_count=0;
_Bool rtc_flag = 0 ;
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit (USART2, USART_IT_RXNE);
/* Read one byte from the receive data register */
uart_buf [uart_count++] = USART_ReceiveData(USART2);
if(uart_count >= 8)
{
uart_count = 0;
rtc_flag = 1;
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
}
}
}
中断的开启:
USART_Cmd(USART2, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
以上的配置一开始只能进行一次正常的数据接收。
解决办法:
通过
IDLE中断
和RXNE中断
结合: 实现接收一个字节,产生RXNE中断
,一帧数据(串口一次接收的数据)接收后 ,产生IDLE中断
。
例:串口收到一个字节,产生8次
RXNE中断
和1次IDLE中断
。
一帧数据:
比如说单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。IDLE中断
就是串口收到一帧数据后产生的中断。
解决方案:
IDLE中断
一、F1系列的单片机:“先读SR寄存器,再读DR寄存器”。
二、F0系列的单片机:需要用ICR寄存器清楚。
由于我用的是F1系列的单片机,处理方法如下:
1、串口初始化函数中,使能
IDLE中断
:
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
2、串口中断函数中,添加
IDLE中断
处理:
else if(USART_GetITStatus(USART2,USART_IT_IDLE) != RESET)//接收到一帧数据
{
USART2->SR;//先读SR
USART2->DR;//再读DR
uart_count = 0;
printf("%s", uart_buf);
}
最后一个问题:就是在编译了一次
IDLE中断
处理之后,再注释掉添加的IDLE中断
,就没有出现原来的问题了,不是很明白是怎么回事。不过加上IDLE中断
是真的不用担心是不是接受完一帧数据了。
完整代码链接: STM32F103RBT6单片机修改RTC时钟初值的串口接收中断问题。.
原帖地址: https://blog.csdn.net/main_h_/article/details/55668953.
十分感谢原帖楼主的分享。