告别自言自语,让 STM32 听懂我的话 (UART中断实战)
摘要:之前用 OpenOCD 点亮了呼吸灯,今天决定换个玩法:用 串口 (UART) 跟板子聊天。作为 Linux 嵌入式原生玩家,体验了 VS Code 强大的 Tab 补全功能,随后抛弃轮询拥抱中断。使用 USB-TTL 配合
stm32flash工具进行 ISP 烧录,在 Linux 终端用picocom充当串口助手,踩了“手滑”、括号缺失、引脚配置等坑,最终实现中断回调控制 LED。
时间: 2026.01.07
环境: Ubuntu + VS Code + GCC + Makefile + stm32flash
硬件: STM32F103C8T6 + USB-TTL (PA9/PA10)
📝 今日目标
之前用 OpenOCD 点亮了呼吸灯,今天决定换个玩法:用 串口 (UART) 跟板子聊天。
- 先跑通最简单的 Hello World(轮询发送)。
- 进阶实现 命令控制(中断接收):电脑发送指令
'1',点亮 LED;发送'0',熄灭 LED。
🚀 初体验:VS Code 的“魔法” (Tab 键治好了我的拼写困难症)
作为直接在 Linux 环境下起步的新手,我没有经历过传统 Keil 开发环境的“折磨”,直接享受了 VS Code 带来的现代开发体验。
在写 Hello World 代码时,我深刻体会到了什么叫“生产力”。STM32 的 HAL 库函数名通常很长(比如 HAL_UART_Transmit),在网上看教程时,发现别人还在一个个字母对着敲。
而在 VS Code 里,我只需要输入 HAL_UART_Tr,智能提示列表瞬间弹出。我看了一眼,排第一的正是 HAL_UART_Transmit,直接按下 Tab 键,它不仅自动补全了冗长的函数名,甚至连参数占位符都给我准备好了。
1 | // 这种顺滑感,谁用谁知道 |
不需要完整打出每一个字母,不需要去翻头文件查参数。这种“所想即所得”的补全功能,让我第一次觉得写 C 语言也能像写 Python 一样流畅。(虽然我后来还是因为太自信没用 Tab 而翻车了,见下文)。
🛠️ 技术进阶:中断控制
跑通 Hello World 后,我决定从“自言自语”升级为“你问我答”。
- 抛弃轮询,拥抱中断: 不在
while(1)里傻等数据,而是开启NVIC中断。 - 工具链切换: 今天尝试了另一种烧录方式:使用 USB-TTL 配合
stm32flash工具进行 ISP 烧录。 - 调试神器: 在 Linux 终端用
picocom充当串口助手,比 Windows 下的点点点帅多了。
💣 踩坑与填坑记录 (Debug Log)
1. 经典的“手滑”现场
虽然 VS Code 有 Tab 补全,但我有一次太自信,坚持手打,结果编译报错 implicit declaration。查了半天发现把 HAL_UART_Transmit 写成了 HAL_UARL_Transmit(UART 变 UARL)。
教训:Tab 键补全才是永远的神,既省力又保命,不要盲目自信手打。
2. 消失的“俄罗斯套娃”括号
在为了测试中断而删除 while(1) 里的旧 Hello World 代码时,不小心把 main 函数的结束大括号 } 也顺手删了。导致 make 疯狂报错 invalid storage class,编译器以为我在 main 肚子里定义了其他函数。
解决:细心检查代码块结构,补上两个 },一个给 while,一个给 main。
3. “昙花一现”的 LED
代码烧进去了,串口也能回显 “LED ON”,但板子上的灯只是闪一下,死活不常亮。
排查: 居然是因为在 CubeMX 里只配了串口,忘了把 PC13 引脚设为 GPIO_Output!
原理: 没设输出时引脚是高阻态(Input),根本没力气拉低电平点灯。改成 Output 后,问题秒解。
💻 核心代码 (Callback 回调)
把逻辑写在回调函数里,主循环空跑,这才是嵌入式的“优雅”:
1 | // 放在 main.c 最下方 |
🎉 最终成果
在终端敲下:
1 | sudo picocom -b 115200 /dev/ttyUSB0 |
按下键盘 1,板子灯亮;按下 0,板子灯灭。
感受: 在 Linux 下敲 make 和 sudo stm32flash 的感觉,真的有点上头!明天试试把之前的 PWM 结合进来,做个可调亮度的灯!