
1. 这个报错到底在闹什么脾气第一次看到Not a genuine ST Device这个弹窗的时候我正赶着给一块 STM32F103C8T6 最小系统板烧程序手边三块板子来回换结果 Keil 突然给我甩了这么一句。字面意思是“这不是一个正版 ST 设备”翻译成人话就是ST-Link 认出了你插上来的东西但它觉得这颗芯片的身份对不上号于是拒绝继续下载。这个报错在 STM32 开发圈里出现的频率相当高尤其是用国产兼容芯片、拆机芯片、或者从某宝淘来的低价核心板时。它跟你的代码写得对不对、编译有没有通过一点关系都没有纯粹是下载器与目标芯片之间的身份校验环节出了问题。换句话说程序编译得好好的卡在了“进门”这一步。我先把结论摆出来这个问题的根源通常落在两个地方。一个是ST-Link 固件版本太新对芯片的校验策略变严了另一个是目标芯片本身不是 ST 原厂出品或者芯片内部的调试接口被读保护、选项字节异常给锁住了。对应的解决思路也就两条主线要么把 ST-Link 的固件降回一个“宽容”的版本要么绕过 Keil 的校验逻辑用 ST-Link Utility 或者 STM32CubeProgrammer 这类工具直接烧。这篇文章我会把这两招拆开揉碎讲清楚包括每一步为什么这么做、参数怎么选、踩过哪些坑。另外标题里提到的“复位键烦人问题”我也会一并解决——很多人烧完程序发现板子必须手动按一下复位才能跑或者每次下载都要按复位这个其实是调试器复位模式配置的问题跟前面那个报错经常一起出现顺手就收拾了。适合谁看如果你正在用 Keil MDK 配合 ST-Link 给 STM32 下载程序被这个弹窗卡住过或者你手上有一堆来路不明的核心板、兼容芯片那这篇基本能覆盖你 90% 的场景。就算你是刚入门的新手跟着步骤走也能搞定因为我会把每个操作背后的逻辑讲明白而不是让你照抄。2. 先搞清楚 ST-Link 和芯片之间发生了什么2.1 身份校验这道关卡是怎么来的ST-Link 是 ST 官方的调试下载器它跟 STM32 芯片之间通过 SWD 或者 JTAG 协议通信。在正式下载之前ST-Link 会读取芯片的一个叫做DBGMCU_IDCODE的寄存器这个寄存器里存着芯片的制造商 ID 和器件 ID。ST 原厂芯片的制造商 ID 是固定的0x20器件 ID 也有一张官方对照表。早些年 ST-Link 的固件比较“单纯”读到 ID 就直接干活。后来 ST 在固件里加了一层校验如果读到的制造商 ID 不是0x20或者器件 ID 不在它的白名单里就直接报Not a genuine ST Device然后罢工。这个策略本身是为了防止山寨芯片冒充但副作用就是很多国产兼容芯片、翻新芯片、甚至某些批次的拆机原装芯片都被误伤了。我实测下来ST-Link 固件版本在V2.J28之后这个校验明显变严了。尤其是 V2.J37、V2.J38 这些版本对非原厂 ID 几乎是零容忍。所以第一招的核心思路就是把 ST-Link 固件降到一个校验宽松的版本比如 V2.J27 或者更早的 V2.J24。2.2 为什么降固件能解决问题这里要解释一个关键点ST-Link 固件是跑在下载器内部那颗单片机上的程序它决定了下载器的行为逻辑。降固件不是降 Keil 的版本也不是降芯片包而是改下载器自己的“大脑”。降回旧版本之后ST-Link 读到非0x20的制造商 ID 时不会立刻翻脸而是继续尝试通信这样就能把程序烧进去。但降固件有个前提你的 ST-Link 得是可升级固件的那种。市面上常见的 ST-Link V2 山寨版那种蓝色小U盘造型的大部分用的是 STM32F103C8T6 做主控固件是可以刷的。而 ST-Link V3 或者板载 ST-Link比如 Nucleo 板子上的情况不太一样降级要谨慎有些版本降不下去或者降了会变砖。注意降固件之前一定要确认你的下载器型号。如果是板载 ST-Link建议先查一下官方文档别贸然操作。独立的山寨 ST-Link V2 基本都可以放心降。2.3 第二招的逻辑绕过 Keil 直接烧如果不想动固件或者固件降不下去那就走第二条路不用 Keil 自带的下载功能改用 ST-Link Utility 或 STM32CubeProgrammer 直接烧录。这两个工具是 ST 官方出的独立烧录软件它们对芯片 ID 的校验策略跟 Keil 不一样很多时候 Keil 报错的芯片用这两个工具能正常识别和烧录。烧进去之后你再回到 Keil 里点调试或者下载有时候就能正常工作了因为芯片里已经有程序ST-Link 的握手过程会顺利很多。这个方法的本质是“先破冰再正常走流程”。2.4 复位键烦人问题的根源顺便说复位的问题。很多人烧完程序发现板子不自动运行必须手动按一下复位键或者每次下载都要按复位。这个通常是因为Keil 的 Debug 设置里Reset 模式选成了SYSRESETREQ或者VECTRESET而你的板子复位电路设计跟这个模式不匹配。STM32 的复位方式有好几种上电复位、手动复位、看门狗复位、软件复位。Keil 下载完成后默认会触发一次复位让程序跑起来但如果复位模式选得不对或者板子的 NRST 引脚被电容拉得太死复位信号就传不过去程序自然不跑。解决办法是在 Keil 的 Debug 配置里把 Reset 改成Autodetect或者HW RESET具体怎么选我后面会详细讲。3. 第一招给 ST-Link 固件降级3.1 准备工作确认下载器型号和当前固件动手之前先做两件事。第一确认你的 ST-Link 是不是独立下载器。插上电脑打开设备管理器看看有没有STMicroelectronics STLink dongle或者类似的设备。如果是板载的设备名可能不一样。第二查当前固件版本。打开 ST-Link Utility或者 STM32CubeProgrammer菜单里找ST-LINK-Firmware update它会显示当前固件版本号。记下这个版本比如V2.J37.S7。这个信息很重要因为你要降到的目标版本必须比它低。我整理了一张常见固件版本与校验严格程度的对照表方便你判断该降到哪个版本固件版本校验严格程度对非原厂芯片的兼容性建议V2.J24 及更早宽松好兼容性优先选这个V2.J27较宽松较好平衡选择V2.J28 - V2.J33中等一般部分芯片会报错V2.J34 - V2.J38严格差大概率报错V3.Jxx非常严格很差不建议用于兼容芯片3.2 降级工具的选择降 ST-Link 固件需要一个专门的工具ST 官方提供的是ST-LinkUpgrade.exe但这个工具通常只让你升级到最新版不让你降级。所以实际操作用得比较多的是一个叫ST-Link Firmware Upgrade的第三方小工具或者直接用 STM32CubeProgrammer 里的固件管理功能。我个人的习惯是用 STM32CubeProgrammer因为它同时能烧程序又能管固件一个软件搞定。打开之后进Firmware upgrade页面如果它检测到你的固件比它内置的版本新会提示你可以降级。但要注意CubeProgrammer 内置的固件版本也不一定是你想要的旧版本所以有时候还是得单独找旧版固件文件。旧版固件文件一般是.bin或者.hex格式配合升级工具使用。这些文件在网上能找到但来源要小心尽量从靠谱的社区或者官方归档里拿。我一般会保留几个常用旧版本在本地省得每次到处找。3.3 降级操作的具体步骤下面是我实际操作的流程以 STM32CubeProgrammer 为例插上 ST-Link确保设备管理器里识别正常。打开 STM32CubeProgrammer左侧选择Firmware upgrade。软件会自动读取当前固件版本显示在界面上。点击Refresh确认连接正常。如果软件内置了可降级的版本直接选目标版本点Upgrade。如果没有点Browse手动加载你下载好的旧版固件文件。等待进度条走完提示升级成功。拔插一次 ST-Link让新固件生效。整个过程大概一两分钟。降完之后回到 Keil重新点下载大概率那个报错就消失了。提示降级过程中千万不要拔掉 ST-Link否则可能变砖。如果真变砖了有些型号可以通过短接特定引脚进入 DFU 模式救回来但那是另一个话题了。3.4 降级后的验证和注意事项降完固件后我建议先用 ST-Link Utility 连一下目标芯片看看能不能正常读到 ID。如果能读到说明降级生效了。然后再回 Keil 下载。这里有个坑要提醒降级后不要手贱去点 Keil 里的固件升级提示。Keil 有时候会弹窗说“检测到 ST-Link 固件有新版本是否升级”你要是点了“是”又回到解放前了。所以降级之后遇到升级提示一律选“否”或者“忽略”。另外降级不是万能的。如果你的芯片制造商 ID 被改得面目全非或者芯片本身已经损坏降固件也救不了。这种情况下就得走第二招。4. 第二招绕过 Keil 用独立工具烧录4.1 ST-Link Utility 的安装与连接ST-Link Utility 是 ST 官方的一个老牌烧录工具界面简洁对芯片 ID 的校验比 Keil 宽松。安装包不大装完之后打开界面左上角有个插头图标点一下就能连接目标芯片。连接的时候要注意几点目标板要供电SWD 的四根线VCC、GND、SWCLK、SWDIO要接对尤其是 GND 一定要共地。我见过不少人因为没共地死活连不上还以为是芯片坏了。连接成功后软件底部状态栏会显示芯片的 ID 和容量信息。如果这里能正常显示说明 ST-Link 和芯片之间的物理连接没问题只是 Keil 的校验逻辑在作怪。4.2 用 ST-Link Utility 烧录的完整流程连接成功之后烧录流程是这样的菜单File-Open file选择你的.hex或者.bin文件。如果是.bin文件需要手动指定起始地址一般是0x08000000。菜单Target-Program Verify或者直接点工具栏的烧录按钮。等待烧录完成底部会显示Verification OK。烧完之后点Target-Run让程序跑起来。这套流程走下来基本能绕过Not a genuine ST Device的报错。烧进去之后你再回 Keil 点下载很多时候 Keil 也能正常识别了因为芯片里已经有合法的程序握手过程会顺畅很多。4.3 STM32CubeProgrammer 作为备选方案ST-Link Utility 虽然好用但 ST 官方已经逐渐用 STM32CubeProgrammer 替代它了。CubeProgrammer 功能更全支持更多芯片型号界面也更现代。如果你的芯片比较新ST-Link Utility 可能不认那就得用 CubeProgrammer。CubeProgrammer 的连接方式跟 Utility 类似选ST-LINK作为接口点Connect。连接成功后左侧会显示芯片信息。烧录的时候选Erasing Programming加载文件点Start Programming。CubeProgrammer 有个好处是它内置了选项字节Option Bytes的管理功能。如果你的芯片被读保护锁了或者选项字节被改乱了可以在这里直接恢复默认值。这个功能在救砖的时候特别有用。4.4 烧录后的 Keil 配置调整用独立工具烧完之后回到 Keil 还需要做一点配置调整否则可能还是下载不了。具体是在Options for Target-Debug-Settings里把Reset模式改一下。默认可能是SYSRESETREQ改成Autodetect或者HW RESET。改完之后点OK保存再试一次下载。如果还是报错那就检查Flash Download页面里的算法是不是选对了。STM32F103 系列一般选STM32F10x Med-density Flash或者对应的容量算法选错了也会导致下载失败。5. 复位键烦人问题的彻底解决5.1 为什么烧完程序必须手动按复位这个问题的本质是Keil 下载完成后触发的复位信号没有成功让芯片重新启动。STM32 的复位引脚 NRST 是低电平复位正常工作时是高电平。Keil 通过 ST-Link 发送复位命令ST-Link 拉低 NRST 一段时间再释放芯片就应该重启。但如果你的板子在 NRST 引脚上接了一个比较大的电容比如 100nF 甚至 1uF这个电容会让复位信号的上升沿变缓ST-Link 的复位脉冲可能不够宽芯片还没复位完信号就结束了。另一种情况是 Keil 的复位模式选成了VECTRESET这个模式只复位内核不复位外设有些板子就会表现得不正常。5.2 Keil 里复位模式的正确配置打开Options for Target-Debug-Settings在Debug标签页里找到Reset下拉框。这里有三个选项SYSRESETREQ软件复位通过内核的系统复位请求触发复位范围较广但依赖芯片支持。VECTRESET只复位内核向量表外设不复位一般不推荐。Autodetect自动检测Keil 会根据芯片型号选一个合适的模式。我实测下来大部分 STM32F1 和 F4 的板子选Autodetect或者SYSRESETREQ都能正常工作。如果选了还不行就试试HW RESET有些 Keil 版本里叫Hardware Reset这个是通过 ST-Link 直接拉 NRST 引脚最接近手动按复位键的效果。5.3 硬件层面的排查如果软件配置都对了还是得手动按复位那就得查硬件。重点看 NRST 引脚上的电容值。STM32 官方推荐的是 100nF但有些板子为了“稳定”会加大到 1uF 甚至 10uF这就过头了。电容太大复位信号上升太慢芯片可能识别不到。另一个要查的是 NRST 引脚有没有被其他电路拉低。比如有些板子把 NRST 接到了某个外设的复位输出上那个外设如果一直输出低电平芯片就一直在复位状态程序当然跑不起来。我遇到过一块板子NRST 上并了一个 10uF 的电容怎么配置都不行最后把电容换成 100nF问题立刻解决。所以硬件问题有时候比软件更隐蔽但一旦找到原因解决起来反而更彻底。5.4 下载后自动运行的额外技巧除了复位模式Keil 里还有一个选项叫Run to main()在Debug-Settings-Flash Download页面里。勾上这个选项下载完成后会自动运行到 main 函数。但有时候这个选项会导致程序在 main 之前就卡住所以如果勾了之后反而有问题就取消勾选试试。另外在Utilities-Settings里有一个Reset after Connect选项勾上它可以让 ST-Link 在连接芯片后自动复位一次。这个对某些板子也有帮助。6. 常见问题速查与避坑经验6.1 报错排查速查表现象可能原因解决方法Not a genuine ST DeviceST-Link 固件太新降级固件到 V2.J27 或更早Not a genuine ST Device芯片非原厂用 ST-Link Utility 绕过校验烧录连接超时SWD 线接错或没共地检查 VCC、GND、SWCLK、SWDIO能识别但下载失败Flash 算法选错在 Keil 里选对容量算法下载后不运行复位模式不对改成 Autodetect 或 HW RESET下载后不运行NRST 电容太大换成 100nF芯片被读保护选项字节被锁用 CubeProgrammer 解除读保护Keil 提示固件升级降级后被检测到一律选“否”不要升级6.2 我踩过的几个坑第一个坑是降级后忘了关 Keil 的自动升级。有一次降完固件下载正常了结果第二天打开 Keil弹窗提示固件升级我手快点了“是”然后那个报错又回来了。后来我养成了习惯降级之后第一件事就是去 Keil 设置里把固件升级提示关掉。第二个坑是用错了 Flash 算法。STM32F103C8T6 是 64KB Flash属于中等容量算法要选STM32F10x Med-density Flash。我有一次选成了High-density结果下载一直失败查了半天才发现是算法选错了。这个错误不会报Not a genuine ST Device但会报别的下载错误容易混淆。第三个坑是ST-Link 的 SWD 线太长。我用杜邦线接了 20 厘米长的 SWD 线结果通信不稳定时好时坏。后来换成 10 厘米以内的短线问题就没了。SWD 是高速信号线太长容易受干扰尤其是旁边有电机或者电源线的时候。第四个坑是芯片被读保护了还不知道。有一块二手板子怎么都连不上后来用 CubeProgrammer 一看读保护等级是 Level 1调试接口被禁用了。解除读保护之后才能正常下载。这个情况在拆机芯片上很常见买二手板子要有心理准备。6.3 几个实用的经验技巧技巧一先连后烧。不管用哪个工具先点连接确认能读到芯片 ID再烧录。如果连都连不上烧录肯定失败先解决连接问题。技巧二保留一个“万能”旧固件。我本地常备一个 V2.J24 的固件文件遇到兼容性问题就刷这个版本基本百试百灵。技巧三用 CubeProgrammer 做芯片体检。拿到一块来路不明的板子先用 CubeProgrammer 连一下看看能不能读到 ID、读保护等级是多少、选项字节是否正常。这比直接上 Keil 烧录更稳妥。技巧四复位问题优先查硬件。如果软件配置都试过了还是得手动复位别犹豫直接查 NRST 引脚的电容和电路。十有八九是硬件问题。技巧五别迷信最新固件。ST-Link 固件不是越新越好对于兼容芯片来说旧固件反而更友好。除非你需要新固件支持的某些新功能否则没必要追新。7. 关于芯片选型和长期使用的建议7.1 兼容芯片的取舍国产兼容 STM32 的芯片现在很多价格便宜引脚兼容但调试下载环节确实容易出问题。如果你只是做实验、跑个灯、学个外设兼容芯片完全够用配合上面两招基本能搞定。但如果是做产品、要量产我建议还是用原厂芯片省去很多调试上的麻烦。原厂芯片的制造商 ID 是0x20ST-Link 读到就直接放行不会有任何校验问题。而且原厂芯片的选项字节、读保护机制都更规范不容易出现莫名其妙的锁死。7.2 开发环境的版本管理Keil MDK 的版本、芯片包的版本、ST-Link 固件的版本这三者之间的兼容性也会影响下载。我个人的经验是Keil 用稳定版芯片包用官方最新ST-Link 固件用旧版。这个组合在兼容性和稳定性之间平衡得比较好。Keil MDK 5.36 是很多人推荐的一个版本对 STM32 的支持比较完善同时不会强制升级 ST-Link 固件。如果你还在用更老的版本比如 5.20 之前的可能会遇到芯片包不兼容的问题建议至少升到 5.30 以上。7.3 备份和恢复策略对于经常折腾 STM32 的人来说有一套备份和恢复策略很重要。我一般会做这几件事备份 ST-Link 的旧版固件文件放在一个固定的文件夹里。备份常用的 Flash 算法配置文件换电脑的时候直接拷过去。记录每块板子的芯片型号、Flash 容量、读保护状态方便排查问题。对于重要的板子烧录前先用 CubeProgrammer 读一次选项字节存个档。这些习惯看起来麻烦但真出问题的时候能省下大量时间。我有一次因为没备份固件降级后想恢复原版找了好几个地方才找到合适的文件从那以后就养成了备份的习惯。7.4 关于 ST-Link V3 的补充说明ST-Link V3 是 ST 官方的新一代下载器速度快支持更多协议但对非原厂芯片的校验也更严格。如果你手上有 V3遇到Not a genuine ST Device的概率会更高而且 V3 的固件降级比 V2 麻烦得多有些版本根本降不下去。我的建议是如果主要玩兼容芯片就备一个便宜的 ST-Link V2 山寨版专门用来烧兼容芯片V3 留着烧原厂芯片。两个下载器分工明确省得来回折腾。8. 最后再聊几句实操心得这套东西我前前后后折腾了好几年从最开始看到报错一脸懵到后来能快速定位问题中间踩的坑不计其数。现在回头看Not a genuine ST Device这个报错其实不算难搞核心就是理解 ST-Link 的校验逻辑然后选择降固件或者绕道烧录。复位键的问题也是同理理解了 STM32 的复位机制和 Keil 的复位模式配置解决起来就是改一个下拉框的事。但如果你不知道背后的原理就会一直在那儿按复位键按到怀疑人生。我个人的习惯是拿到一块新板子先用 CubeProgrammer 连一下确认芯片能识别、读保护正常、选项字节没问题然后再进 Keil 开发。这个前置检查能排除掉大部分下载环节的坑。另外ST-Link 固件我固定用 V2.J27这个版本在我手上十几块不同批次的板子上都表现稳定兼容性和功能性平衡得最好。如果你手上的板子比较多建议给每块板子贴个标签写上芯片型号和下载注意事项。比如“F103C8T6兼容片需降固件”或者“F407VET6原厂直连即可”。这样下次用的时候不用重新试错直接按标签操作就行。这套方法不仅适用于 STM32F1 和 F4对 F0、F7、H7 系列也基本通用只是 Flash 算法和选项字节的细节略有不同。核心思路是一样的先解决连接和校验问题再解决复位和运行问题。把这两个环节打通剩下的就是专心写代码了。