之前一直使用F4的片子,现在替换成H7。原以为只是简单的替换一下HAL就可以正常运行,但是在实际测试中发现不少问题,串口ORE就是其中之一。
ORE全拼为overrun error即溢出错误,当数据寄存器中的数据还未读取处理,新的数据又来了,导致溢出,硬件自动置位,需要软件清除。如果不主动清除该位,后续数据是接收不了的,串口“挂死”。
F4、H7的串口接收函数实现方式类似,都是等待“接收非空标志被置位,然读取数据寄存器”,都是软件清除ORE标志,但是具体实现不同。F4是先读取SR寄存器,再读取DR寄存器,即清除了ORE标志,由于“接收非空RXNE”和“溢出错误ORE”都位于SR寄存器中(分别是bit5、bit3),因此F4芯片只需要调用HAL_UART_Receive 函数就会自动清除ORE标志。
编辑切换为居中
F4手册中描述
H7芯片向 USART_ICR 寄存器中 ORECF 位写1,即可清除。其库函数HAL_UART_Receive 没有此操作,因此需要编写人员主动清除。
编辑切换为居中
H7手册中描述
除此之外,我还发现H7芯片还可以屏蔽溢出检测,只需要在初始化时将CR3中bit12写‘1’.
H7屏蔽串口溢出检测初始化配置:
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
UartHandle.Init.ClockPrescaler = UART_PRESCALER_DIV1; UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT; UartHandle.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE; HAL_UART_DeInit(&UartHandle);
HAL_UART_Init(&UartHandle);