为什么 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() */
}
我在 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() */
}