讲实话,我一开始对“嵌入式软件AI编程”是持怀疑态度的。做过STM32的人都知道,一个外设驱动要跑通,引脚、时钟、延时、中断、库函数版本,哪个环节错了都够折腾半天。AI一个生成式模型,能把GPIO和TIMER玩明白?但这两个月我把一个完整的STM32项目整个流程用AI重走了一遍之后,不得不承认:只要你把开发流程设计对了,AI真的能顶一个干活利索的初级工程师,而且它不怕改、催不烦、还不会跟你抱怨需求变更。
这篇文章我想把一套能落地、可复用的AI编程STM32开发流程完整讲清楚。不是我纸上谈兵,而是我实际做完一整个项目之后踩坑踩出来的。会从整体工作流设计讲起,再讲环境与工具选型,然后以一个STM32环境监测小项目为例,把从需求拆分、外设配置、驱动生成、业务逻辑到调试排错的完整过程都过一遍。适合那些已经会一点STM32、想用AI大幅提升开发效率的人;如果你刚入门嵌入式,建议至少先把HAL库的基本套路搞明白,再来看AI生成的代码,否则后面排查问题会非常痛苦。
1. 先搞清楚:AI进入STM32开发,流程哪里变了
1.1 传统STM32开发流程的痛点
大部分人的STM32开发流程大概是这样:打开STM32CubeMX配置时钟和引脚,生成HAL库工程,然后在MDK或者CubeIDE里写业务代码。遇到不熟悉的外设,翻Datasheet、翻参考手册、翻正点原子或者野火的例程,把寄存器或者HAL库函数一个个对上号。碰上时序要求严格的东西,比如DHT11、DS18B20、NTC测温,还得用逻辑分析仪一点一点调时序。项目一复杂,光移植驱动就能耗掉小半天。
这套流程本身没毛病,问题在“体力活太多”。比如GPIO翻转、定时器捕获、串口收发、I2C读传感器,这些功能芯片手册写得清清楚楚,社区里例子一抓一大把,说白了就是“熟练工”的活儿。但在传统流程里,你仍然要一个字一个字敲,一个寄存器一个寄存器查。更别提那种“昨天还记得API名字、今天就忘了”的情况,来回翻手册的时间比写代码还长。
还有个隐藏痛点:嵌入式项目的代码和硬件强相关,出了bug你不确定是代码问题还是硬件问题,调试循环特别长。传统流程里,写代码、编译、烧录、看现象、打日志,这一圈下来,五分钟起步。如果每次都是手工调,半天时间很快就没了。
1.2 AI介入后的新流程:一个“需求-生成-验证”的闭环
AI编程进入STM32之后,我的整体流程变成了这样:
- 用自然语言描述功能需求(比如“用PA4读取DHT11温湿度,每秒刷新一次”);
- 让AI生成对应的HAL库代码,并且明确指定芯片型号、库版本、时钟频率;
- 人工检查关键部分(引脚、时钟、时序相关代码必须看,其他可以扫一眼);
- 烧录测试,如果出问题,把报错信息或现象描述丢回给AI,让它提出修改建议;
- 反复上述闭环,直到功能稳定。
这套闭环和传统流程最大的区别是:大部分“从需求到代码”的翻译工作被AI接管了。我做的事从“手写每个函数”变成了“设计需求、审查代码、判断结果”。听起来好像只是换了个干活方式,但实际上整个开发节奏完全变了。以前一个驱动模块从找例程到调通可能要40分钟,现在AI生成+人工审查基本能压到10分钟以内,核心省掉的是“翻资料”和“敲样板代码”的时间。
1.3 AI的擅长与不擅长:哪些能交出去,哪些必须自己扛
再强的AI工具也有边界,尤其是嵌入式这种和硬件强相关的领域。用了这么久,我总结下来AI在STM32开发里的擅长清单和不擅长清单大概是这样的:
| 环节 | AI擅长程度 | 说明 |
|---|---|---|
| 通用外设驱动生成 | 很擅长 | GPIO、UART、I2C、SPI、TIM、ADC这些标准外设,HAL库代码很模式化,AI生成质量高 |
| 协议解析 | 擅长 | Modbus、CAN、串口自定义协议、PID控制算法这类逻辑清晰、网上资料多的东西,AI很能打 |
| 业务状态机 | 比较擅长 | 只要你把状态转移条件说清楚,AI能给你排版工整、结构清晰的状态机框架 |
| 底层时序相关 | 需要人工重点审查 | 比如DHT11单总线时序、WS2812灯带时序,AI容易忽略延时精度和GPIO速度配置 |
| 硬件BUG调试 | 不擅长 | AI看不到你的原理图,也测不了波形,这类问题只能靠逻辑分析仪和经验 |
| 芯片特有寄存器操作 | 看情况 | 如果是常见型号,AI很熟;如果是冷门型号或者最新芯片,AI容易一本正经地胡说 |
所以我的原则是:逻辑性强的、网上资料多的任务大胆交给AI;硬件相关、时序相关、芯片特有配置的任务,AI生成后必须逐行确认。这不是不相信AI,而是嵌入式这行的特殊性决定了你不能当甩手掌柜。
2. 开工前这些事没做对,AI再强也白搭
2.1 环境准备:5分钟搭好一套能跑通的基础开发环境
AI编程不是让你抛弃原来的工具链,而是让你在原有工具链上提效。所以第一步,把STM32开发基础环境准备好。我的标配清单如下:
- STM32CubeMX:用来生成工程骨架、配置时钟树和引脚。这一步我建议不要跳过,哪怕AI能直接给你代码,用CubeMX先把时钟和引脚初始化好,能少掉一半以上的低级错误。
- Keil MDK或者STM32CubeIDE:二选一。MDK更通用,很多人公司里用的就是它;CubeIDE免费、跨平台、自带编译器和调试器,适合个人项目。
- ST-Link或者J-Link:烧录调试必备。新手建议用ST-Link,便宜、官方支持好。
- 串口调试助手:推荐用带波形和图表功能的,比如VOFA+,调试PID、看传感器曲线特别好用。
- 逻辑分析仪(建议):便宜的十几块钱的就行,调单总线时序、I2C、SPI时它是刚需,AI给不了你这个。
另外常见的问题是芯片包安装。Keil MDK默认不带所有STM32型号的支持包,如果你用STM32F103系列,需要装Keil.STM32F1xx_DFP;用F4系列就装F4的DFP。CubeMX生成工程时也会检查芯片包。很多人新建工程失败,十有八九是支持包没装或者版本不匹配,AI帮不了你,自己装好更省心。
2.2 选择AI编程工具:我用下来最顺手的是这几款
现在市面上的AI编程工具很多,我实际用过的有ChatGPT、Claude、GitHub Copilot、Cursor、通义灵码。分别说下嵌入式场景下的体验:
| 工具 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| Claude | 长上下文理解能力强,能一次给一大段完整驱动代码,代码审查时表现突出 | 偶尔会生成不存在的HAL库API | 生成完整模块、代码审查、逻辑分析 |
| ChatGPT | 生态成熟,支持自定义指令,对STM32常见型号很熟 | 长代码容易出现上下文丢失、自己打自己脸 | 日常问答、函数级代码生成 |
| GitHub Copilot | 和IDE深度融合,补全体验极佳 | 嵌入式场景的深层逻辑不太行,容易“顺着你的错误写下去” | 写业务逻辑时快速补全 |
| Cursor | 能直接加载整个工程,改代码像改作文一样方便 | 对国内网络和Keil工程适配一般,MDK工程结构它不一定懂 | 多文件工程重构、批量修改 |
| 通义灵码 | 中文理解好、免费,对国内开发者友好 | 底层模型能力相比国外头部产品还有差距 | 日常问答、代码解释 |
我主力用的是Claude + Cursor的组合。Claude负责对话式需求设计和代码审查,Cursor负责在工程里直接改代码。但如果你的预算有限,先用免费的选项也完全够入门。记住一句经验:AI工具本身不是核心竞争力,你喂给它的上下文和你的审查判断力才是。同一个AI,有人用出来是神器,有人用出来是人工智障,差别就在这里。
2.3 嵌入式AI编程的提示词技巧:比工具更值得学
很多人用AI写STM32代码,上来就一句:“帮我写一个DHT11驱动。”AI确实能给你写,但大概率是网上抄来的通用代码,芯片型号可能是STM32F103默认配置,延时函数可能是标准库写法,跟你手上的HAL库版本对不上。问题不在AI,而在你没给它足够的约束。
我总结了一套嵌入式场景的提示词模板,每次生成代码前套一下,效果立竿见影:
你是嵌入式软件开发专家,精通STM32系列和HAL库。 请帮我生成【DHT11温湿度传感器驱动】,要求如下: 1. 芯片型号:STM32F103C8T6,主频72MHz; 2. 开发环境:Keil MDK5,HAL库版本1.8.0; 3. 引脚:PA4,开漏输出,外部上拉10K; 4. 功能:提供初始化函数、读取温湿度函数,返回值表示读取是否成功; 5. 时序要求:严格按照DHT11数据手册的时序,注意响应信号和40bit数据位读取; 6. 编码风格:函数注释用中文,变量命名清晰; 7. 最后用表格列出你生成的文件清单和每个文件的职责。这个模板的核心要素有四个:角色设定、硬件约束、接口要求、输出格式。你给AI的信息越具体,它生成的东西越能用。另外一个小技巧:分步生成,不要一次要太多。让AI先给你搭建工程结构,再生成底层驱动,再生成业务逻辑,每一步验收通过后再进行下一步。这样出问题能快速定位是哪一步的问题,而不是面对一堆看不懂的代码干瞪眼。
3. 实操:用AI开发一个STM32环境监测小项目
3.1 项目需求定义:先让AI帮你把活拆清楚
我们拿一个真实能跑的小项目来走一遍完整流程:基于STM32F103C8T6的温度湿度监测与报警系统。需求大概是:
- 用DHT11采集温度和湿度;
- 用OLED显示实时的温湿度数据;
- 两个按键,一个切换显示界面,一个设置温湿度报警阈值;
- 超阈值时蜂鸣器报警,并且串口输出报警日志;
- 数据每秒刷新一次。
这个项目能覆盖GPIO、UART、I2C/SPI、定时器、外部中断、状态机这些常用外设和架构,非常适合展示AI编程流程。
传统做法是自己从零写或者翻例程拼装。用AI的做法,我第一步是让AI帮我做需求拆解和模块划分。这步很多人忽略,但恰恰是最出效果的。我给的提示词很简单:
请帮我梳理一个STM32环境监测项目的软件架构。 功能需求:DHT11温湿度采集,OLED显示,按键设置阈值,蜂鸣器报警,串口日志。 请给出: 1. 模块划分和各模块之间关系; 2. 每个模块的核心接口; 3. 推荐的工程文件结构; 4. 开发顺序建议。AI给的输出虽然不会直接变成代码,但它像一个经验丰富的同事帮你把活路捋顺了。根据AI给的建议,我确定了工程结构:
Core/ Inc/ Src/ Drivers/ STM32F1xx_HAL_Driver/ User/ main.c dht11.c dht11.h oled.c oled.h buzzer.c buzzer.h key.c key.h app_state.c app_state.h模块边界清晰之后,后面每一块都可以单独让AI生成,互不干扰。
3.2 用CubeMX + AI生成外设配置代码
工程骨架我还是用STM32CubeMX生成,这一步不交给AI。原因很简单:CubeMX生成的时钟树、引脚定义、基础初始化代码是经过大量项目验证的,比AI凭空写的可靠得多。CubeMX里需要配置的外设有:
- RCC:外部8MHz晶振,PLL倍频到72MHz;
- GPIO:PA4(DHT11数据)、PA5(OLED_SCL)、PA6(OLED_SDA)、PA7(蜂鸣器)、PA0(按键1)、PA1(按键2),全部按实际电路配置;
- UART1:115200-8-N-1,用于日志输出;
- I2C1:用于OLED(如果你用I2C接口的屏),或者用软件模拟I2C,这里选硬件I2C1;
- TIM2:配置为1ms中断,作为系统心跳,给DHT11延时和业务轮询用。
CubeMX生成工程之后,你会得到一个带HAL初始化函数的项目,但里面没有任何业务代码。接下来才是AI的主场:让AI生成驱动层代码。
3.3 AI生成驱动层:DHT11和OLED的实战示范
DHT11驱动是典型的“AI能写但必须人工检查”的模块。我按上面的模板把需求发给AI,它很快生成了核心代码。关键部分贴出来给大家看个意思:
// dht11.h #ifndef __DHT11_H #define __DHT11_H #include "main.h" typedef struct { uint8_t humi_int; uint8_t humi_dec; uint8_t temp_int; uint8_t temp_dec; uint8_t checksum; } DHT11_Data; uint8_t DHT11_Init(void); uint8_t DHT11_Read(DHT11_Data *data); #endif// dht11.c 核心读取函数(AI生成后人工修正过) uint8_t DHT11_Read(DHT11_Data *data) { uint8_t buf[5] = {0}; uint8_t i, j; // 主机起始信号 DHT11_Data_Out(); HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_RESET); HAL_Delay(18); // 拉低至少18ms HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_SET); DHT11_Delay_us(30); // 拉高20-40us // 切换为输入模式 DHT11_Data_In(); // 等待应答信号 if (DHT11_ReadPin() != GPIO_PIN_RESET) { return 1; // 无应答 } DHT11_Delay_us(80); if (DHT11_ReadPin() != GPIO_PIN_SET) { return 2; // 应答异常 } DHT11_Delay_us(80); // 读取40bit数据 for (j = 0; j < 5; j++) { for (i = 0; i < 8; i++) { while (DHT11_ReadPin() == GPIO_PIN_RESET); // 等待数据位低电平结束 DHT11_Delay_us(40); if (DHT11_ReadPin() == GPIO_PIN_SET) { buf[j] |= (0x80 >> i); // 高电平持续50us以上判定为1 while (DHT11_ReadPin() == GPIO_PIN_SET); } } } // 校验 if ((uint8_t)(buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) { >void OLED_Init(void); void OLED_Clear(void); void OLED_ShowString(uint8_t x, uint8_t y, char *str); void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len);这个模块AI生成一次,简单检查I2C地址对不对(SSD1306一般有0x3C和0x3D两种情况),就能直接进下一步。
3.4 AI生成业务逻辑:状态机与报警机制
驱动层搞定以后,业务逻辑层的代码让AI写就非常顺手了。这一层的特点是逻辑明确、不需要跟硬件时序较劲,正好是AI的舒适区。我把需求描述给AI:
请用状态机的方式实现以下功能: 1. 默认界面显示温度和湿度,每秒刷新一次; 2. 短按按键1切换显示界面:界面1显示温湿度,界面2显示当前阈值设置; 3. 在界面2下,短按按键2切换修改温度上限和湿度上限; 4. 当温度或湿度超过阈值时,蜂鸣器1秒间隔鸣叫; 5. 每次状态切换和每次报警触发,串口输出一条日志。AI给的设计很清晰,大概这样:
typedef enum { APP_DISPLAY_TEMP_HUMI, APP_DISPLAY_THRESHOLD, APP_SET_TEMP_MAX, APP_SET_HUMI_MAX } AppState; typedef struct { AppState state; uint8_t temp_max; uint8_t humi_max; uint8_t alarm_flag; } AppContext;在main.c的主循环里,我只需要按状态机结构调用对应的处理函数,整个业务逻辑一目了然。这里AI还帮我处理了一个小细节:按键消抖。如果按键接的是普通机械开关,在状态切换代码前得有去抖动处理,AI默认生成了20ms的消抖延时,这个点我一开始没提,但AI能自动考虑到,说明它对嵌入式开发的常见坑是有认知的。
总结一下这一小节的经验:驱动层AI能写但要重点审查,业务层AI既快又稳可以大胆用。差别就在于业务层的代码和硬件行为的耦合度低,AI不容易因为“看不见的硬件”而胡编。
3.5 代码审查:用AI找出AI写出来的坑
代码全部生成完后,我习惯做一个AI交叉审查。让另一个AI(或者同一个AI的新对话窗口)审查AI生成的代码。有时候自己写代码容易有盲区,AI审查也一样。给AI的审查提示词可以这样写:
你是嵌入式代码审查专家。请审查下面的STM32 HAL库代码。 重点检查: 1. 引脚配置是否和CubeMX生成的一致; 2. HAL库函数名称是否真实存在,版本是否匹配; 3. 是否有潜在的硬件时序风险; 4. 变量类型是否溢出; 5. 中断和主循环是否存在竞争问题。 如果有问题,请以表格列出:问题位置、问题原因、修改建议。实测下来,AI交叉审查能发现不少问题。比如说一次AI生成了一个I2C读写函数,里面用了HAL_I2C_Mem_Write,但参数类型是uint16_t,而实际API要求的是uint16_t MemAddress,表面看没问题,仔细一看AI把寄存器地址和内存地址混为一谈了。这种问题,用第二个AI一查就被揪出来了。
当然,AI交叉审查不是万能的。硬件相关的问题AI看不出来,只有测试才能暴露。所以做完审查后,最终还是要下载到板子上实测。
4. 调试环节,AI还能怎么帮忙
4.1 编译报错别急着百度,把报错原样丢给AI
STM32开发里最烦人的事情之一就是编译报错。以前遇到一个从没见过的报错,得复制粘贴到搜索引擎查半天,搜出来的结果还可能是好几年前的论坛帖。现在处理编译报错的流程变成了这样:
- 把Keil或者CubeIDE的完整编译输出日志复制出来;
- 连同出问题的代码文件(能贴就贴)一起发给AI;
- 让AI分析报错原因,并给出修复建议。
我给AI的提示词是这样:
下面是STM32项目的编译报错日志,请分析原因并给出修复方法: [粘贴完整的编译日志] 如果和代码有关,请说明问题代码的修改方式。举一个真实的例子。有一次我自己写代码时用了HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13),编译报错error: #20: identifier "GPIOC" is undefined。问AI之后,它直接指出是因为CubeMX配置里没开启GPIOC的时钟,并且对应的GPIOC宏定义在芯片头文件里没有使能。原因是工程里stm32f1xx_hal_conf.h中的HAL_GPIO_MODULE_ENABLED没打开,或者CubeMX根本没勾选GPIOC。这类问题对所有STM32开发者来说非常常见,AI几秒钟就解决了,不用再翻遍各大论坛。
还有个高频报错是Undefined symbol HAL_Delay,多半是HAL库延时相关的模块没包含进来。AI也会告诉你:去stm32f1xx_hal_conf.h确认HAL_CORTEX_MODULE_ENABLED有没有打开。这类经验在传统流程里可能要踩几次坑才能积累下来,现在AI直接就把答案给你了。
4.2 运行逻辑问题:串口日志 + AI分析
编译通过不等于程序能跑,运行时的逻辑问题才是最耗时间的。这个环节的关键是:先把能观测到的现象描述准确,再丢给AI分析。
我之前在调试这个环境监测项目时,遇到一个诡异问题:OLED上温湿度数据能显示,但偶尔会变成FF FF,而且报警蜂鸣器有时候不响,有时候乱响。我把串口日志和代码发给AI,并且描述了现象:“DHT11读取偶尔返回失败,报警状态异常切换。”AI分析后给出的判断是:DHT11读取失败后,数据没有做有效性判断,导致后续用全FF的数据去处理和显示;报警状态机的阈值比较用了无符号类型,而DHT11出错时返回的255比阈值大,所以触发报警。
这个案例说明了一个思路:AI分析运行逻辑问题的前提是,你能把“现象”转述成AI能理解的“状态信息”。所以在代码里,我习惯在所有关键状态切换和异常分支上都加串口日志输出,比如:
printf("[APP] DHT11 read fail, code=%d\r\n", ret); printf("[APP] Alarm triggered: temp=%d.%d, max=%d\r\n", ...);日志越完整,AI分析得越准。否则你丢给AI一句“程序不好使”,它再强也没办法凭空猜出你的硬件出了什么问题。
4.3 踩过的坑速查表:AI编程STM32常见问题实录
做完整的项目下来,整理了我在AI辅助开发过程中实际踩过、以及帮很多人排查过的高频问题,做成速查表分享给大家:
| 现象 | 常见原因 | 解决办法 |
|---|---|---|
| DHT11一直读取失败 | 微秒延时函数未正确实现,或GPIO速度配置太低 | 用定时器实现us级延时;确认GPIO输出速度配置为High |
| OLED显示白屏 | I2C地址错误或SDA/SCL引脚接反 | 确认SSD1306的0x3C/0x3D地址;用扫描工具检测I2C设备地址 |
| HAL_Delay卡死 | SysTick被占用或中断优先级配置错误 | 检查是否有其他中断把SysTick堵死;确认HAL_Init没问题 |
| ST-Link/J-Link连不上芯片 | 之前代码禁用了SWD接口,或者芯片进入了休眠 | 按住复位键的同时点击下载,在复位的瞬间连接;必要时用Flash Loader擦除整片 |
| 编译报错identifier undefined | CubeMX配置里没勾选对应外设,或芯片支持包版本不对 | 回到CubeMX把所有用到的引脚重新配置并重新生成代码 |
| 按键无响应 | GPIOC或对应GPIO时钟没开启,或输入模式没配置上拉 | 检查CubeMX引脚配置;用万用表量按键电平变化 |
| 串口输出乱码 | 波特率不匹配或时钟频率和代码预设不一致 | 确认CubeMX时钟树频率和串口助手波特率一致 |
| 报警蜂鸣器不响 | 蜂鸣器驱动引脚初始化和GPIO配置有问题 | 单独写一个测试函数翻转GPIO,排除硬件问题后检查PMW或延时逻辑 |
这个表格里前面几个问题和AI直接相关,后面几个更像是通用STM32开发经验。但我之所以一起列在这里,是因为AI辅助开发时更容易“甩锅”给AI:程序一不对就责怪AI生成的代码不行,结果往往是自己的基础环境出问题了。AI可以帮你写代码,但它不能帮你确认硬件连接、检查引脚波形。所以排查问题时,还是要按照“硬件—配置—软件”的顺序找原因。
4.4 调试心态:别让AI背锅,自己要有基本的硬件验证能力
用AI开发嵌入式软件最容易犯的一个错,就是过度依赖AI,导致自己对硬件行为的敏感度下降。AI生成代码跑不通时,很多人第一反应是“AI又坑我”。但这个项目的经验告诉我,大概率问题是出在硬件连接、时钟配置或者CubeMX生成环节上。
我养成了一个习惯:烧录之前先快速检查硬件层面的三件事——电源电压是否正常、地线是否共地、关键引脚的电平状态是否符合预期。这三件事花不了两分钟,但能把一半以上的“程序跑不起来”问题挡在门外。然后用Keil的调试模式把程序跑起来,在Debug界面看外设寄存器的值,比如GPIO的ODR端口输出寄存器是否符合预期,这个手段比反复改代码烧录可靠得多。
用AI能提高下限,但如果你连基本的硬件验证能力都没有,AI反而会放大你的盲区。它写代码没问题,但永远替代不了你对示波器波形、对寄存器数值、对硬件行为的基本判断力。这些基本能力,是我建议所有想用AI做嵌入式开发的人,先花几天时间把基础调试手段练熟的原因。
5. 用了半年AI编程,我的避坑清单和真实心得
5.1 最常见的AI生成STM32代码坑
这半年下来,AI生成STM32代码的坑也踩得七七八八了,选几个典型的说说。
一是HAL库函数名被AI篡改。AI会一本正经地生成一个看起来很像、但实际不存在的API,比如HAL_GPIO_Write_Pin(实际是HAL_GPIO_WritePin)、HAL_UART_Transmit_IT参数写反、HAL_TIM_PWM_Start的通道参数用错。排查这类问题最直接的办法就是让AI交叉自查,或者直接把API名在IDE里点进去看定义。
二是时钟频率相关的“想当然”。很多AI默认给STM32F103做72MHz主频,但如果你的外部晶振是8MHz而配置成了12MHz,PLL配置就全错了,串口波特率、定时器溢出时间全跟着错。哪怕用CubeMX生成的工程,AI生成代码时也可能在某个角落里写了个SystemClock_Config覆盖了原本正确的配置,这就是折腾人的地方。
三是引脚数超出芯片实际资源。AI偶尔会建议你用不存在的引脚,比如在小封装F103T8上让你用PB9,但芯片根本没有这个引脚,编译的时候才报错。这提醒我们:生成代码前把芯片型号和引脚映射表喂给AI,或者生成后对照芯片封装图快速确认一遍。
四是延时函数实现太粗糙。AI默认用的延时往往是大循环空转,在开优化的情况下行为不稳定。正确处理是用定时器、SysTick或DWT实现精确延时,尤其在DHT11、DS18B20、WS2812这类对时序敏感的外设上,这个坑特别突出。
5.2 嵌入式AI编程的正确姿势:小步迭代、上下文、验证
使用AI的核心经验可以总结成六个字:小步、上下文、验证。
小步指的是不要一次让AI替你生成一个大而全的完整工程,而是把项目拆成十几个小模块,一个模块一个模块地完成。比如先让AI生成DHT11驱动,验证通过后再生成OLED驱动,再验证。这样即使出错,定位范围也是小块的,不会出现一整盘代码堆在一起根本不知道从哪开始调的崩溃局面。
上下文指的是给AI的信息越“像你手上这个工程”,生成的东西越可靠。每次生成代码前,把芯片型号、主频、库版本、引脚定义、已有的代码片段都喂给它。如果AI工具有工程上下文功能(比如Cursor和Copilot),直接把整个工程目录加载进去,让AI看得见你项目里已有的文件,它会尽量避免覆盖你不该动的东西。
验证指的是AI生成的代码到了板子上必须走一遍真实的硬件验证。AI写得再完美,最终判断标准还是“硬件行为和预期一致”。我见过很多人沉迷于AI把代码写得天花乱坠,但下载到板子上跑不通,回头又说AI不行。其实不是AI不行,是你缺了验证这一步。用AI开发的正反馈应该建立在“每次改动都上板验证”的基础上,而不是“生成代码很爽,烧录跑不动”的挫败循环。
5.3 最后分享一个我现在一直在用的小技巧
最后说一个小技巧:我给自己建了一个私有“提示词库”,把常用的STM32开发相关提示词模板都存了下来。
比如生成外设驱动的模板、代码审查模板、编译报错排查模板、串口日志分析模板、状态机设计模板。每次新开项目,我先从模板库里调出对应的提示词,改一下芯片型号和引脚,再发给AI。这样既保证了AI生成质量的一致性,又不用每次从头描述需求。这个习惯让我AI编程的稳定性和效率都有了明显提升,推荐所有人都试试。格式也很简单,就是一个Markdown文件,按模块分类,每类下面存提示词和之前用过的成功案例,时间长了这就是你个人的“AI编程最佳实践手册”。