STM32 HAL库极简入门:串口通信
本文最后更新于54 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

前言

在没有显示屏的情况下,我们如何知道程序运行到了哪一步?传感器采集的数据是多少?串口可以将单片机中的变量、状态等信息发送到各种设备上。今天,我们就来搞定 STM32 的 UART 发送与接收。


一、 串口通信基础:UART 是什么?

UART(通用异步收发传输器)是一种简单的串行通信协议。它只需要两根线:

  • TX (Transmit):发送数据。
  • RX (Receive):接收数据。

(请先共地)

核心参数(必须两端一致):

  1. 波特率 (Baud Rate):通信速度(如 115200 bps)。
  2. 停止位 (Stop Bits):标志一帧数据的结束。
  3. 校验位 (Parity):用于奇偶校验,通常设为 None。

二、 实战步骤:串口打印与数据回传

我们将实现两个功能:

  1. 每隔一秒向电脑发送“Hello STM32!”。
  2. 串口中断回传:电脑发给单片机什么,单片机就立刻原样回传(Echo)。

1. CubeMX 配置

  • 选择引脚:在左侧菜单栏选择 Connectivity -> USART1
  • 模式设置:Mode 选择 Asynchronous(异步模式)。
  • 参数设置
    • Baud Rate: 115200 Bits/s
    • Word Length: 8 Bits
    • Parity: None
    • Stop Bits: 1
  • 开启中断 (重点):点击 NVIC Settings 选项卡,勾选 USART1 global interruptEnabled。这是实现高效接收的关键。
  • 生成代码:点击右上角 GENERATE CODE。

2. 编写逻辑代码

功能一:阻塞式发送 (Polling Mode)

main.cwhile(1) 循环中,我们可以直接发送字符串。

/* USER CODE BEGIN WHILE */
while (1)
{
    char msg[] = "Hello STM32! \r\n";
    // 参数:串口句柄,数据指针,数据长度,超时时间(ms)
    HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 100);

    HAL_Delay(1000);

    /* USER CODE END WHILE */
}
功能二:中断式接收 (Interrupt Mode)

阻塞式接收(HAL_UART_Receive)会让程序死等,效率极低。实际开发中,我们使用中断

第一步:开启接收中断
main() 函数的 /* USER CODE BEGIN 2 */ 区域调用一次:

/* USER CODE BEGIN 2 */
uint8_t rxBuffer; // 定义一个接收缓冲区(单个字节)
// 开启接收中断,每收到 1 个字节触发一次中断
HAL_UART_Receive_IT(&huart1, &rxBuffer, 1);
/* USER CODE END 2 */

第二步:编写回调函数
main.c 的末尾(USER CODE BEGIN 4 区域)编写中断触发后的逻辑。

/* USER CODE BEGIN 4 */
// 当串口接收到指定数量的数据后,HAL库会自动调用这个回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        // 1. 将接收到的数据原样发回
        HAL_UART_Transmit(&huart1, &rxBuffer, 1, 10);

        // 2. 重新开启中断(非常重要!HAL库的中断接收是一次性的)
        HAL_UART_Receive_IT(&huart1, &rxBuffer, 1);
    }
}
/* USER CODE END 4 */

3. 终极技巧:重定向 printf

每次都写 HAL_UART_Transmit 太麻烦了?我们可以把 C 语言的标准 printf 函数重定向到串口,这样就能像在电脑上编程一样使用 printf 了。

main.c 中添加以下代码(需 #include <stdio.h>):

/* USER CODE BEGIN 0 */
#ifdef __GNUC__
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}
/* USER CODE END 0 */

注:如果你使用的是 Keil,记得在 Project Settings 里勾选 “Use MicroLIB”。

现在,你可以在代码里随处调用 printf("传感器数值: %d \r\n", sensor_value); 了!


三、 常见问题与坑 (Troubleshooting)

  1. 串口助手乱码
    • 检查波特率是否匹配(工程里是 115200,助手也要设为 115200)。
    • 检查外部晶振频率是否与 CubeMX 中配置的一致。
  2. 只能发不能收
    • 检查 HAL_UART_Receive_IT 是否在 while(1) 之前调用了。
    • 检查是否在回调函数里忘记了再次开启中断。
  3. printf 无输出
    • 检查是否勾选了 “Use MicroLIB”。
    • 确保 fputc 重定向代码已正确添加。

四、 总结

UART 是 STM32 最基础也最重要的外设之一。

  • 发送:简单打印调试信息,推荐重定向 printf
  • 接收:推荐使用中断模式(HAL_UART_Receive_IT),或者更高级的 DMA + 串口空闲中断(适合处理长数据包,我们以后再聊)。

学会了串口,你就拥有了观察程序内部运行的“超能力”。



[下一篇预告:STM32 中断系统与按键消抖]

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇