ST意法半导体
直播中

凌流浪

8年用户 1024经验值
擅长:可编程逻辑 电源/新能源
私信 关注
[问答]

NUCLEO64 - G071RBTX如何使用USART2实现Modbus RTU的接收超时中断?

电路板详细信息:NUCLEO64 - G071RBTX
我试图了解使用 USART2 实现 Modbus RTU 的接收超时中断。首先,要检查接收超时中断,我想检查 2 秒超时中断。所以在下面相应地配置了 RTOR 寄存器(如果配置错误请指导)
===
USART2 配置:
波特率=19200
默认所有其他位
===
我在代码生成 (HAL) 之后额外使用的步骤 下面的步骤是在 HAL 配置 USART2 之后编写的。
  • 启用 RXNEIE 中断
  • 启用 RTOIE 中断
  • 启用接收超时(USART2->RTOEN 位已设置)
  • 配置值为 3840002 的 RTOR 寄存器(查看 2 秒后的中断)
           RTOR 的计算结果 = (2000000/ 0.520833)。我参考了这里的计算
  • static void MX_USART2_UART_Init(void)
  • {
  •   /* USER CODE BEGIN USART2_Init 0 */
  •   /* USER CODE END USART2_Init 0 */
  •   /* USER CODE BEGIN USART2_Init 1 */
  •   /* USER CODE END USART2_Init 1 */
  •   huart2.Instance = USART2;
  •   huart2.Init.BaudRate = 19200;
  •   huart2.Init.WordLength = UART_WORDLENGTH_8B;
  •   huart2.Init.StopBits = UART_STOPBITS_1;
  •   huart2.Init.Parity = UART_PARITY_NONE;
  •   huart2.Init.Mode = UART_MODE_TX_RX;
  •   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  •   huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  •   huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  •   huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  •   huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  •   if (HAL_UART_Init(&huart2) != HAL_OK)
  •   {
  •     Error_Handler();
  •   }
  •   if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  •   {
  •     Error_Handler();
  •   }
  •   if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  •   {
  •     Error_Handler();
  •   }
  •   if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  •   {
  •     Error_Handler();
  •   }
  •   /* USER CODE BEGIN USART2_Init 2 */
  •   //By default Receive interrupt is not enabled
  •   //Enable Receive interrupt and receive timeout of USART2
  •   USART2->CR1 |=(1<<26U) | (1<<5U);
  •   USART2->CR2 |=(1<<23U);        //RECEIVER TIMEOUT ENABLE
  •   USART2->RTOR=3840002u;
  •   /* USER CODE END USART2_Init 2 */
  • }
最后在下面的 USART2 IRQ 处理程序中是代码:
IRQ 处理程序中还有一件事,我检查了每一位。这是正确的方法吗?
  • void USART2_IRQHandler(void)
  • {
  •   /* USER CODE BEGIN USART2_IRQn 0 */
  • if((USART2->ISR && 32u))
  • {
  •           unsigned char test=USART2->RDR;
  •           //USART2->ICR |=(1<<11u);        //CLEAR RTOF BIT
  • }
  • else if ((USART2->ISR && 2048u))
  • {
  •         //ENTERED RTOF
  •         unsigned char tester;
  •         tester=0u;
  •         USART2->ICR |=(1<<11u);        //CLEAR RTOF BIT
  • }
  •   /* USER CODE END USART2_IRQn 0 */
  •   HAL_UART_IRQHandler(&huart2);
  •   /* USER CODE BEGIN USART2_IRQn 1 */
  •   /* USER CODE END USART2_IRQn 1 */
  • }
大约 2 秒后不会发生中断。请指导我。








回帖(1)

陈忠阳

2023-1-31 15:51:29
你确定这是正确的吗?


  • if((USART2->ISR && 32u))
  • {
  • //...//
  • }
  • else if ((USART2->ISR && 2048u))
  • {

  • }

也许这就是你的意思


  • if((USART2->ISR & 32u))
  • {
  • //...//
  • }
  • else if ((USART2->ISR & 2048u))
  • {

  • }

这是我连续接收字符序列的程序。


  • static uint8_t _RxChar;
  • static void _receiveAgain(UART_HandleTypeDef *uart_ptr);

  • /// initialization
  • void begin (UART_HandleTypeDef *uart_ptr)
  • {
  •     //.....//
  •     // 1st time
  •     _receiveAgain(uart_ptr);
  • }

  • /// override `HAL_UART_RxCpltCallback`
  • extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *uart_ptr)
  • {
  •     assert(uart_ptr);

  •     // isr code here...

  •     // the received character is in `_RxChar`
  •     _receiveAgain(uart_ptr);
  • }
  • /// override `HAL_UART_TxCpltCallback`
  • extern "C" void HAL_UART_ErrorCallback(UART_HandleTypeDef * uart_ptr)
  • {
  •     assert(uart_ptr);

  •     auto err = HAL_UART_GetError(uart_ptr);

  •     if (err & (HAL_UART_ERROR_ORE | HAL_UART_ERROR_FE | HAL_UART_ERROR_NE | HAL_UART_ERROR_PE))
  •     {
  •         __HAL_UART_CLEAR_FLAG(uart_ptr, UART_IT_ERR);
  •         
  •         //
  •         // isr code here...
  •         //
  •         _receiveAgain(uart_ptr);    // receive again
  •     }
  • }

  • static void _receiveAgain(UART_HandleTypeDef *uart_ptr)
  • {
  •         assert(uart_ptr);
  •         uart_ptr->pRxBuffPtr = &_RxChar;
  •         uart_ptr->RxXferSize = 1;
  •         uart_ptr->RxXferCount = 1;
  •         uart_ptr->ErrorCode = HAL_UART_ERROR_NONE;

  •         // Check if a transmit process is ongoing or not
  •         if (uart_ptr->RxState == HAL_UART_STATE_BUSY_TX) uart_ptr->RxState = HAL_UART_STATE_BUSY_TX_RX;
  •         else uart_ptr->RxState = HAL_UART_STATE_BUSY_RX;

  •         __HAL_UNLOCK(uart_ptr);
  •         __HAL_UART_ENABLE_IT(uart_ptr, UART_IT_PE);
  •         __HAL_UART_ENABLE_IT(uart_ptr, UART_IT_ERR);
  •         __HAL_UART_ENABLE_IT(uart_ptr, UART_IT_RXNE);
  • }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分