别着急,坐和放宽
STM32G0B1系列的单片机,使用软件RS485通信。频繁进入HAL_UART_ErrorCallback。
因为在错误回调中做过清错误的处理,一直都功能正常,直到今天偶然间才发现这个问题。
错误寄存器显示ORE,NE,FE,PE错误,ORE为溢出错误,NE/FE为噪声错误/帧错误。
初步判定我的软件485收发切换不及时导致。
折腾了一天,测试结果现象如下:
1.发现问题之后,我怀疑我自己封装的驱动调用路径太长。所以用CubeMX新建了一个工程,新工程中没有复现该现象。我理解为现在STM32的HAL库中,提供的HAL_UART_TxCpltCallback就是说明TC中断触发,所以在里面切换为接收模式。在发送前切换为发送模式。
2.把CubeMX的收发方式移植到我的工程中,问题依旧。
3.注释掉其他代码,问题解决。
4.检查HAL库代码,感觉没什么问题。将工程的485改成硬件485问题解决。
5.使用-O0和-Ofast编译,进入错误中断的频率明显是-O0高很多。
现在疑惑:
我如下这样方式使用串口,加上自己的逻辑后,为什么会导致收发切换来不及?从而进入串口错误回调函数。
/**
* @brief UART发送完成回调函数
* @note 当一包数据发送完成时调用,用于RS485切换回接收模式
*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart1) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
} else if (huart == &huart2) {
} else if (huart == &huart3) {
}
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1)
{
HAL_UARTEx_ReceiveToIdle_IT(&huart1, rx_buffer1, RX_BUF_SIZE);
}
}
int main(void)
{
...
while (1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
uint8_t cmd = 0x02;
HAL_UART_Transmit_IT(&huart1, &cmd, 1);
HAL_Delay(10);
}
}
虽然改成硬件485之后得以解决。但是还是没想通为啥。