使用中断模式与DMA模式进行串口通信

在 STM32 开发中,串口(UART)通信主要有 轮询模式、 中断模式DMA(直接存储器访问)模式 三种方式。其中 中断模式DMA 模式 适用于高效、非阻塞的串口通信。


1. 中断模式(Interrupt Mode)

中断模式(UART Interrupt Mode) 依赖 UART 接收/发送完成 时触发 中断 来处理数据,适用于 低速串口通信或短数据包传输

中断模式的工作原理

  • 发送:调用 HAL_UART_Transmit_IT(),数据传输完成时触发 HAL_UART_TxCpltCallback() 回调函数。
  • 接收:调用 HAL_UART_Receive_IT(),数据接收完成时触发 HAL_UART_RxCpltCallback() 回调函数。
  • CPU 只在数据传输完成时才执行回调函数,减少 CPU 资源占用。

示例代码

① 开启 UART 中断接收

uint8_t rxData[10];  // 接收缓冲区

// 初始化 UART 接收中断(一次接收 1 字节)
HAL_UART_Receive_IT(&huart1, rxData, 1);

② 处理 UART 接收中断

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1)  // 判断是哪个串口
    {
        HAL_UART_Transmit_IT(&huart1, rxData, 1);  // 回显接收的数据
        HAL_UART_Receive_IT(&huart1, rxData, 1);   // 继续接收
    }
}
使用中断接收的方式不需要在循环中重复使用中断接收函数,只需在循环前执行一次,再在接收中断回调函数中继续执行接收即可。

③ 处理 UART 发送中断

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1)
    {
        // 发送完成后可以执行其他操作
    }
}

中断模式的优点

非阻塞:CPU 只在需要时处理数据,空闲时可以执行其他任务。
适用于短数据包通信(比如命令解析、按键输入等)。
比轮询模式更节省 CPU 资源

中断模式的缺点

需要占用 CPU 处理中断,当数据流量较大时,中断频繁触发会影响系统性能
不能高效处理大数据量传输,会影响 CPU 响应时间。


2. DMA 模式(Direct Memory Access Mode)

DMA(直接存储器访问)模式UART 直接通过 DMA 控制器读写内存无需 CPU 介入,适用于 大数据量、高速串口通信(如日志输出、数据采集等)。

DMA 模式的工作原理

  • 发送数据:调用 HAL_UART_Transmit_DMA(),DMA 直接从内存读取数据发送到 UART,不占用 CPU。
  • 接收数据:调用 HAL_UART_Receive_DMA(),DMA 直接将 UART 接收到的数据存入内存,完成后触发 HAL_UART_RxCpltCallback() 回调。

示例代码

① 配置 UART 使用 DMA

uint8_t rxBuffer[100];  // DMA 接收缓冲区

// 开启 DMA 接收(一次性接收 100 字节数据)
HAL_UART_Receive_DMA(&huart1, rxBuffer, sizeof(rxBuffer));

② 处理 DMA 传输完成回调

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1)
    {
        // 数据接收完成,可以处理 rxBuffer 里的数据
        HAL_UART_Transmit_DMA(&huart1, rxBuffer, sizeof(rxBuffer));  // 发送接收到的数据
    }
}

DMA 模式的优点

完全非阻塞:DMA 负责数据搬运,CPU 只在数据完成时处理,不受干扰。
适用于大数据量、高速通信(如 GPS、WiFi、摄像头数据传输)。
CPU 负载低,系统可以执行其他任务(如 RTOS 多任务)。

DMA 模式的缺点

需要额外配置 DMA 控制器,比中断模式复杂。
适合连续大数据传输,不适用于短数据命令交互(比如 AT 命令)。
可能需要管理环形缓冲区(Ring Buffer),避免数据丢失。


3. 中断模式 vs. DMA 模式对比

在 STM32 串口通信中,DMA 模式中断模式 都依赖 中断机制,但它们的 中断触发方式、频率、CPU 负载 有显著区别。以下是两者的详细对比:

3.1. 中断模式的中断触发

触发条件

  • 发送完成中断(Tx Complete Interrupt):每次发送完 1 次完整的数据 后触发。
  • 接收完成中断(Rx Complete Interrupt):每次接收到 指定数量的数据 后触发。

中断触发频率

  • 发送数据每次调用 HAL_UART_Transmit_IT() 都会触发 1 次发送完成中断
  • 接收数据每次调用 HAL_UART_Receive_IT() 都会触发 1 次接收完成中断
  • 如果接收数据是逐字节的,那么每收到 1 个字节 就会触发一次中断,导致中断频率高,影响 CPU 性能

示例:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1)  
    {
        HAL_UART_Transmit_IT(&huart1, rxData, 1);  // 发送回显数据
        HAL_UART_Receive_IT(&huart1, rxData, 1);   // 继续接收
    }
}

问题:如果接收的数据流量大,每个字节都触发一次 HAL_UART_RxCpltCallback(),会导致 CPU 频繁处理中断,降低系统响应能力。


3.2. DMA 模式的中断触发

触发条件

  • 发送完成中断(Tx DMA Complete Interrupt):整个 DMA 传输 全部数据 结束后触发。
  • 接收完成中断(Rx DMA Complete Interrupt):整个 DMA 缓存区接收满指定的字节数到达 时触发。

中断触发频率

  • 由于 DMA 直接传输整个数据块,相比中断模式 减少了大量的中断触发
  • 例如,使用 DMA 方式接收 100 字节数据,仅在100 字节全部接收完成时触发一次中断
  • 相比中断模式,DMA 方式极大地降低了中断频率,提高了系统效率。

示例:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1)  
    {
        // 一次性接收100字节数据
        HAL_UART_Transmit_DMA(&huart1, rxBuffer, 100);  
        HAL_UART_Receive_DMA(&huart1, rxBuffer, 100);   // 继续接收
    }
}

优势:DMA 只在整个数据块传输完成时触发 1 次中断,而不是逐字节触发,提高了 CPU 的可用性。


3.3. 触发中断次数对比

方式触发中断条件触发次数(假设 100 字节)适用场景
中断模式每接收 1 个字节触发100 次中断低速数据、小数据包
DMA 模式整个缓冲区满了 触发1 次中断高速数据、大数据流

3.4. 中断模式 vs. DMA 模式:中断影响

方式中断触发频率CPU 负载适用于
中断模式高(逐字节触发)高(CPU 处理开销大)短数据、低速通信(如 AT 指令)
DMA 模式低(整块数据传输完成后才触发)低(CPU 只需处理一次中断)高速数据、大数据量(如 GPS、日志记录)

3.5. 总结

如果数据量小(例如 AT 指令交互),使用 中断模式,因为它简单易用。
如果数据量大(如 WiFi 模块、传感器数据采集),必须用 DMA 模式,减少 CPU 负载,提高效率。
DMA 模式大幅减少了中断次数,适用于 高速数据传输,尤其是 RTOS 或多任务系统

如果你的项目涉及 高频率串口通信,比如传感器数据流、日志记录等,DMA 绝对是最优选择! 🚀


4. 什么时候用哪种模式?

如果数据量较小(命令解析、调试信息)→ 选用中断模式
如果数据量较大(日志存储、传感器数据)→ 选用 DMA 模式
如果数据量很小,但 CPU 负载高 → 也可以考虑 DMA。

例如:

  • 调试信息(printf 串口输出):中断模式
  • GPS 数据流:DMA 模式
  • 按键输入解析:中断模式
  • WiFi 模块(AT 指令):中断模式(少量指令),DMA(大量数据)

5. 总结

  • 中断模式(Interrupt Mode) 适用于 短数据包、低速通信,如 按键输入、AT 指令解析
  • DMA 模式(Direct Memory Access Mode) 适用于 大数据流、高速通信,如 GPS 传输、日志存储
  • DMA 优先级高于中断,在高负载系统中推荐使用 DMA,避免 CPU 过载。

如果你的 STM32 需要处理大数据的串口通信,建议 使用 DMA 模式,否则中断模式即可满足需求! 🚀

上一篇
下一篇