
写嵌入式的人都有种感觉项目周期里真正花在“写代码”上的时间远没有花在“查手册、调配置、擦屁股”上的时间多。外设初始化要对着参考手册翻寄存器串口数据不对就来回试波特率换了芯片型号之后HAL库版本对不上又得从头改。这几年我前前后后做了不少STM32项目最近半年开始认真尝试嵌入式软件AI编程把Claude Code拉进日常开发流程用下来的感受非常直观——它不是帮你“多写几行代码”而是把整个“查手册、改样板、编译报错再修”的循环大幅压缩了。这篇文章是“嵌入式软件AI编程”系列的第一篇我会把自己目前基于STM32加Claude Code的完整工作流、提问方式、验收方法以及踩过的一些坑整理出来分享给准备尝试AI辅助嵌入式开发的同行。1. 为什么我会把AI编程工具放进嵌入式工作流1.1 嵌入式开发真正的痛点在哪嵌入式软件开发和纯软件开发的节奏完全不一样。写个Web服务改完代码热重载就能看效果出了问题日志一拉基本能定位。但STM32这种MCU项目一次完整的验证流程是改代码、编译、烧录、接示波器或者串口看现象发现问题再回头改。这一轮下来快的几分钟慢的折腾半天而且很多问题不是看代码能看出来的比如引脚冲突、时钟配置不对、中断优先级配错甚至硬件上拉电阻没焊好导致通信不稳定。更麻烦的是样板代码太多。每个外设都要走一遍“使能时钟、配置引脚、配置外设参数、配置中断、写回调”的流程。我早期做项目用的标准库后来换到HAL库光是把以前写过的UART、I2C、SPI驱动翻出来移植到新工程就要花掉不少时间。这些代码本身不难但非常琐碎而且不同芯片型号、不同库版本之间还有细微差异。这时候我就特别希望有个“帮手”能直接把这些样板生成好我专注于业务逻辑和硬件方案。AI编程工具在嵌入式领域的发展其实比很多人想象中要实用。早期我用过代码补全类工具它能在我写HAL_GPIO_WritePin的时候把参数带出来但也就到此为止了。真正让我改变工作方式的是把Claude Code这种“能自己读工程、自己改文件”的agent工具接进来它能理解我整个工程的结构顺着我的上下文把相关的初始化代码、中断回调、业务框架一次性补全这在以前是不可想象的。1.2 Claude Code和Codex、Copilot这类工具有什么区别先说明一点我这里说的Claude Code是Anthropic出的命令行编程agent不是那个手机App。它跟我们在IDE里装的自动补全插件是完全不同的物种。传统AI补全工具的工作方式是“跟随光标”你写一行它预测下一行。这种方式在写业务逻辑比较多的地方很舒服但在嵌入式工程里就比较鸡肋因为嵌入式工程的复杂度主要分布在文件之间一个外设驱动要同时改头文件、源文件、中断处理、回调函数只靠编辑器补全根本串不起来。Claude Code这类agent的工作方式更接近“你自己雇了一个坐旁边的初级工程师”。你给它一个任务它能自己去翻阅工程里的文件、定位相关代码、修改多个文件、执行命令、根据报错再次调整。我实际用下来的感受是它对整个STM32工程的理解能力比我想象中强很多。我可以直接说“把UART1改成DMA收发接收部分加环形缓冲区”它不会只改一个文件而是会把uart.c、uart.h、main.c、stm32f1xx_it.c里的中断处理一并处理掉。至于Codex我也试过。它对“生成一整块独立代码”的能力很强但在“理解并修改一个现有大型工程”这件事上Claude Code的长上下文和多轮修改能力更贴合嵌入式开发习惯。当然这纯粹是个人体验两个工具都在快速迭代我现在的主力是Claude Code偶尔两个工具对比着用看哪个在这个任务上更靠谱。1.3 什么样的开发者适合这套组合如果完全没有单片机基础那我的建议是先把基础知识补上再来用AI工具。因为AI生成的代码质量如何需要用的人自己有判断力。它能帮你写代码但不会帮你判断这个代码在你的板子上能不能跑、晶振是多少、boot引脚有没有被占用。适合用这套组合的人我认为主要有两类。第一类是已经有STM32开发经验、想提升效率的工程师这个最好理解。第二类是刚入门的学生或转行者对寄存器、外设协议已经有概念但写起来不熟练这种情况下让AI帮你生成一份标准的驱动当参照可以快速理解一个完整驱动该有的结构和步骤。我自己属于第一类但我也见到不少第二类朋友把Claude Code当“贴身助教”用效果也不错。关键是心态要对工具是加速器不是替身。2. 环境搭建Claude Code STM32开发环境的组合拳2.1 Claude Code的安装与基础配置安装Claude Code其实不复杂但第一次装的时候Windows用户容易在PowerShell这一步卡住。先把前置条件说清楚你需要一个能正常安装Node.js的环境Claude Code是跑在Node上的所以Node版本不能太低我建议用18以上的LTS版本。装Node的时候记得把npm一起装上之后所有操作都靠npm。安装命令只有一行npm install -g anthropic-ai/claude-code装完之后在终端里执行claude --version验证一下能打印出版本号就说明安装成功。但Windows上经常会出现一个问题明明npm安装成功执行claude却报错提示类似“无法加载文件因为在此系统上禁止运行脚本”。这是因为Windows PowerShell默认的执行策略限制了脚本运行解决方法是给当前用户放开权限用管理员权限打开PowerShell执行Set-ExecutionPolicy -Scope CurrentUser RemoteSigned执行完再重新打开终端claude命令就能正常使用了。之后需要登录授权这一步会把你导向浏览器完成账号认证。认证完成后会有一些交互式的配置选项比如主题、使用的模型偏好等直接按默认走就行。有一点要注意Claude Code的使用受账号配额限制免费额度用完后可能需要订阅或使用API热词里那句“your limits are temporarily boosted. your weekly claude code limit is 50% higher”就是典型的配额提示。做嵌入式开发经常会连续跟它对话好几个小时建议提前确认自己的配额情况避免正干到一半被限流。2.2 STM32开发环境怎么搭AI才能更好理解工程在Claude Code之前我一直觉得STM32的开发环境选择是“怎么都能搭”但引入AI之后我意识到环境的结构是否清晰直接影响AI理解工程的速度和准确度。我现在的标准组合是STM32CubeMX生成初始化代码VS Code当编辑器EIDE插件管理编译下载arm-none-eabi-gcc当编译器ST-Link当调试器。这套组合的好处是工程结构简单、文件关系清楚Claude Code在分析代码的时候路径明确不会出现Kile工程里那种一堆中间产物和分散文件的问题。这里插一句国内很多刚入门的同学会用Keil5而Keil5有个经典问题就是C51和STM32的兼容安装。实际上C51和STM32在Keil里是两套完全独立的工具链安装时分别装对应的Device Pack就行比如ST的芯片装Keil.STM32F1xx_DFP51内核的芯片装Keil.C51。两套Pack可以共存新建工程的时候选择正确的芯片型号就不会互相干扰。如果你用Claude Code辅助Keil工程一定要在提示词里说明用的是哪个Pack和库版本否则它按默认配置生成的代码很可能跟你本地环境不匹配。VS Code这边除了EIDE我还会用Cortex-Debug配合OpenOCD做在线调试。有些人用STM32CubeProgrammer或者STM32 ST-LINK Utility来烧录这都行。核心原则只有一个工具链要稳定、路径要简单、能命令行操作最好。因为Claude Code本身不是一个图形化工具它要通过读文件和分析逻辑来工作工程越规整它的表现越稳定。2.3 用CLAUDE.md给AI补“项目脑图”很多人直接用Claude Code在工程根目录里开始对话也不管它看不看得懂这个项目然后问“帮我写个按键扫描”结果AI给出的代码和自己芯片的HAL库版本对不上就抱怨AI不行。其实问题出在没给它足够的项目背景。Claude Code支持工程根目录放一个CLAUDE.md文件这个文件相当于告诉它这个项目的“前情提要”。我强烈建议每个STM32工程都补上这个文件内容不用多把最关键的信息写清楚就行。我自己的CLAUDE.md大概长这样# STM32F103C8T6 智能家居控制节点 ## 芯片与库 - MCU: STM32F103C8T6, 72MHz, Flash 64KB, RAM 20KB - 固件库: STM32CubeF1 HAL库 v1.8.5 - 工程由STM32CubeMX v6.9生成注意不要手动修改CubeMX生成的初始化代码区域 ## 编译与烧录 - 编译工具: arm-none-eabi-gcc EIDE - 调试器: ST-Link V2, SWD接口 - 烧录命令: 通过EIDE插件“Build and Program”完成 ## 工程结构 - Core/Inc: 头文件 - Core/Src: main.c, stm32f1xx_it.c等 - Drivers/STM32F1xx_HAL_Driver: HAL库文件 - user/: 我自己的业务代码新增模块放在这里 ## 注意 - 按键使用PA0默认外部中断下降沿触发 - 板载LED在PC13低电平点亮 - 所有业务代码不要使用阻塞延时使用HAL_GetTick()实现超时管理这个文件写完之后Claude Code对这个工程的理解水平会高一大截。比如它要改中断相关代码会主动去看stm32f1xx_it.c而不是在main.c里乱加它知道板载LED在PC13就不会让你改完代码之后发现灯不亮还一头雾水。实测下来有CLAUDE.md之后AI生成的代码第一次能编译通过的概率高了很多来回返工的情况也大幅变少。3. 实操用Claude Code写完一个UARTDMA驱动3.1 提问技巧把需求说成人话用Claude Code辅助写STM32代码提问质量直接决定输出质量。这不是什么玄学而是因为它要基于你给的信息去推断整个技术方案你给的上下文越完整它犯错的概率越低。我自己总结了一个提问公式基本可以覆盖大部分场景先说芯片型号和库版本再说外设和功能然后说接口要求最后补充约束条件。举个例子我让它写串口驱动时会这样说“基于STM32F103C8T6和HAL库v1.8.5帮我写一个UART1的DMA收发驱动。要求如下串口接收使用DMA接收不定长数据数据以0x0A换行符结尾接收数据存入环形缓冲区发送使用DMA发送发送完成之后有回调通知波特率1152008位数据位1位停止位无校验。整个驱动需要提供初始化函数、发送函数和接收回调接口。”如果你什么都不说只来一句“帮我写一个串口程序”它大概率会给你一个轮询方式收发的最基础示例能用但离实际项目需求差很远。不是它不行是你没把需求讲清楚。嵌入式开发本来就是需求驱动把这个思路用在跟AI沟通上效果立竿见影。另外一个很重要的技巧让AI先出方案、再写代码。我会在正式写代码之前加一句“先给我你的实现思路确认没问题再动手”。这样可以提前发现它可能选错方案的情况比如我要用DMA做接收它可能打算用普通中断接收或者它打算自己实现一个麻烦的协议这些在方案阶段就能拦住不用等代码写完了才发现路走偏了。3.2 让Claude Code读你的工程而不是凭空生成很多人在用Claude Code写嵌入式代码时犯的最大错误是让它“脱离工程背景凭空写文件”。它在不了解你工程细节的情况下生成的文件要么和main.c里已有的初始化冲突要么风格和现有代码完全不一致混在工程里非常难受。正确做法是让它先读关键文件。第一次使用某个STM32工程时我会在对话里加一个指令“先读一下Core/Src/main.c、Core/Src/stm32f1xx_it.c和Core/Inc/main.h了解当前的外设初始化和中断处理情况然后根据现有代码风格来实现UART驱动。”这样它会在动手前把工程的基础结构过一遍接出来的代码风格、命名方式、函数接口会跟你原有的代码保持一致。最终生成的文件路径我也会先口头上指定。比如我会说“在user/文件夹下新建bsp_uart.c和bsp_uart.h注意头文件加extern C保护”这样它不会自作主张地把业务代码混进HAL库目录也不会把main.c改得乱七八糟。对于CubeMX生成的代码区域要在对话中明确告诉它“不要动CubeMX生成的代码块”否则它一不留神就可能把初始化代码改成手工维护版本下次再打开CubeMX重新生成就全丢了。等它写完不要急着烧录先看看它生成了哪几个文件、改了哪几个文件用claude右上方的文件修改记录确认改动范围。我习惯先看一眼头文件的接口声明再决定要不要采用这套代码。如果接口不合理直接让它重来比你自己动手改要快得多。3.3 验收与集成AI写的代码怎么用才安全AI生成的代码本质上是一个“能力很强的初级工程师”写的能跑是底线但能不能长期稳定地跑、遇到边界情况会不会崩都需要你亲自把关。我给自己定的验收标准是三步编译、逻辑审查、手册比对。第一步是先编译。编译不过后面的都白搭。如果编译报错把报错信息直接贴给Claude Code说“编译报错如下请修复”它通常会自己分析错误原因并调整。这个过程非常高效因为嵌入式编译报错往往信息量巨大人工看得头大但AI处理起来是强项。第二步是逻辑审查。我会重点看几个AI容易犯错的地方中断优先级有没有配置不同优先级的中断里有没有共享数据结构有没有在中断服务函数里调用阻塞函数DMA通道配置跟实际使用的通道是否一致GPIO复用功能有没有写对。这些问题用逻辑审查就能发现不用等跑起来再踩雷。第三步是手册比对。这个最花时间但对复杂外设也最必要。特别是当你用的是一个相对小众的芯片型号或者HAL库版本比较新AI很可能基于它训练时的旧数据给出过时的写法。我碰到过它把HAL_UART_Receive_DMA的第三个参数写成长度而不是缓冲区大小看起来没什么问题但一跑就进HardFault。这种时候直接让它“请查阅参考手册中的DMA传输模式部分并对比当前代码”它多半能自己发现错误。顺便提一句初始化代码里有些参数可以交给AI帮你算比如STM32的晶振负载电容计算。我之前做板子时问它“8MHz晶振负载电容12pF外挂两个电容应该选多大”它能很快给出计算思路和结果虽然不是所有硬件参数都适合让它拍板但这种标准化的计算用它省心也不容易错。4. 踩坑记录Claude Code STM32排错笔记4.1 安装和运行层面的问题我最早在Windows上装Claude Code第一次就撞上了PowerShell执行策略的问题。明明npm输出一堆安装成功的日志执行claude却弹出一段英文报错大意是系统禁止运行脚本。后来查了一下这是Windows的安全策略给当前用户放开RemoteSigned权限就好了。命令上面写过这里不重复。如果执行Set-ExecutionPolicy时报权限不足记得用管理员身份运行PowerShell。还有一个很容易被忽略的问题是Node.js的版本。Claude Code对Node版本有要求如果系统里Node版本太老安装的时候可能不报错但运行时会莫名其妙地闪退或者提示找不到模块。解决方式很简单去Node官网装最新的LTS版本然后把npm全局包重新装一遍。另外就是配额问题。免费额度用完之后继续干活时弹出的提示特别影响节奏。我的习惯是下午开始连续开发之前先在终端跑一下claude看看有没有额度提示有的话提前安排好任务优先级别等到写代码写一半才发现被限流了那种体验真的非常难受。4.2 烧录和调试层面的问题用STM32开发最容易碰到的烧录错误之一就是OpenOCD那行经典的报错error: no stm32 target found! if your product embeds debug authentication, pl...。这个报错我刚接触的时候被坑过好几回后来总结出几个排查方向。首先要确认ST-Link有没有被正确识别。插上ST-Link后打开设备管理器看有没有带叹号的设备如果驱动有问题先重装ST-Link驱动。其次要看OpenOCD的配置文件跟目标芯片是否匹配比如你是STM32F1系列用的却是F4的target配置它当然找不到芯片。最后一个容易被忽略的是芯片的读保护问题。有些二手板子或者之前烧录过加锁程序的芯片SWD口会被锁住这种时候需要用STM32CubeProgrammer连接芯片把读保护级别改成无擦除后就能正常烧录了。跟这个类似的一个问题是STLINK的虚拟串口识别不了。很多STM32板子上的ST-Link自带VCP功能电脑上会多出一个串口设备但如果驱动不对设备管理器里就是黄色叹号。这时不需要重新编译工程去ST官网下载并安装对应版本的VCP驱动就行。还有朋友喜欢用J-Flash直接烧录或读取STM32的bin文件。读取bin文件的时候如果芯片开了读保护J-Flash会读出一堆0xFF或者直接报错这时候同样要先去解除读保护。另外注意J-Flash读取的是整个Flash区域包括中断向量表、程序代码和字库等数据如果只想看自己编译出来的bin有没有烧进去不如在编译输出目录里直接用工具对比比读Flash再存文件省事得多。4.3 AI的“幻觉”代码坑说到AI辅助嵌入式开发我最想吐槽的就是它的“幻觉”问题。它会把一些不存在的外设、寄存器或者引脚定义写得很像那么回事。比如说让它给STM32F103配置一个硬件CRC模块它还真能写出一段调用HAL_CRC_Init的代码问题是F103根本没有CRC外设这个在F4系列才有。第一次遇到这种问题时我还认真对着参考手册找半天最后发现是AI自己脑补出来的。还有一次让它写外部Flash的驱动它给出的引脚分配里有一个跟板载LED冲突了导致Flash初始化的时候LED会莫名其妙跟着闪。这就是典型的没有结合工程实际凭空猜测硬件连接。我的应对方法是在提示词里反复强调“以实际硬件和参考手册为准”并且让它必须声明每个引脚和寄存器配置的出处。如果它引用了一个我不确定的寄存器我会直接跟它说“查一下参考手册确认这个寄存器在STM32F103上是否存在并把手册相关段落贴出来”。你会发现当它被要求给出依据时幻觉率会明显下降。如果它还是给不出可靠依据那就自己上去改把它写的代码当成一个参考版本即可。5. 几点心得以及新手怎么起步5.1 别把AI当成嵌入式大佬用了一段时间之后我对Claude Code在嵌入式开发中的定位有了更清晰的理解它是一个阅读理解能力和代码生成能力都很强的工具但它不是一个嵌入式硬件专家。它不懂你的电源纹波大不大不知道你的PCB走线有没有问题也不会告诉你板子上的传感器I2C地址是不是写错了。硬件上的一些判断特别是跟电路、信号完整性、功耗相关的决策必须靠开发者自己。AI可以做的是帮你快速补齐代码层面的事情比如生成驱动、修编译错误、整理代码结构。我见过有人完全照着AI生成的代码做了一块板子结果硬件本身设计就不对然后回过头来怪AI代码有bug。这种用法其实是本末倒置了。嵌入式开发的核心还是你对硬件和系统的理解AI只是让你写代码这件事变得更快。5.2 起点给自己一个小项目练手如果从来没试过用AI来写STM32代码不建议一上来就拿一个复杂的量产项目做试验。最好的方式是从一个自己能完全掌控的小项目开始。热词里那些“STM32鱼缸控制器”“宿舍智能台灯”“8266宿舍控制灯”这类小项目其实就是非常好的练手目标它们有明确的功能边界涉及的硬件不多代码量不大但麻雀虽小五脏俱全能把GPIO、定时器、UART、中断全都用上。我的建议流程是先用STM32CubeMX把基本工程生成出来让Claude Code阅读工程然后用CLAUDE.md描述项目需求再让它按模块逐一实现功能。这个流程走完你对“AI在嵌入式开发里到底怎么用”会有一个非常实在的体感比看十篇教程都有用。做完一个小项目之后再拿它去辅助效率更高的开发任务心里就有底了。5.3 后续还能玩什么这套方法论一旦跑通可以扩展的方向非常多。比如FreeModbus在STM32上的移植让AI分析协议栈源码和移植接口可以省下大量读文档的时间。再比如K210和STM32之间的通信两个芯片的异构通信调试起来本来很折磨人让AI同时读两边的工程代码并检查协议字段匹配排查问题的速度会快很多。还有STM32的USB库、条形码识别模块、I2S数播等方向都是AI辅助的好场景。这些方向我后续会在这个系列里继续展开每一篇都会围绕一个具体的嵌入式实战问题讲清楚怎么用Claude Code配合解决。如果你也在用AI做嵌入式开发欢迎把踩到的坑和好用的技巧一起交流。我个人的体会是AI辅助编程这个方向在嵌入式领域才刚刚开始真正的价值不在于它替你写了多少代码而在于它把你从重复劳动里解放出来让你有更多精力去思考真正重要的系统设计问题。