ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

STM32调试踩坑指南:从环境搭建到OTA的完整排查链

STM32调试踩坑指南:从环境搭建到OTA的完整排查链 1. 环境搭建阶段的三连坑芯片包、驱动和下载线我把话放在前头STM32开发调试中最消耗耐心的事情往往不是代码逻辑而是“程序怎么都下载不进去”。我第一次接触STM32的时候花了一个周末才把板子点亮期间大部分时间不是在写代码而是在折腾Keil、芯片包、ST-LINK驱动和一根不知道是不是坏了的USB线。这段经历让我明白一个道理——环境问题不像Bug有报错提示它只会以“No Target Connected”这种冷冰冰的句子怼你让人无从下手。1.1 芯片包装了还是找不到型号Keil5兼容C51和STM32安装这个话题在搜索热词里居高不下说明踩的人非常多。首先要明确一点Keil MDK用于ARM和Keil C51用于8051是两套完全独立的工具链可以装在同一台电脑上但安装目录一定要分开千万不要图省事装到同一个文件夹否则后装的会把前装的文件覆盖掉最后两边都打不开。芯片包的问题就更隐蔽了。用Pack Installer在线安装芯片包时国内网络经常下载到一半就断Pack Installer可能会提示失败也可能显示“installed”但实际文件不完整。这时候你去新建工程Device列表里就是找不到STM32F103C8T6。最稳的办法是去ST官网或者在各技术社区找离线包手动双击安装让Keil自动帮你解压到ARM/PACK目录。安装完成后有个验证技巧打开Keil点击Project - Manage - Pack Installer看Installed栏里有没有对应DFP包或者点击菜单Help - About确认当前使用的Pack版本号。如果你发现Pack明明装好了但新建工程时还是看不到芯片多数情况下是Pack路径指向了别的Keil版本——比如你电脑里同时装了Keil4和Keil5Pack被装到了Keil4的目录下。此时在Pack Installer界面里点那个“刷新”按钮或者手动把.pack临时拷贝到对应目录下重新装一次基本能解决。1.2 STM32无法识别USB设备从驱动到供电的排查插上ST-LINK后电脑提示“无法识别USB设备”这个坑出现频率极高而且原因五花八门。我先按出现的概率排个序驱动问题排第一USB线问题排第二板子供电问题排第三调试器本身损坏排最后。很多低价ST-LINK V2使用的是盗版或兼容固件Windows 10/11系统默认驱动不一定兼容需要手动安装驱动。最省心的做法是去ST官网下载STM32 ST-LINK Utility或者新版STM32CubeProgrammer安装包自带的驱动目录覆盖了绝大多数兼容版ST-LINK。如果装完驱动仍然显示未知设备打开设备管理器右键未知设备 - 更新驱动程序 - 手动查找 - 选择“从计算机的可用驱动程序列表中选取”再指向ST-LINK驱动目录试试。USB线的问题非常迷惑。有些USB线只能充电不能传数据插上之后电源灯亮了但设备管理器中完全没有新设备出现。我的建议是准备多根不同的USB线分别插到电脑后面板的USB口测试同时排除供电不足的可能。ST-LINK通过USB口给目标板供电时如果目标板功耗较大会导致电压被拉低芯片运行不稳定、下载失败。正确的做法是目标板用USB转TTL或者独立电源供电ST-LINK单独接USB两边共地即可。1.3 下载线的“玄学”SWD的四根线不能省ST-LINK和板子之间用的是SWD调试接口最少只需要四根线SWDIO、SWCLK、GND和3.3V3.3V不是必须但接上可以给部分板子的电平转换电路供电。SWDIO是数据线SWCLK是时钟线GND必须共地。很多人为了省事只接SWDIO、SWCLK和GND发现也能下载于是以为3.3V可接可不接。但对于一些低功耗板或者调试器供电能力弱的板子不接3.3V会导致目标芯片掉电复位下载到一半就失败。另一个很容易踩的坑是杜邦线太长。SWCLK频率较高时长杜邦线会引入干扰导致“RDDI-DAP Error”或下载失败。解决方法是把Keil里SW Mode的Max Clock调低比如从4MHz降到1MHz或800kHz。如果你的板子必须用十几厘米以上的杜邦线调试这一招立竿见影。最后提醒一句SWDIO和SWCLK接反也会导致No Target Connected用万用表通断档确认杜邦线两端引脚编号对不对这种问题最冤枉。2. 程序下载失败与芯片被锁一条完整的排查链路程序下载失败是STM32调试中最常见的现象而且错误提示五花八门。很多新手一看到Error就懵了其实每一种报错都有它的逻辑。我把常见的下载失败报错和对应原因整理成一个表格方便你对照排查。注意这不只是告诉你“为什么会报错”更重要的是给你一个完整的排查顺序避免在错误的方向上浪费时间。报错信息常见原因排查方向No Target Connected接线错误、目标板没供电、芯片锁死查SWD线序、板上电源指示灯No ST-LINK detected调试器未被电脑识别驱动异常查设备管理器、换USB口、重装驱动Error: Flash Download failFlash算法没选对、Flash地址越界Keil里Target页配置编程算法RDDI-DAP ErrorUSB供电不稳、SWCLK频率过高换USB口、降低SW时钟频率Internal command error调试器固件与Keil版本不兼容用STM32CubeProgrammer升级ST-LINK固件Cannot access target目标芯片进入低功耗模式按住复位键点击下载瞬间松开2.1 从设备管理器到目标板的五步走遇到程序下载失败我现在的排查顺序是固定的基本上能在十分钟内定位问题。第一步看设备管理器插上ST-LINK后有没有识别到“ST-LINK”相关设备如果没有问题在驱动或硬件。第二步打开Keil的Options for Target - Debug页签确认选择了ST-Link然后点击右侧Settings看里面能否识别到SW Device。如果Settings里的IDCODE区域是空白表示调试器和芯片没通讯上需要往板子方向查。第三步用万用表测板子电源轨确认3.3V正常SWDIO和SWCLK两个引脚上的电压不是0V或直接短到GND。第四步检查Boot0和Boot1引脚的电平状态——部分板子出厂时Boot0被拉高芯片会从系统存储器启动此时SWD可以连接但无法正常下载调试需要把Boot0拉低再试。第五步按住板子复位键在Keil里点下载下载动作发起的瞬间松开复位键这个方法能绕过芯片上电瞬间调试器连接不上的问题。2.2 Flash算法配置最容易忽视的一步芯片在Keil里能识别到但一下载就报“Error: Flash Download failed - Cortex-M3”十有八九是Flash编程算法没配好。新建工程时如果只选了芯片型号而没有在Target页面添加Flash算法Keil不知道用什么方式给芯片写Flash自然就失败了。解决方法在Options for Target - Target - Flash Download页签勾选“Programming Algorithm”点击Add按钮从列表里选对应的芯片Flash算法比如STM32F10x系列选“STM32F10x Med-density Flash”或“STM32F10x High-density Flash”具体看你用的型号是中等容量还是高密度。然后确认编程起始地址是0x08000000。这类问题在Keil5兼容C51和STM32的双环境电脑上尤其容易出因为某些版本的MDK会自动勾选默认算法但匹配错误需要手动调整。2.3 芯片被读保护锁死用ST-LINK Utility或CubeProgrammer解锁如果你在烧录配置里勾选了“Programming”后面的“Erase Sectors”之外还勾了“Reset and Run”之类或者在某些量产软件里开启了读保护又或者程序里自己操作了Flash写保护功能芯片就可能在下载时被锁定出现No Target Connected。此时芯片不是坏了而是调试接口被禁止访问。STM32支持在调试接口不可用时通过复位引脚配合ST-LINK的Connect Under Reset模式恢复连接在Keil的Settings里把Reset策略改成“Connect under Reset”或“Hardware Reset”通常能连上并重新烧录。连上之后用STM32 ST-LINK Utility或新版STM32CubeProgrammer打开目标芯片点击Target - Option Bytes把Read Out Protection从Level 1改成Level 0然后Apply。这里必须提醒解除读保护前芯片会执行一次整体擦除芯片里的代码和数据全部清空。如果你的设备里还有需要保留的数据先评估是否可以通过备份方式恢复。没有备份就只能认栽了。我手上就有一块板子因为量产前开启了读保护后来想回读Flash做逆向验证结果只能全片擦除重新烧录之前的出厂程序还得从版本库里重新拉出来编译浪费了不少时间。3. 串口调试乱码、丢字节和那个“不靠谱”的USB转TTL串口是STM32项目里使用频率最高、也最容易出幺蛾子的调试手段。我发现很多新手对串口有一个误区觉得USB转TTL模块插上就能用串口助手配好波特率就能收到数据。实际上串口通信失败的原因非常多元化从硬件电平到软件配置、从波特率偏差到中断处理逻辑任何一个环节有问题都会表现为同样的现象——乱码、没数据或数据错位。3.1 乱码先查波特率和晶振别急着改代码乱码是串口调试最常见的现象也是背锅最严重的问题。遇到乱码很多人第一反应是程序有Bug改来改去发现毫无变化。我的经验是乱码出现时先怀疑晶振和波特率配置因为这是最容易被忽略的硬件基础问题。STM32的UART波特率是由外设时钟除以分频系数得到的。F103系列通常使用外部8MHz晶振HSE经过PLL倍频后给USART1提供72MHz的时钟。如果你的板子上的晶振是8MHz但初始化代码用的是12MHz或者按内部HSI 8MHz配置波特率就会偏离预期。比如你配置115200实际发出的可能是96000甚至更低接收端按115200去解码收到的全是乱码。排查方法非常直接把TXD引脚接到逻辑分析仪或示波器上看一个字节的时间宽度估算实际波特率再对比串口助手里设置的波特率差别一目了然。另外不要忽略了USB转TTL芯片本身。CH340、CP2102、FT232这些芯片的驱动质量和抗干扰能力差别很大使用老版本PL2303驱动时如果系统为Windows 10/11很容易出现端口识别异常、收不到数据甚至蓝屏的情况。换一个品牌的模块往往能解决很多“灵异问题”。3.2 printf重定向半主机模式是卡死的元凶用串口助手打印调试信息时最常见的做法是重定向printf到UART。标准库的printf实现默认依赖半主机模式Semihosting在STM32裸机环境下如果你没有禁用半主机模式就调用printf程序会卡死在BKPT指令上表现为串口完全无输出或者程序不运行。解决方式有两种。第一种最推荐在工程选项里勾选“Use MicroLIB”MicroLIB是一个轻量级的C库它不依赖半主机模式重定向printf只需要实现一个fputc函数。第二种手动实现fputc后再在代码中屏蔽半主机模式相关的函数如下所示int fputc(int ch, FILE *f) { /* 等待上一个字节发送完成 */ while (!(USART1-SR USART_SR_TXE)); /* 发送当前字节 */ USART1-DR ch; return ch; }这里还有个隐藏较深的坑如果你在中断服务函数里调用printf或者在多线程RTOS环境里多个任务同时printf会导致字符交错、卡死。printf是阻塞型函数在处理高速数据流或实时性要求较高的控制环路时务必避免直接调用优先使用环形缓冲区加DMA发送的方式。3.3 丢字节和首字节丢失中断里别做耗时操作串口接收丢数据的根因绝大多数是中断服务函数ISR里的处理逻辑太耗时。UART波特率9600时收到一个字节只需要大约1ms115200时只需要约87us。如果在ISR里做了字符串解析、协议处理、调用printf打印等耗时操作下一个字节到来时ISR还没退出中断被挂起数据就被后面的数据覆盖了。 正确处理方式在ISR中只把收到的字节放进环形缓冲区解析和业务处理全部放到主循环中执行。接收中断标志位的处理也需要注意——STM32的USART要避免先读DR再读SR因为接收数据寄存器非空时RXNE标志位会被硬件清除正确的顺序是先检查SR、再读DR这个细节能避免偶发性丢字节。首字节丢失的怪现象也有一个常见来源发送端和接收端共地不完整。两个开发板之间用串口通信时必须保证两边GND连在一起否则参考电压不一致会出现第一个字节是乱码或丢失、后面的数据正常的情况。此外USB转TTL模块在刚插入电脑USB口的瞬间TXD引脚会有一次电平抖动如果此时目标板恰好处于接收状态可能误触发一次串口中断。处理办法是在软件上对接收启动进行延时或在硬件上给TXD/RXD串一个1kΩ左右的限流电阻。4. 外设应用中的隐藏规则时钟、编码器、测频与超声波当你迈过了下载和串口这两个大坑真正的业务代码调试才刚刚开始。我发现很多项目Bug的根源是“对芯片内部机制理解不够深”典型表现就是时钟配置不对导致外设工作异常编码器脉冲乱跳导致位置漂移测频值不稳定导致速度波动超声波模块把引脚烧坏。这些外设问题单独看都不复杂但如果不理解芯片内部的工作逻辑排查起来会非常痛苦。4.1 时钟树所有外设正确性的基石STM32的时钟系统是一棵树所有外设的时钟都从这棵树的根节点分出来。根节点可以是外部高速晶振HSE也可以是内部RC振荡器HSI。HSI的优势是上电即用缺点是精度不够高且受温度影响明显如果你对串口波特率、定时器时序有要求请使用HSE锁相环倍频的方式生成系统时钟。外部晶振不起振是常见问题表现为程序上电后跑不起来或者跑起来极慢用示波器测量晶振引脚看不到振荡波形。晶振不起振的原因通常有三个晶振虚焊或引脚短路、负载电容不匹配、内核电压不足。还有一个很容易忽略的点——示波器表笔的寄生电容可能导致晶振停振测量时换用10倍衰减档并减小表笔接触面积或者直接看SystemCoreClock的值来判断。如果你用的是HAL库时钟初始化在SystemClock_Config函数里标准库则在SystemInit里。无论哪种调试任何外设之前先在调试器里看变量SystemCoreClock是否等于芯片主频。我在一个F103项目里就遇到过这种情况工程是从F407移植过来的PLL配置参数没改F103输出了128MHz的超频时钟芯片居然还能跑但USART波特率、定时器时间全部错乱排查了很久才发现是时钟源倍频系数的锅。4.2 编码器模式为什么位置值总在乱跳编码器是电机控制项目中不可或缺的传感器STM32的定时器有编码器接口模式可以直接对AB相正交信号解码省去外部解码芯片。这个模式配置不复杂但实际调试时最常出现的问题是电机没转计数器却在乱跳。这种情况几乎都是硬件电气问题。编码器的AB相输出通常是开漏结构或推挽结构如果外部没有上拉电阻引脚电平会悬空抖动定时器检测到无数个假脉冲计数器自然乱飞。排查方法用示波器看AB相引脚波形如果边沿很缓或有很多毛刺就需要给信号线加上拉电阻或者在定时器配置里开启输入滤波器Input Filter设置一个合理的滤波长度滤掉毛刺。另外一个隐蔽问题是倍频混淆。编码器接口模式支持1倍频、2倍频和4倍频计数。1024线的编码器如果配成4倍频转一圈计数4096如果配成1倍频转一圈只计1024。程序里处理位置时如果不统一单位你会发现位置值和实际角度对不上。初始化编码器模式后建议先把TIMx-CNT清零再读取一次确认是0再开始工作避免上电瞬间引脚电平不确定引入的误计数。4.3 测频法高低速场景要用不同的测量策略测频法在电机测速、流量计等场合非常常用。STM32测频的原理可以拆成两种M法测频率法在固定时间闸门内对输入脉冲计数适合高速信号T法测周法测量单个输入脉冲的周期适合低速信号。如果电机转速范围变化很大只靠一种方法容易顾此失彼更稳的策略是M/T法同时测量实际闸门时间和该时间内的脉冲数进而在全速段都保持精度。M法实现时的经典坑点使用两个定时器配合比如TIM2定时100msTIM3外部计数读取计数器时如果在读取高16位和低16位之间发生了计数溢出会读到脏数据。32位计数器没有这个问题但16位计数器就非常容易出现。处理方式是先禁用计数、再读取、最后恢复计数或者直接使用定时器的影子寄存器部分型号支持来原子读取。调试测频功能时我发现示波器或信号发生器是非常有效的工具。用信号发生器直接给定时器引脚输入已知频率的方波比如10kHz看程序计算的结果是否接近10kHz误差在小数点后一位以内说明测频逻辑没问题如果差距很大再回头检查定时器配置和时钟分频。4.4 超声波测距5V电平回灌烧引脚热词里“stm32超声波测距”出现频率很高这是很多毕业设计和入门项目的选择。HC-SR04这类超声波模块的工作电压是5VTrig和Echo引脚输出信号也是5V电平。如果你直接把Echo引脚接到STM32的3.3V GPIO上5V电平会通过引脚内部的保护二极管回灌到VDD长期或大电流情况下轻则引脚损坏重则芯片烧毁。正确做法是加电平转换电路Echo输出先经过一个电阻分压比如2kΩ和1kΩ串联分压到大约3.3V再接到STM32引脚或者使用MOS管单向电平转换。另一条思路是选3.3V供电的超声波模块比如RCWL-9600省去电平转换的麻烦。软件层面测量Echo高电平脉宽通常使用输入捕获功能测得的脉宽乘以声速再除以2就能得到距离。声速并非固定值而是随温度变化0℃时约331m/s20℃时约343m/s。如果你的项目在室外使用季节温差会导致几厘米级别的测量误差在有精度要求的场景建议加上DS18B20等温度传感器做声速补偿。最后别忘了盲区处理超声波在近距离时存在测量盲区软件里设置一个最小有效距离比如3cm以下的测距值直接丢弃否则会出现反射波叠加导致的异常读数。5. OTA与批量下载Bootloader、分区和量产线的坑进入生产阶段后调试的重点从“让代码跑起来”变成了“让产品可维护、可量产”。OTA升级和批量烧录这两件事是我在实际项目里被坑得最惨的部分。OTA搞不好会让设备变砖量产烧录搞不好会让生产线停摆。下面把这两块的关键点和踩坑经验梳理一下。5.1 Bootloader跳转App中断向量表偏移是第一优先级OTA升级方案的常规结构是Bootloader放在0x08000000起始地址App放在0x08008000或更高地址。Bootloader负责检查升级标志通过串口、WiFi或4G接收固件包写入App分区后跳转执行。App工程的IROM1起始地址必须修改为App存储的起始地址同时大小要小于Flash总容量减去Bootloader占用大小。完成这些还不够最关键的一步是设置中断向量表偏移。ARM Cortex-M3/M4内核的中断向量表默认位于0x08000000如果App放在0x08008000但不修改向量表偏移App启动过程中一旦发生中断比如系统节拍、串口中断、外部按键CPU会去0x08000000处找中断处理函数找到的是Bootloader的中断向量导致App异常重启或卡死。标准库的写法是调用NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000)HAL库的写法是SCB-VTOR 0x08008000写在App主函数开头越早越好。跳转函数本身也有讲究typedef void (*pFunction)(void); pFunction JumpToApp; /* 关闭全局中断 */ __disable_irq(); /* 将外设恢复到复位状态 */ HAL_RCC_DeInit(); SysTick-CTRL 0; SysTick-LOAD 0; SysTick-VAL 0; /* 设置MSP为主堆栈指针 */ __set_MSP(*(volatile uint32_t *)0x08008000); /* 取出App的Reset_Handler地址并跳转 */ JumpToApp (pFunction)(*(volatile uint32_t *)(0x08008004)); JumpToApp();这里有个百度都搜不太到的细节跳转前必须关闭全局中断并把SysTick和外设全部复位否则App启动时会带着Bootloader的环境运行HAL库的初始化很可能因此卡在某个等待标志位的死循环里。跳转失败时现象是程序停在Bootloader里没有任何报错很容易误判为App代码问题实际是跳转前残留状态的锅。5.2 升级断电变砖双分区加回滚标志OTA升级中最悲剧的场景是设备正在写入Flash突然断电或通信中断App分区写了一半下次重启连Bootloader都进不了。因为Bootloader要检查App分区是否有效发现校验失败直接停在等待升级状态设备就成了“砖”。还过得去的方案是Bootloader App 备份区A/B分区升级时先写入备份分区校验通过后再拷贝到App分区或者直接把启动标志从A切到B。这样即使升级中断恢复出厂版本仍然是完整的。另一种简单方案是Bootloader存储两个标志位升级请求标志和升级完成标志上电时如果发现升级完成标志未置位就判定上次升级失败继续停留在Bootloader等待新固件而不是跳到半成品App。批量下载时也一样量产工位烧录完最好做一次校验回读。用STM32CubeProgrammer命令行模式可以批量烧录hex/bin并设置选项字节。这里要特别提醒量产烧录不要随便勾选读保护一旦开启后面想通过调试器回读程序或更新出厂固件都被限制必须先全片擦除再解除效率大打折扣。ST-LINK Utility是老工具现在ST官方已经用STM32CubeProgrammer取代了它新项目建议直接用CubeProgrammer。5.3 换芯片型号和库版本启动文件与引脚复用是重灾区STM32家族型号众多F1和F4的启动文件、外设库都不完全相同。从F103代码移植到F407最大的坑是启动文件startup_stm32f407xx.s没有添加编译时可能报了“未定义SystemInit”或“HardFault_Handler”之类的错误下载到板子上直接死机。启动文件负责初始化堆栈、调用SystemInit、建立中断向量表缺了它程序根本没法正常启动。引脚复用也是F1升级F4的高发问题。F103的GPIO是普通的推挽/开漏配置F407则引入了GPIO_AF复用功能概念使用USART、SPI、I2C等外设时引脚必须配置为相应的AF通道比如USART1_TX要配成GPIO_AF7_USART1。如果忘了配AF程序逻辑再正确外设也不会有输出。这类问题调试时表现为“代码看起来全对但硬件没反应”非常容易让人怀疑芯片坏了。 解决方法是每移植一个外设就去对应的数据手册查引脚复用表不要靠猜。用STM32CubeMX重新生成管脚配置是最省力的做法它会把F1到F4的差异自动规避掉再把生成的初始化代码拷到你的工程里能省一半的排查时间。6. 调试习惯把时间花在“正确的事”上前面聊的都是具体问题最后我想聊点方法论层面的东西。调试STM32项目这些年我最大的心得是大多数看似复杂的Bug其实不用debugger也能定位而真正难缠的问题靠的也不是反复试错而是成体系的排查顺序和工具链。6.1 从“改代码试试”升级为“控制变量法”遇到Bug第一反应是“改一行代码试试”这是新手最常见的做法也是最浪费时间的方式。更有效的策略是控制变量法把可能出问题的环节逐个隔离每改一个地方就测试一次直到找到真正的原因。比如串口收不到数据不要先去改中断优先级或重新初始化UART而是先拿逻辑分析仪看TXD引脚有没有波形。有波形说明单片机已经发送问题在接收端没波形再回头查UART配置、时钟使能、GPIO复用。实际操作中控制变量的顺序也有讲究我自己的顺序是先查硬件供电、接地、接线再查时钟SystemCoreClock、外设时钟然后查配置GPIO模式、中断、定时器参数最后才是逻辑协议解析、状态机。这个顺序符合“从底层到上层”的排查逻辑能最大程度避免在错误层面积累错误结论。6.2 日志与状态机让程序自己“说话”printf大法虽然看起来土但在很多场景下比仿真器更高效。定时器中断、PWM输出、ADC采样这类实时性要求较高的地方断点调试会改变程序的时序行为导致“加了断点能用取消断点就坏”的诡异现象。日志输出的设计原则是不要在所有地方都加日志那样日志本身会拖慢系统而是要针对关键节点输出比如协议帧的收发、状态机的跳转条件、错误标志位置位等。对于复杂的交互逻辑我强烈建议用状态机的方式组织代码。每个状态对应一组明确的入口条件、执行动作和退出条件当出问题时看一眼当前状态和跳转条件就能定位。配合条件编译开关比如#define DEBUG_ENABLE可以在开发阶段打开日志量产时一键关闭不会影响最终代码体积和运行效率。6.3 版本管理代码提交信息和实验记录调试过程中经常遇到一种情况今天改了个参数明天发现问题但你忘了昨天改了什么。没有版本管理的项目就是给自己埋雷。STM32项目完全可以享受Git的好处别因为Keil工程文件多就放弃。我目前的习惯是每次有可编译、可运行的版本就提交一次提交信息写明改动点和测试结果。遇到调试卡壳的时候可以直接回到上一个能跑的版本用二分法缩小问题范围。还有一些信息是代码本身不会告诉你的比如引脚接线、拨码开关状态、烧录选项、环境温度和电源电压。手上常备一本小本子或者电子笔记把这些信息记录成“实验日志”很多看似无解的Bug翻看实验日志后会发现原来是某个硬件跳线帽被他人在无意中动过。6.4 善用调试工具STM32CubeProgrammer和逻辑分析仪最后但同样重要的是不要把所有调试压力都压在Keil身上。STM32CubeProgrammer除了烧录解锁还能擦除Flash、配置选项字节、读取芯片信息甚至能读取Flash内容配合对比逻辑分析仪价格低廉在串口、SPI、I2C、编码器信号的调试中几乎不可替代。我现在的默认排查工具包里必有一块万用表、一个逻辑分析仪、一个USB转TTL模块、一个ST-LINK外加一根质量有保证的USB线。工具不需要多昂贵但每次用的时候要清楚它测量的是什么、能反应什么问题。我个人的体会是STM32调试到了后期真正让人成长的其实不是某个具体问题的答案而是解决问题的过程从现象到思考、从实验到结论的一整套方法。一个踩过的坑如果只是记在笔记里就浪费了把它转成可复用的排查清单下次遇到同类问题才能更从容。如果这篇文章里有一个坑能帮你省下一晚上的熬夜排查时间那这个踩坑总结就没白写。
返回列表