STM32(GD32)串口通信ORE(overrun error)导致死机
STM32串口通信ORE(overrun error)导致死机
现象就是:我要接收到16个字节到数据后就开始处理数据,但是主机发过来的指令超过了16个字节,就导致我这里死机了,其实我这里不应该死机的,因为波特率才9600,一个字节的时间来处理中断代码完全够用。
怎么掉进坑的呢:因为我在接收中断处理函数里加了发送字符的函数putchar,也就是当我接收到16个字节时,我就在中断函数里给主机回复“ok”这两个字符。这就完蛋了,如果主机发了16个字节不发了,那没问题,如果发了16个字节还在发,就overrun了。悲催。
原来用的是STM32的单片机,HAL库,估计HAL库会出现overrun,但是不会死机,因为在HAL库的串口中断函数里我看有清ORE的功能。但是后来STM32涨价,就换了GD32,用的GD32标准库,然后就进坑了。
下面是STM32 HAL库的void USARTx_IRQHandler(void),对各种错误是有处理的。
在USART的SR(状态寄存器)出现overrun标志后如何清掉呢
先读一下SR寄存器,然后再读一下DR寄存器。
在HAL库里感觉还有一个USART_ICR寄存器,但是手册里没有,在库的USART_TypeDef;里有定义。偏移地址是0x20
在GD32的库里也有一个偏移20的定义
看注解的话,这两个应该是对应的了
HAL库里的__HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);这个清标志就是:
#define __HAL_UART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__))
我想找到在GD32里清这个标志的函数,应该就是下面这个了
但是和STM32不同的是,这里是一下清RBNE和ORERR两个标志,HAL库是只清UART_CLEAR_OREF这一个标志
不管了,还是解决问题吧,在串口中断里判断如果发生了ORE错误中断,就清这个中断标志,然后再读下SR和DR,这应该可以了吧。
关键是把中断函数里的putchar()函数给去了。
【当出现问题时,我是看了别的大神的文章才知道ORE这个问题的,在此感谢!】