我对 USART 行为有疑问,想知道你们是否可以提供帮助!我正在使用一个 STM32F303,它的三个 USART 正在使用中,其中 USART1 配置为异步 RS485 端口,其 DE 线自动控制。微控制器的 TX、RX 和 DE 引脚连接到 TI SN65HVD1792 RS485 收发器,该收发器向用户提供四根线(TX+、TX-、RX+、RX-)进行通信。
我正在使用中断驱动的 USART 通信,在大多数情况下都可以正常工作。但是,我在处理 RS485 链路配置为双线(TX+/RX+ 和 TX-/RX- 连接在一起,以形成用于两者的 +ve/-ve 线对的错误情况时遇到问题)传输和接收)并且总线上的多个设备尝试同时传输。发生这种情况时,STM32 将停止响应所有串行通信,直到重新上电。
仔细看看发生了什么,我看到 stm32f3xx_it.c 中的 USART1_IRQHandler 被反复调用——一遍又一遍,直到我重新启动电路板。这会调用stm32f3xx_hal_uart.c中的HAL_UART_IRQHandler(&huart1),其作用是检查发生了哪个中断(奇偶校验错误、帧错误、噪声错误、溢出、从停止中唤醒、rx寄存器不为空、tx准备好、tx完成),适当处理,然后清除中断状态。但是,这些特定中断都没有被识别为已触发 - 执行只是通过所有“if”语句,函数退出,然后再次运行 - 无休止。
我找不到任何方法来识别这已经发生,因为它不会抛出任何公认的错误条件。我知道 RS485 总线冲突是应该通过良好的系统设计来避免的,但我们不能排除在客户安装系统时会发生这种情况的可能性 - 它需要能够识别错误,忽略“冲突”消息并继续 - 需要重新启动它是不可接受的。
有没有人知道如何识别这种情况/阻止系统进入中断循环?
提前致谢
中断例程如下(HAL 文件版本 1.2.0,日期 15 年 11 月 13 日)
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
/* UART parity error interrupt occurred -------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);
huart->ErrorCode |= HAL_UART_ERROR_PE;
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
}
/* UART frame error interrupt occurred --------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);
huart->ErrorCode |= HAL_UART_ERROR_FE;
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
}
/* UART noise error interrupt occurred --------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);
huart->ErrorCode |= HAL_UART_ERROR_NE;
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
}
/* UART Over-Run interrupt occurred -----------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
huart->ErrorCode |= HAL_UART_ERROR_ORE;
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
}
/* Call UART Error Call back function if need be --------------------------*/
if(huart->ErrorCode != HAL_UART_ERROR_NONE)
{
HAL_UART_ErrorCallback(huart);
}
/* UART wakeup from Stop mode interrupt occurred -------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_WUF) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_WUF) != RESET))
{
__HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF);
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
HAL_UARTEx_WakeupCallback(huart);
}
/* UART in mode Receiver ---------------------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET))
{
UART_Receive_IT(huart);
/* Clear RXNE interrupt flag */
__HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
}
/* UART in mode Transmitter ------------------------------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE) != RESET))
{
UART_Transmit_IT(huart);
}
/* UART in mode Transmitter (transmission end) -----------------------------*/
if((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET))
{
UART_EndTransmit_IT(huart);
}
}