0

我正在为 STM32F4 编写软件。STM32 需要通过 UART 拉入一个字符串。该字符串的长度可变,并且每秒从一个传感器输入。字符串存储在一个固定的缓冲区中,因此缓冲区内容不断变化。

传入的字符串如下所示:“A12941;P2507;T2150;C21;E0;”

UART的设置:

  • 波特率:19200
  • 字长:8Bits
  • 奇偶校验:无
  • 止损:1
  • 过采样:16 个样本
  • 全局中断:启用
  • 无 DMA 设置

main.c 函数中使用的部分代码:

uint8_t UART3_rxBuffer[25];

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    HAL_UART_Receive_IT(&huart3, UART3_rxBuffer, 25); //restart interrupt reception mode

    
int main(void)
{  
  HAL_UART_Receive_IT (&huart3, UART3_rxBuffer,25);
}
  while (1)
  {
  }
}

stm32f4xx_it.c中的部分代码

void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */
  /* USER CODE END USART3_IRQn 1 */
}

以这种方式用变量字符串填充缓冲区确实有效,但由于缓冲区不断被补充,因此很难提取字符串的开头和结尾。例如,缓冲区可能如下所示: [0]'E' [1]'0' [2]'/n' [3]'A' [4]'1' [5]'2' [6] '9' [7]'4' [8]'1' [9]';' [10]'P'等....但我想要一个从'A'开始的缓冲区。

我的问题是,如何正确处理 uart 上的传入字符串,以便我只有字符串“A12941;P2507;T2150;C21;E0;”?

提前致谢!!

4

2 回答 2

0

我可以看到三种可能性:

  1. 在中断中完成所有处理。当您到达可变长度消息的末尾时,然后执行您需要对信息执行的所有操作,然后更改位置变量以重新从头开始填充缓冲区。

  2. 并行使用(至少)两个缓冲区。当您在中断上下文中检测到可变长度消息的结尾时,然后开始从位置零填充不同的缓冲区并向主上下文发出信号,表明前一个缓冲区已准备好进行处理。

  3. 串联使用两个缓冲器。让中断以循环方式填充环形缓冲区,不注意消息何时结束。在主上下文中,从上一条消息的末尾开始扫描,看看您是否还有整条消息。如果这样做,则将其复制到另一个缓冲区中,使其从缓冲区的开头开始。记录下一次在环形缓冲区中完成的位置,然后在线性缓冲区上进行处理。

选项 1 仅适用于您可以在少于发送器发送下一或两个字节的时间内完成所有处理的情况。其他两个选项使用更多的内存并且实现起来有点复杂。只要您足够频繁地轮询新消息,就可以使用循环模式 DMA 实现选项 3,从而避免需要中断。如果您的主上下文可能没有足够频繁地轮询,选项 2 允许将多条消息排队。

于 2021-04-23T06:42:15.943 回答
0

我想分享一个与您的问题相关的示例代码。但是,这不是您要寻找的。您可以根据需要编辑此代码段。如果我没记错的话,您也可以根据选项 3 对其进行编辑。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART2) {
    HAL_UART_Receive_IT(&huart2,&rData,1);

    rxBuffer[pos++] = rData;
    if (rData == '\n') {
        pos = 0;
    }
}

在开始之前,在 main 函数中,在 while 循环之前,您应该使用“HAL_UART_Receive_IT(&huart2,&rData,1);”启用一个字节的中断。如果您的传入数据具有像“\n”这样的限制器,那么您可以保存每个帧可能具有不同长度的整个数据。

如果您希望数据框以某个特定字符开头,那么您可以等待保存数据,直到您获得该字符。在这种情况下,您可以通过将 '\n' 更改为您的字符来编辑此代码,并且在获得该字符后,您应该开始将以下数据保存到缓冲区内。

于 2021-04-25T15:45:43.883 回答