
上周末接了一个 STM32 鱼缸控制器的小项目一路水温传感器、一路水泵、一路加热棒再加上照明灯外带串口在电脑上手动干预。放在以前我得先打开 CubeMX 老老实实把引脚配完再从串口驱动写到 PWM 输出最后烧进板子调 bug一晚上基本就交代了。这次我换了个搞法——用 Claude Code 来做嵌入式软件 AI 编程的辅助把整个流程真正落到自己的项目里。这篇文章就是我这次实操的完整记录不是什么概念吹水。从 Claude Code 安装、工程接入、提示词设计到 STM32 代码生成、编译烧录、踩坑排查全流程过一遍。适合两类人看一是刚接触 Claude Code、想知道它能不能用来写嵌入式固件的朋友二是已经在用各种 AI 工具、但还没想清楚怎么跟 STM32 开发结合的开发者。我先说个结论Claude Code 不是那种把需求扔过去就给你一个完整固件的工具它更像一个能进你工程目录、能读文件、能改代码、能执行命令的结对编程搭子。用得好它能节省一大半编码时间用得不好它也完全能写出让你想砸键盘的代码。下面按我的实操顺序讲。1. 我为什么把 Claude Code 接进 STM32 开发流程1.1 过去工作流里的三个痛点我以前写 STM32 的流程很固定先用 CubeMX 生成初始化骨架然后在 Keil 里打开工程照着参考手册写外设驱动再调业务逻辑最后烧录调试。这套流程最大的问题不是难而是样板工作量太大。串口收发要写GPIO 点灯要写PWM 调速要写I2C 读传感器要写每个外设来回来去就那么几套模式。你真正需要动脑子的地方比如协议怎么设计、状态机怎么切、异常怎么处理反而被埋在一大堆重复代码里。我试过用网页版 ChatGPT 辅助写代码效果一般。原因很简单网页聊天框和你本地工程是完全隔离的AI 不知道你用的是 HAL 库还是标准库不知道主频多少不知道引脚配在哪也不知道你的代码风格。每次都要在聊天框里贴上一大段代码和报错信息上下文稍微一长就乱了。最要命的是AI 写完代码之后我还是要手动复制到工程里编译报错了再来一轮复制粘贴效率提升非常有限。1.2 Claude Code 和聊天框 AI 的本质区别Claude Code 是 Anthropic 出的命令行编程 agent和网页聊天的思路完全不同。它直接跑在你的终端里和你的项目在同一个环境内工作。第一个区别是它能读文件。输入一条自然语言指令它自己去翻工程目录读 main.c读 main.h读 Makefile甚至主动找 CubeMX 生成的配置。这意味着它不需要你手动把代码贴过去它能自己建立对工程的整体认知。第二个区别是它能改文件。它不是给你一段代码让你自己粘而是直接在文件里定位修改加在合适的 USER CODE 区块里。改完你可以 git diff 看一下它动了什么。第三个区别是它能执行命令。你允许它跑 make、gcc、stm32flash 这些命令它就能自动编译、自动烧录、自动看报错然后根据报错信息自己修代码。这个闭环非常关键等于它有了试错-修正的能力。我在鱼缸控制器这个项目里的切身体会是Claude Code 不是替你做嵌入式开发的外挂它更像是把你从繁琐的机械编码中解放出来的一道工具链。你依然要懂芯片、懂外设、懂电路但你可以把大量时间从敲代码转移到思考方案和排查问题上。2. 搭建 Claude Code STM32 的联合开发环境2.1 Claude Code 安装过程与常见坑在 Windows 上安装 Claude Code 并不复杂但有几个细节不处理好会卡住我把我的完整步骤和踩到的两个坑列出来。第一步确认本机有 Node.js 环境。Claude Code 官方推荐用 npm 安装所以你至少要有 Node.js 18 以上版本。在 PowerShell 里执行node -v npm -v第二步全局安装 Claude Codenpm install -g anthropic-ai/claude-code安装完成后执行claude --version能输出版本号就说明装上了。第三步配置认证。Claude Code 需要你有 Anthropic API key 或者 Claude 订阅账号。我的做法是把 API key 设置成环境变量这样每次启动终端它都能读到# PowerShell 临时设置 $env:ANTHROPIC_API_KEYsk-ant-xxxx # 永久设置需要写入用户环境变量 setx ANTHROPIC_API_KEY sk-ant-xxxx第一次运行claude命令它会确认条款并要求你选择一个工作目录。这里注意要在 STM32 工程根目录下启动而不是随便在一个目录里启动。因为它会以当前目录作为项目上下文启动位置不对后续它读到的文件树就不对。我遇到的两个安装坑第一个坑是 PowerShell 执行策略。如果你用了官方推荐的安装脚本方式而不是 npm可能会报错说脚本被禁止执行。这是因为 Windows 默认 ExecutionPolicy 限制。解决办法是用管理员权限执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser第二个坑是启动时报权限相关的错误。Claude Code 首次启动会要求你确认权限模式它默认会询问哪些命令允许执行、哪些目录允许读写。很多人直接无脑全允许这对普通项目问题不大但对 STM32 这种会跑烧录命令的工程我建议保守一点。后面我会专门讲权限配置。确保你的终端能正常访问 Claude API 服务这是使用的基础条件。如果网络访问存在问题先解决网络连通性再继续配置否则启动后所有请求都会卡在超时上。2.2 用 CLAUDE.md 让 AI 看懂你的 STM32 工程Claude Code 有一个很重要的机制叫 CLAUDE.md这是放在工程根目录下的说明文件。它类似于给 AI 的一份项目上岗手册Claude Code 每次启动时都会读它并在整个会话里持续参考。很多人忽略了这一步直接让 AI 去读代码。AI 确实能读但没有 CLAUDE.md 引导的时候它可能要翻很多文件才能猜出芯片型号、时钟频率、当前用的固件库版本。与其让它瞎猜不如把硬件底座信息直接写在 CLAUDE.md 里。我在鱼缸控制器工程里写的 CLAUDE.md 内容大致是这个结构# STM32F103C8T6 鱼缸控制器 ## 硬件信息 - 芯片STM32F103C8T6主频 72MHz - 库STM32CubeMX 生成的 HAL 库 - LEDPC13低电平点亮 - 串口USART1PA9/PA10波特率 115200 - PWMTIM2_CH3PA2频率 1kHz用于加热棒功率调节 - 烧录ST-Link V2SWD 接口 ## 工程结构 - Core/main.c 和中断处理 - Drivers/HAL 库和 BSP 驱动 - MDK-ARM/Keil 工程文件 - CMakeLists.txtCMake 构建脚本备用 ## 编码约束 - 所有新增代码必须写在 /* USER CODE BEGIN */ 到 /* USER CODE END */ 之间 - 不要修改 CubeMX 自动生成的初始化代码 - 修改时钟树前必须确认外部晶振数值这段 CLAUDE.md 解决了 AI 最缺乏的硬件上下文问题。它不需要再去猜 MCU 型号和引脚分配而是被直接告知了关键参数。实测效果Claude Code 生成的代码在引脚命名、外设实例名上基本不会出错。如果你还在用标准外设库或者 LL 库也要在 CLAUDE.md 里写清楚。Claude 的预训练数据里包含大量 STM32 代码但它默认倾向于给你 HAL 库的写法你不声明库类型它大概率会生成混合风格的代码。2.3 构建与烧录命令的准备Claude Code 能执行命令但前提是这些命令在终端里本身就能跑通。所以你在接入 AI 之前必须先保证工程可以用命令行完成编译和烧录。Keil 是 IDE不一定能方便地在命令行自动化构建。我的做法是给工程额外配一套 CMake arm-none-eabi-gcc 工具链。这样 Claude Code 收到编译指令时可以直接跑cmake --build build来验证代码能不能通过编译。Keil 只用来做最终烧录或者在需要调试器调试的时候才打开。烧录命令也提前准备好。我用的 STM32CubeProgrammer 命令行工具烧录整个固件的命令类似于STM32_Programmer_CLI.exe -c portSWD modeUR -w build/fish_tank.elf -v把这个命令写进 CLAUDE.mdAI 就能在生成代码后自动帮你烧录到板子然后从你的反馈中判断是否需要继续修改。注意烧录命令的执行涉及硬件我强烈建议第一次使用时自己手动跑通确认无误之后再把这条命令的权限开放给 Claude Code。2.4 权限控制建议Claude Code 默认的权限模型会逐条询问是否允许执行命令。对 STM32 工程来说我建议用 allowedTools 做白名单只允许它执行构建和烧录相关的命令claude --allowedTools Read,Write,Edit,GlobalMemoryRead,Glob,ls,Grep,cmake,STM32_Programmer_CLI这样 AI 可以读文件、改代码、跑 cmake 和烧录命令但不能随手执行 format、rm、shutdown 这种危险操作。如果你不想每次都要确认可以设置--permission-mode acceptEdits让它在编辑文件时不需要确认但执行命令仍需逐条批准。这个折中方案我实测下来效率最高。另外我强烈建议在接 Claude Code 之前给工程做一个 git 提交。AI 改代码偶尔会改出莫名其妙的结果有 git 兜底你可以随时回退没有 git 你就只能手动对比文件差异痛苦至极。3. 实战用 Claude Code 开发串口命令控制的 PWM 呼吸灯下面这个例子是我鱼缸控制器项目里的一段典型功能电脑通过串口发送命令控制 LED 亮灭和加热棒 PWM 呼吸模式。硬件上就是 STM32F103C8T6、一个板载 LEDPC13、一个 TIM2_CH3 的 PWM 输出。功能本身不复杂但很适合用来演示 Claude Code 的真实工作方式。3.1 需求描述和工程准备我先用 CubeMX 生成基础工程配置好 USART1115200-8-N-1、PC13 输出、TIM2_CH3 PWM 输出。所有外设初始化由 CubeMX 生成我不动。然后我把 CLAUDE.md 写好把工程根目录作为 Claude Code 的启动目录。启动后在终端里输入claude进入交互模式后我直接把需求描述给 AI。3.2 提示词设计为什么说差提示词和好提示词差距巨大先说差提示词。如果我只是说帮我在 STM32 上写一个串口控制 LED 的程序Claude Code 确实会给我输出代码但大概率是这种结果用 GPIOA PIN0 控制 LED、默认 8MHz 主频、用阻塞式串口接收、没有考虑 CubeMX 的 USER CODE 区。代码看起来完整拿不到工程里用因为它没有阅读我的 main.c 和引脚配置纯粹在凭预训练知识虚构一个 STM32 工程。我实际用的提示词是这样的请先阅读 Core/Inc/main.h、Core/Src/main.c 和 Drivers 目录 了解当前 CubeMX 生成的引脚配置和外设初始化。 芯片是 STM32F103C8T6HAL 库主频 72MHz。 PC13 是 LED低电平点亮。 USART1 已经初始化波特率 115200。 需求 1. 串口接收中断模式PC 下发以下命令以换行结尾 LED_ON、LED_OFF、BREATH_START、BREATH_STOP 2. LED_ON / LED_OFF 用 GPIO 控制 PC13。 3. BREATH_START 时TIM2_CH3 输出 1kHz PWM 占空比按呼吸节奏从 0 慢慢变到 100再从 100 慢慢回到 0。 4. 串口收到命令后回显状态比如 LED ON、LED OFF、BREATH MODE。 5. 所有新增代码放在 USER CODE 段内不要改动 CubeMX 生成的初始化部分。这段提示词的核心不是命令列表而是它要求 Claude Code 在动手前先读工程文件。这比你给它贴代码再问怎么改要高效得多。提示词里明确写出了芯片型号、引脚极性、外设实例这些是 STM32 代码最容易出错的点先给定下来AI 出错的概率立刻降一半。3.3 Claude Code 生成的代码质量和修正过程Claude Code 读完工程后先在 main.c 的 USER CODE 区里添加了串口接收缓冲区和状态变量。它用了经典的 HAL_UART_Receive_IT 方式接收完一帧后进入回调然后在回调里做命令解析。生成的接收回调部分大概是这样void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart-Instance USART1) { if (rx_buffer[rx_index - 1] \n) { rx_buffer[rx_index - 1]