1

我对 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);
  }

}
4

1 回答 1

0

我要做的第一件事是禁用所有你没有明确使用的中断。至少,这应该有助于确定罪魁祸首。__HAL_UART_DISABLE_IT()通过传入要禁用的中断来使用宏执行此操作。

如果这不起作用,请尝试确认TXE中断被UART_Transmit_IT()IRQ 调用的函数禁用。确定这是否是问题的一种快速方法可能是手动禁用中断(当您的问题发生时)并查看 IRQ 是否停止触发。否则,您可以尝试中断UART_Transmit_IT()函数并查看该__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);行是否被执行。如果TXE中断在完成后没有被正确禁用,它将继续触发 - 导致类似于您所看到的情况。

于 2016-04-27T15:53:56.963 回答