跳到主要内容

【UART 串口】任意数据的收发

下载例程代码: 下载代码 如何使用例程【点击查看教程】

通过串口(TYPE-C)接收任意不定长的数据,并将接收到的数据原样返回。

  • 使用UARTEx扩展库,实现不定长数据的接收

  • 使用DMA通道,实现串口数据的快速传输,不占用CPU资源

如何使用例程

  • 编译并下载程序到学习板

  • 使用配套TYPE-C数据线,将学习板连接到计算机

连接usb线
串口

例程讲解

下面介绍了如何自己实现该例程的功能

1、工程配置

  • 打开串口2外设:Pinout&Configuration -> Connectivity -> USART2,将Mode选择为Asynchronous

  • 添加DMA通道:在 USART2 -> Configuration -> DMA Settings 标签卡中,点击 Add 按钮,分别添加 USART2_RX 和 USART2_TX 的 DMA 通道

DMA config
  • 使能串口中断:在 USART2 -> Configuration -> NVIC Settings 标签卡中,勾选 USART2 global interrupt 的 Enable
IT config

2、代码

  • 定义全局变量 rx_data 作为串口接收缓冲区

    由于是不定长数据的接收,因此缓冲区大小可以根据实际需求调整,只能大不能小,否则可能会丢失数据

    // 串口接收缓冲区
    uint8_t rx_data[256] = {0};
  • 在 main 函数中,使用 HAL_UARTEx_ReceiveToIdle_DMA 函数开启不定长数据DMA接收

    注意:需要关闭DMA传输过半中断,我们只需要接收完成中断

    此函数是以空闲中断作为接收完成的标志,而不是接收长度,因此可以接收任意长度的数据

    // 使用Ex函数,接收不定长数据
    HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rx_data, sizeof(rx_data));
    // 关闭DMA传输过半中断(HAL库默认开启,但我们只需要接收完成中断)
    __HAL_DMA_DISABLE_IT(huart2.hdmarx, DMA_IT_HT);
  • 在中断函数 HAL_UARTEx_RxEventCallback 中,处理接收到的数据

    所有的串口接收和发送操作都在中断函数中进行,不会阻塞主程序

    // 不定长数据接收完成回调函数
    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
    {
    if (huart->Instance == USART2)
    {
    // 使用DMA将接收到的数据发送回去
    HAL_UART_Transmit_DMA(&huart2, rx_data, Size);
    // 重新启动接收,使用Ex函数,接收不定长数据
    HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rx_data, sizeof(rx_data));
    // 关闭DMA传输过半中断(HAL库默认开启,但我们只需要接收完成中断)
    __HAL_DMA_DISABLE_IT(huart2.hdmarx, DMA_IT_HT);
    }
    }