STM32F303:RS485总线冲突后重复触发USART中断问题

时间:2016-04-26 10:01:01

标签: interrupt stm32 usart rs485

我遇到了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,日期为11月13日15日)

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

}

1 个答案:

答案 0 :(得分:0)

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

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