1

我有一些(主要是 CubeMX 生成的)代码:

volatile uint8_t buf[4];

int main(void)
{
    ...
    HAL_UART_Receive_IT(&huart3, buf, sizeof(buf));
    while (1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART3) {
        HAL_UART_Transmit(&huart3, buf, sizeof(buf), 0xFFFF);
        HAL_UART_Receive_IT(&huart3, buf, sizeof(buf));
    }
}

这成功地回显了 USART3 上接收到的所有内容。(此代码只是了解串行端口的一次性示例。)

我担心HAL_UART_RxCpltCallback()被调用和HAL_UART_Receive_IT()设置下一个接收之间的时间。

STM32F103有什么功能可以保证这个时间间隔内数据不会丢失吗?我没有发现任何证据表明 USART 上有超过两个字节的接收缓冲区。

我特别担心某些更高优先级的 USB 设备活动可能会延迟调用HAL_UART_RxCpltCallback(),因此可能会丢失一个或多个字符。

4

1 回答 1

2

快速回答:

HAL_UART_Transmit 是一个阻塞函数,所以在它完成之前不会调用 HAL_UART_Receive_IT 并且 uart 肯定会溢出。如果您担心任何其他中断会抢占您的执行,请在发出命令时使用 dma 或禁用麻烦的中断。您也可以提高 UART 中断优先级,但是....

提示:

....您不应在 HAL_UART_RxCpltCallback 中调用 HAL_UART_Transmit 和 HAL_UART_Receive_IT,因为您处于 ISR 模式。这会导致某些版本的 HAL 框架出现一些附带问题。最好设置一个标志并从主代码中检查它。

你也应该避免使用 volatile,如果你使用像 gcc 这样的编译器屏障会更好__asm volatile("" ::: "memory")

于 2020-01-13T12:42:26.157 回答