尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

UART烧录STM32H753ZI踩坑实录:从连不上到稳定量产

UART烧录STM32H753ZI踩坑实录:从连不上到稳定量产 UART烧录STM32H753ZI踩坑实录从连不上到稳定量产烧录的完整排查过程干嵌入式这么多年用ST-LINK烧录STM32几乎是肌肉记忆。但真到了现场调试或者小批量产的时候手边只有一块Nucleo-H753ZI、一根USB转串口线、一台不连外网的工控机ST-LINK那套就不太现实了。于是UART烧录成了唯一的救命稻草——这本该是STM32的“基本操作”可真在这块板子上走一遍从驱动、接线、BOOT引脚到CubeProgrammer的各种报错能把你折磨到怀疑人生。这块板子的板号是MB1363主控是STM32H753ZICortex-M7最高480MHz在ST的生态里属于性能担当。问题是性能越强系统层面的启动逻辑就越复杂UART烧录踩坑的概率也越高。这篇文章不打算复制手册只讲我在这块板子上一次UART烧录失败后从硬件接线、启动模式、驱动安装到报错排查的完整链路以及最后稳定量产烧录的实操经验。如果你也卡在“No STM32 target found”或者“Timeout error”这种报错上这篇文章应该能帮到你而且顺便帮你把UART通信协议和系统bootloader的原理也理清楚。1. UART烧录H753ZI为什么会走到这一步1.1 明明有ST-LINK为什么还要UART烧录先说个反直觉的事实Nucleo-H753ZI板载了ST-LINK正常情况下插上USB线ST-LINK会被识别为调试器烧录调试一条龙体验很好。但工程现场很少这么理想。我之前遇到的情况是这样的产品样机用的是H753ZI调试阶段一直走SWD接口。到了小批量验证阶段生产现场没有装ST-LINK驱动也没有J-Link只有一台工控机和一个USB转串口模块。而且产品是封闭式外壳没有预留SWD接口只引出了一组UART引脚用于和上位机通信。这时候要在不改硬件的情况下更新固件UART烧录就是唯一的路。另一个场景是量产工厂流水线上烧录程序不可能每台设备都配一个调试器成本太高。大部分量产方案是生产线统一走UART烧录或者产品出厂前预留串口烧录接口现场升级Bootloader后通过网络或串口更新 Application。STM32全系列出厂时ROM里都有一段系统Bootloader支持UART烧录这相当于芯片自带的“最小引导程序”不需要额外烧录任何代码就能用。1.2 UART烧录与其他烧录方式的取舍在H753ZI这块板子上除了UART烧录还有几种替代方案SWDST-LINK/J-Link、USB DFUDevice Firmware Upgrade、以及通过自定义Bootloader的串口更新。这几种方式各有特点烧录方式需要的硬件优点缺点SWDST-LINK/J-Link调试器速度快、支持调试、带读保护解除需要调试器成本高现场不一定有USB DFUUSB线不需要额外硬件USB口现成需要芯片支持USB bootloader引脚要引出USBUART系统BootloaderUSB转串口硬件要求最低串口几乎都有速度相对慢BOOT引脚需要能控制接线容易错自定义BootloaderUARTUSB转串口可定制、支持升级校验需要自己写Bootloader而且Bootloader本身要先烧进去如果只是临时救急比如我的现场场景UART烧录最划算。但如果产品要大规模量产我建议还是花时间写一个自定义Bootloader配合上位机做固件校验和断点续传比直接用系统Bootloader更灵活。这篇文章后面讲的原理和排查方法对自定义Bootloader也同样适用。2. 先弄清启动机制UART烧录前必须理解的原理2.1 System Bootloader芯片出厂自带的“小型引导程序”STM32的每一颗芯片在出厂时都在ROM里烧录了一段固件这段固件叫System Bootloader也叫系统引导程序。它不是存在Flash里的用户代码而是ST在生产时固化在芯片内部存储器里的独立程序。你没法擦除它也没法修改它但它一直在那里等着你把它“激活”。这段Bootloader的作用是在特定条件下芯片上电后不执行用户Flash里的程序而是执行ROM里的程序。这个程序会初始化一些外设比如UART、USB、CAN等具体支持哪些外设取决于芯片型号然后在一个固定引脚上等待主机的命令。主机PC端通过UART发送特定的命令帧Bootloader收到后执行擦除Flash、写入Flash、校验数据等操作。这个过程和电脑的BIOS有点像电脑上电时先运行BIOS然后根据设置决定从硬盘、U盘还是网络启动。STM32的System Bootloader就是“BIOS”BOOT引脚设置就是“选择从哪个设备启动”UART烧录就是“从串口启动”。2.2 BOOT0引脚与启动模式选择要让H753ZI进入系统Bootloader最核心的动作是把BOOT0引脚拉高然后复位。这里有一个非常容易踩的坑很多人以为BOOT0拉高后芯片会立刻进入Bootloader模式但其实关键不在于拉高这个动作而在于拉高之后必须有一个完整的复位过程——BOOT0引脚的电平是在复位信号的上升沿被锁存到芯片内部的如果先上电再拉高芯片已经运行了用户程序此时再拉BOOT0并不会切换启动模式。具体到STM32H753ZIBOOT0引脚是PH3。在Nucleo-H753ZIMB1363板卡上BOOT0默认是下拉的也就是通过一个电阻接到地正常启动走主Flash。要进入Bootloader一般有两种方式如果板子上有跳线帽把BOOT0对应的跳线短路到高电平然后按复位键。如果没有预留跳线Nucleo-144板上一般是焊桥SB就需要用杜邦线直接把PH3引到3.3V或者用镊子短接焊桥。用示波器看过的话你会发现BOOT0拉高后只要复位一下芯片在复位释放的瞬间采样BOOT0电平为高然后跳转到ROM里的Bootloader。这时候用户程序不会运行LED灯也不亮串口上会等待主机发来的握手命令。2.3 H753ZI上Bootloader默认启用的串口引脚这是另一个坑。很多人以为UART烧录随便接哪个串口都行实际不是。STM32H753ZI的系统Bootloader支持的UART引脚是固定的参考ST官方文档AN2606H753ZI的Bootloader在UART外设上支持以下引脚组合外设TX引脚RX引脚USART1PA9PA10USART2PA2PA3USART3PB10PB11USART6PC6PC7注意有的版本Bootloader还支持 LPUART但使用优先级和默认握手引脚排序上USART1排最前面。也就是说如果条件允许优先使用USART1PA9/PA10因为System Bootloader启动后初始化的第一个串口默认就是USART1握手成功率最高。这里特别说明一下上文提到的具体引脚号和板卡丝印位置如果手里有Nucleo-H753ZI的原理图或用户手册对应文档编号通常与MB1363板卡一起提供强烈建议先查一下USART1对应的排针位置不要盲猜。很多Nucleo板卡的串口是通过板载ST-LINK的虚拟串口复用的默认可能接到USART3或其他引脚如果你把USB转串口接到PA9/PA10以外的引脚即使BOOT0拉高了也等不到主机握手。3. 从接线到连接一套可复现的完整操作流程3.1 硬件准备与接线先说硬件。我现场用的USB转串口模块是FT232R也就是常见的蓝色USB转TTL小板。后来换过CP2102N也试过FT231X驱动装好后使用上没有本质区别。重点是接线一定不能错UART烧录的接线比SWD严格得多共地USB转串口的GND必须和H753ZI的GND连在一起不共地的话电平参考就不一致通信必然失败。TX接RXRX接TXUSB转串口的TX要接到目标板的RX引脚PA10RX接到目标板的TX引脚PA9。很多人第一次接反了导致完全没反应。这里可以用一个简单的类比你和对讲机通话你的听筒对着他的嘴他的听筒对着你的嘴。RX接收必须接对方的TX发送如果两头都接了各自想要的方向等于两个人都对着自己的话筒说话谁也听不见谁。接线表USB转串口模块 STM32H753ZI GND -------- GND TX -------- PA10 (USART1_RX) RX -------- PA9 (USART1_TX)有条件的话接线尽量短杜邦线不要超过10cm。我之前在测试台上用了一根20cm的杜邦线波特率115200时偶尔会通信失败换成10cm以内的线就好了。如果你在强电磁干扰环境下烧录比如旁边有大电机、开关电源短接线加上合适的波特率会显著提高成功率。3.2 软件准备驱动、STM32CubeProgrammer与串口状态软件这边首先要确保USB转串口的驱动装好了。FT232R用的是VCP驱动在Windows下插上后设备管理器里会出现一个COM口比如COM3或者COM5。如果设备管理器里显示的是感叹号那先装驱动再继续。CP2102N需要装Silicon Labs的驱动包FT231X同样需要FTDI的驱动。这里插一句很多人烧录失败不是硬件问题也不是板子问题而是驱动没装好系统压根没有正确识别出串口。装好驱动后最好先用一个串口调试助手比如SSCOM打开对应COM口手动发一个0x7F字节。为什么是0x7F这是STM32 System Bootloader的握手协议要求的Bootloader启动后会在UART上按固定波特率通常自动检测默认内部波特率约115200但Bootloader会根据收到的0x7F帧自动校准等待接收0x7F收到后才会回一个0x7F或0x79作为应答。如果串口助手发出去之后能收到回应说明Bootloader已经启动了只是握手成功与否还需要看通信格式。这一步可以提前验证硬件链路和Bootloader是否激活。然后安装STM32CubeProgrammer目前版本支持Windows/Linux/Mac接口支持UART、USB、SWD、SPI等。我用的版本是较新的9.x版本对于H753ZI这种新芯片建议用较新的版本因为老版本可能没有准确的H7系列器件数据库识别芯片和擦写Flash会出问题。3.3 操作步骤拉高BOOT0、复位、连接、烧录整个UART烧录流程可以拆成下面几步按顺序执行基本不会乱把USB转串口插到电脑确认驱动正常记住COM口号。把BOOT0PH3拉高到3.3V。这一步可以直接用杜邦线短接PH3和3.3V排针但要注意别碰到旁边的引脚。按一次板子上的复位键Nucleo板上一般是标注RESET的黑色按钮让芯片在BOOT0为高的状态下重新启动。打开STM32CubeProgrammer在界面左侧选择UART接口模式选择对应的COM口和波特率默认115200即可如果通信有问题可以降到9600。点击“Connect”正常情况下右侧会识别出芯片型号STM32H753ZI和Flash大小、UID等信息。连接成功后在“烧录”页面选择.hex文件或者.bin文件bin文件需要手动指定起始地址0x08000000。点击“Start Programming”等进度条跑完出现“Download verified successfully”提示。烧录成功后断开连接把BOOT0拉回低电平再次按复位键用户程序就开始运行了。这里特别强调一下第7步烧录完成后不要急着拔线先确认校验通过。如果校验失败大概率是硬件接线或供电问题可以按下一节的排查思路处理。另外有个小细节在CubeProgrammer连接之前建议先确认没有其他软件比如串口调试助手、打印日志的终端占用这个COM口。之前我在调试时开着两个串口软件同时打开同一个COM口CubeProgrammer一直报“Unable to open port”或者连接超时关闭其他软件后立刻就好了。4. 报错排查H753ZI UART烧录中最容易踩的坑4.1 连接失败“No STM32 target found”的排查链路这个报错是UART烧录里最常见的几乎80%的失败都指向这个错误。它意味着CubeProgrammer通过UART发送了握手命令但没有得到任何有效响应。遇到这个报错排查顺序很重要不要一开始就去怀疑芯片坏了先确认BOOT0状态上电前或复位前BOOT0是否为高用万用表量一下PH3对地电压应该在3.3V左右。如果量出来是0V说明拉高没生效可能是接触不良也可能是焊桥没短接正确。检查复位确认复位键按下去并且松开后芯片确实重启了。如果不确定可以再次按一次复位键再点Connect。检查串口号设备管理器里确认当前COM口号CubeProgrammer里选的是否一致。注意有些USB转串口模块在插拔后COM号会变。检查RTS/DTR信号有的USB转串口模块默认把RTS或DTR接到了一个电平控制脚如果模块在打开串口时拉低了DTR可能导致目标芯片的复位或者BOOT状态被干扰。最简单的办法是换一个不控制RTS/DTR的串口工具或者用串口助手把所有引脚默认电平设为高再关闭。我之前遇到过一次很典型的“No STM32 target found”排查了两小时最后发现是USB转串口模块的DTR引脚默认被拉低而我把DTR接到了板子的复位脚上导致每次打开串口板子就自动复位一次复位瞬间BOOT0正好还没稳定Bootloader就错过了握手窗口。后来把DTR悬空问题直接消失。4.2 接线与通信问题RX/TX反接、线材和波特率如果说BOOT0是最大的坑那RX/TX反接就是第二大的坑。这个错误的典型症状是CubeProgrammer连接时没有任何回应或者报“Timeout”。排查方法很简单——把TX和RX两根线对调一下即可。但还有一种隐蔽的接线问题部分USB转串口模块的TX/RX引脚电平不是标准的3.3V而是5V。虽然STM32的引脚大多容忍5V输入但H7系列某些引脚并不完全兼容5V而且长期用5V电平去驱动3.3V的UART引脚有烧毁引脚的潜在风险。所以优先选择3.3V电平的USB转串口模块或者用485转串口工具电平转换芯片不要直接用5V的RS232电平。线材方面我之前遇到过一种情况杜邦线内部接触不良万用表量导通是好的但一有电流就断断续续。这种问题非常隐蔽因为静态测量没问题动态通信时就会失败。如果各种排查都做了还是连接不上换一根杜邦线试试成本最低。波特率方面H753ZI的Bootloader支持自动波特率检测CubeProgrammer默认115200一般都能连上。但如果你用了质量很差的线或者线太长115200的边沿抖动太大会导致误码。这时可以把CubeProgrammer的波特率降到9600或者19200试试成功率和线路容错能力都会提升。缺点是传输速度会慢小固件影响不大几MB的固件会明显久一些。4.3 串口工具与驱动FT232/FT231X/CP2102N识别问题USB转串口芯片是UART烧录里的“最后一公里”它的问题往往伪装成其他问题。常见的故障现象CubeProgrammer里能看到COM口但点连接就卡住或者进度极其缓慢。我最早用的一批FT232R模块在Win10下偶尔会出现驱动不稳定的情况表现为设备管理器识别正常但打开串口后根本无法通信。后来我在设备管理器里把该COM口禁用再启用问题解决。另外FT231X和FT232R虽然都是FTDI的芯片但驱动版本对老芯片的支持不太一样如果驱动装的是新版遇到老芯片反而可能有问题。我的经验是遇到驱动异常去FTDI官网下载对应芯片的专用驱动不要用Windows自带的或者第三方驱动工具自动安装的。CP2102N是Silicon Labs的芯片驱动相对稳定但安装时需要区分32位和64位系统装错了系统会一直显示感叹号。如果手头有CP2102N和FT232R两种模块可以用A/B替换的方式排查是模块的问题还是目标板的问题。4.4 读保护与选项字节难以察觉的元凶还有一个很隐蔽的问题芯片的读保护等级RDP不是Level 0。如果之前用STM32CubeProgrammer或者别的工具设置过读保护Level 1或Level 2那UART烧录时可能会直接拒绝连接或者连上之后无法读取Flash内容。这种情况的排查方法是在CubeProgrammer连接时即使提示失败也先操作一下“读保护等级”设置把级别调回Level 0。注意如果之前设的是Level 2那芯片可能彻底锁死连UART和SWD都无法访问只能靠ST-LINK的硬件解除保护如果支持或者直接换芯片。所以量产环节一定要做好读保护的管理不要轻易上Level 2。另外H7系列有个特殊性选项字节里还有RDP、WRP等位如果配置错误可能会影响UART烧录的擦写操作。遇到“Programming error address”这种报错检查一下选项字节把RDP设回Level 0把WRP相关位清除再重新尝试。5. 实测中的经验与小技巧5.1 建议提前确认的板子细节如果你用的是Nucleo-H753ZIMB1363有几个细节建议在开工前就确认清楚板载ST-LINK的虚拟串口VCP默认连接到了哪个USART。VCP的跳线如果短接会占用USART1的PA9/PA10。如果你的USB转串口模块也要用PA9/PA10需要把VCP对应的焊桥断开否则两路信号会打架。BOOT0的焊桥在板子上的具体位置。Nucleo-144的板子BOOT0焊桥往往靠近ST-LINK的排针区域。如果找不到直接查用户手册的原理图。板子的供电能力。如果只靠USB口供电且板子又接了外部外设电流可能不够稳定UART烧录时容易在校验阶段失败。我的建议是如果手头有外部3.3V稳压电源直接给板子的3.3V和GND供电USB线只做串口这样供电最稳。5.2 提高烧录成功率的几个小习惯经过多次实测下面这些习惯确实能把烧录成功率从五五开提到九成以上先连接再烧录不要直接点“Start Programming”先点Connect确认芯片识别成功后再烧录。连接成功表示bootloader握手已经完成此时烧录基本不会因为链路问题失败。尽量用短杜邦线10cm以内的线最稳。20cm以上导线在115200波特率下容易出现边沿失真。供电要稳如果板载LED在烧录过程中出现闪烁或者亮度变化说明供电不足优先解决供电。不要同时打开多个占用串口的软件CubeProgrammer、串口助手、日志监控工具同时占用同一个COM口会导致握手失败。用.hex文件替代.bin文件hex文件自带地址信息不会出现地址填错烧到错误位置的问题。bin文件如果地址填错0x08000000写成了0x8000000轻则烧录失败重则覆盖起始向量表导致程序跑飞。5.3 烧录之后的验证与恢复烧录完成并不是结束至少要做两件事验证断开CubeProgrammer的连接BOOT0拉低按复位键确认用户程序正常启动。如果程序有串口打印观察输出是否正常如果程序控制LED看LED是否按预期闪烁。如果发现程序没启动优先检查复位后是否走了正确的启动路径BOOT0是否确实恢复低电平Flash里是否有有效向量表。可以用CubeProgrammer再连接一次读取Flash起始地址的0x08000000处的8个字节确认栈指针和复位向量是否正确。如果这两个值看起来是0xFFFFFFFF说明Flash没有被正确写入。另外提醒一点UART烧录后芯片的调试寄存器状态可能会和SWD烧录时不太一样。如果你在烧录完成后想接着用ST-LINK调试最好先把板子完全断电再上电一次让调试器能重新枚举目标芯片。我遇到过几次烧录后ST-LINK连不上的情况重新上电就好了。6. 一个容易被忽略的进阶选择从系统Bootloader到自定义Bootloader既然已经摸清了系统Bootloader的脾气最后聊一个进阶话题。直接用系统Bootloader做UART烧录最大的限制有几个引脚固定不能随意换串口。协议固定不能加自定义校验、加密或者断点续传。对BOOT0引脚的依赖很强现场没有留BOOT0控制线就很麻烦。这就是为什么很多产品最终会写一个自定义Bootloader。底层思路其实和系统Bootloader一样芯片上电后先进入BootloaderBootloader通过UART等待上位机发来的固件升级命令收到数据后写入Flash的Application分区校验通过后跳转执行。我在一个量产项目里就是这么做的把BOOT0焊桥固定拉高但不用系统Bootloader而是自己写了一段Bootloader通过在特定时间内检测串口数据来决定是否进入升级模式。如果上电后200ms内收到合法的升级命令帧就在串口接收固件并写入App分区如果没收到就正常跳转执行App。这样现场不需要控制BOOT0引脚只需要一根串口线就能完成升级。这样做的好处是对现场人员极其友好不需要知道什么是BOOT0只需要打开升级工具、选择文件、点一下“升级”就行。而且可以在Bootloader里加上CRC32校验和Flash分区保护避免断电导致的半成品固件。当然代价是Bootloader本身需要经过严格测试一旦Bootloader坏了芯片就变成了一块需要SWD恢复的“砖”。所以Bootloader的代码量尽量精简而且要加上看门狗机制防止异常情况下卡死在升级流程里。如果你只是在实验室里临时烧录一块H753ZI系统Bootloader足够用了。但如果你要做一个需要长期维护的产品我建议尽快迁移到自定义Bootloader的方案这会让你在固件升级这件事上掌握完全主动权。最后再分享一个小技巧在实际操作中我习惯在第一次连接时用9600波特率握手。因为H753ZI的Bootloader在低波特率下握手成功率更高握手成功后可以再用115200进行数据传输速度也能保证。这个技巧在长线、干扰大的环境下尤其有用。
返回列表