STM32 UART 串口通信代码指南

适用芯片:STM32 / ESP32 / Arduino / AVR

STM32 UART 串口通信是嵌入式开发中最基础也是最重要的通信方式之一。无论是调试打印日志、与传感器通信,还是与上位机数据交互,STM32 UART 都扮演着核心角色。本文将全面讲解 STM32 HAL 库的 UART 配置与使用方法,同时涵盖 ESP32 和 Arduino 的串口代码示例,帮助你快速掌握嵌入式串口通信开发。

一、STM32 HAL 库 UART 初始化代码(最常用)

// USART2 初始化:115200, 8N1, TX=PA2, RX=PA3
// 定义一个 UART 句柄(handle),用于操作 USART2
UART_HandleTypeDef huart2;

// 函数:初始化 USART2(115200 波特率,8 位数据,1 停止位,无校验)
void MX_USART2_UART_Init(void) {
    // 指定使用哪个硬件外设:STM32 的 USART2
    huart2.Instance = USART2;

    // 设置波特率:115200 bps(常见调试速率)
    huart2.Init.BaudRate = 115200;

    // 数据位:8 位(标准)
    huart2.Init.WordLength = UART_WORDLENGTH_8B;

    // 停止位:1 位(标准)
    huart2.Init.StopBits = UART_STOPBITS_1;

    // 校验位:无(None)
    huart2.Init.Parity = UART_PARITY_NONE;

    // 模式:发送 + 接收(双向通信)
    huart2.Init.Mode = UART_MODE_TX_RX;

    // 硬件流控:关闭(不使用 RTS/CTS)
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;

    // 过采样:16 次(提高抗噪能力,推荐)
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;

    // 初始化 UART,若失败则进入错误处理
    if (HAL_UART_Init(&huart2) != HAL_OK) {
        Error_Handler();  // 自定义错误函数(死循环或 LED 闪烁)
    }
}

// 发送字符串(阻塞模式)
HAL_UART_Transmit(&huart2, (uint8_t*)"Hello\r\n", 7, HAL_MAX_DELAY);
// ↑ 使用 huart2 发送 7 个字节,HAL_MAX_DELAY = 一直等直到发完

// 接收单字节(轮询模式,阻塞等待)
uint8_t rx;                                      // 接收缓冲区
HAL_UART_Receive(&huart2, &rx, 1, HAL_MAX_DELAY); // 一直等,直到收到 1 字节

// 中断接收(推荐!不阻塞 CPU)
HAL_UART_Receive_IT(&huart2, &rx_byte, 1);       // 开启中断,收到 1 字节就进回调

// 中断回调函数(在 stm32fxx_it.c 或 main.c 中实现)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART2) {             // 确认是 USART2 触发的中断
        // rx_byte 已被自动填入数据
        // 处理完后必须重新开启中断,否则只收一次
        HAL_UART_Receive_IT(&huart2, &rx_byte, 1);
    }
}

二、ESP32 UART 串口编程(Arduino IDE)

void setup() {
    // 初始化默认串口 UART0
    // TX = GPIO1, RX = GPIO3(ESP32 开发板默认 USB 转串口)
    Serial.begin(115200);

    // 初始化 UART2,自定义引脚
    // 参数:波特率、格式、RX 引脚、TX 引脚
    Serial2.begin(115200, SERIAL_8N1, 16, 17);
    // SERIAL_8N1 = 8 数据位,無校验,1 停止位
}

void loop() {
    // 通过 USB 串口打印(连接电脑可见)
    Serial.println("Hello ESP32");

    // 检查 UART2 是否有数据到达
    if (Serial2.available()) {
        // 读取 1 字节并转发到 USB 串口
        Serial.write(Serial2.read());
    }

    // 延时 100ms,避免 CPU 占满
    delay(100);
}

三、Arduino 串口通信代码示例

void setup() {
    // 初始化硬件串口(连接 USB 芯片)
    // TX = 数字引脚 1, RX = 数字引脚 0
    Serial.begin(9600);  // 波特率 9600(Arduino 经典速率)
}

void loop() {
    // 发送字符串 + 换行(串口监视器自动换行)
    Serial.println("Hello Arduino");

    // 检查是否有数据从电脑发来
    if (Serial.available()) {
        char c = Serial.read();      // 读取 1 字节
        Serial.print("Recv: ");      // 回显提示
        Serial.println(c);           // 打印收到的字符
    }

    // 延时 100ms,降低 CPU 负载
    delay(100);
}

四、STM32 UART 常用串口引脚速查表

芯片 外设 TX RX 备注
STM32F103 USART1 PA9 PA10 开发板常用
STM32F103 USART2 PA2 PA3 CH340 串口
ESP32 UART0 GPIO1 GPIO3 默认调试口
ESP32 UART2 GPIO17 GPIO16 常用扩展
Arduino Uno Serial 1 0 数字引脚(D1/D0)

使用提示

  • STM32:需在 CubeMX 中使能对应引脚复用
  • ESP32:UART0 常用于 Serial.print() 调试
  • ArduinoSerial.begin() 自动使用 D0/D1,避免与其他设备冲突

五、总结

STM32 UART 串口通信是嵌入式开发的基础技能。通过本文,你已经掌握了:

  • STM32 HAL 库的 UART 初始化配置(波特率、数据位、停止位、校验位)
  • 阻塞发送和中断接收两种数据传输方式
  • ESP32 和 Arduino 的串口编程方法
  • 常用单片机的默认串口引脚配置

掌握 STM32 UART 通信,能够让你在嵌入式项目中实现设备间的数据交互、日志输出和远程调试等功能。


相关阅读

  • [[04-硬件平台/ESP32-C3引脚指南]] - ESP32-C3 完整引脚配置
  • [[04-硬件平台/Arduino-UNO引脚指南]] - Arduino UNO 引脚详解
  • [[06-FreeRTOS/Day3-通信机制]] - FreeRTOS 串口通信实战

延伸阅读