为什么 UART 继续写入我的 25 字节缓冲区,它停止了哪个字节?

Why does UART keep continuing to write my 25 byte buffer which byte it left off?

我在 STM32F1 上有一个基于中断 (RXNE) 的接收周期 运行。我只使用接收命令:

HAL_UART_Receive_IT(&huart3, RxBuffer, sizeof(RxBuffer));

因此我收到一条消息然后写入我的缓冲区:

uint8_t RxBuffer[25];

在使用 RxBuffer 的内容后,我正在使用这个函数清除这个数组:

memset(RxBuffer, '[=12=]', sizeof(RxBuffer));

传入的数据永远不会超过 24 字节 btw。一切正常,直到接收到另一个数据并将其写入 RxBuffer。当接收到下一个数据时,发生了一些奇怪的事情,HAL_UART_Receive_IT(&huart3, RxBuffer, sizeof(RxBuffer)); 函数开始将数据填充到我的 RxBuffer 上次接收时它遗漏的字节。

例如;

1 -> RxBuffer 通常初始化为 NULL

RxBuffer = {'[=14=]', '[=14=]', '[=14=]', '[=14=]', ... '[=14=]'} (25 bytes NULL)

2 -> 收到第一个数据后变成这样

RxBufer = "xc32 CMD1 400 200 50" (it's 20 bytes total and last 5 bytes are still NULL)

RxBuffer = {'x', 'c', '3', '2', ' ', 'C' ... '[=16=]', '[=16=]', '[=16=]'}

3 -> 然后我使用 memset(...) 函数清除缓冲区内容。

RxBuffer = {'[=14=]', '[=14=]', '[=14=]', '[=14=]', ... '[=14=]'} (25 bytes NULL again)

4 -> 收到另一个数据如“xc32 CMD2”后:

RxBuffer = {'C', 'M', 'D', '2', '[=19=]', '[=19=]', '[=19=]' ... 'x', 'c', '3', '2', ' '} (still 25 bytes of data but UART begins to write data which byte it left off last time, and it becomes some shifted shit..)

它的行为就像一个环形缓冲区。如何正确执行此接收过程以使其在每次接收时都从缓冲区的第 0 个索引开始?

因为它是中断例程,所以它在后台运行。它将接收数据到这个缓冲区,直到缓冲区结束。

如果您的数据不是固定长度的,您应该启用“空闲”中断并在此中断处理程序中处理数据(或更好地在 HAL 回调中)。然后重启接收。

使用DMA逐字节接收数据可以解决问题。

char rx_buff[10];
HAL_UART_Receive_DMA(&huart1, (uint8_t*)rx_buff, 1);

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    ...
    array[i++] = rx_buff[0];
    /* Then reset buffer using bzero() or memset() */
}