STM32F103+FreeRTOS芯片没反应?先验芯片真假再改代码
最近后台收到几条几乎一模一样的求助STM32F103 FreeRTOS 的板子程序能下载进去LED 就是不亮SWD 也能连上但你点“全速运行”芯片就像死了一样没有任何反应。这种问题最折磨人因为你说它没烧录吧下载回报是成功的你说代码有问题吧同样的工程换个板子又能跑。等我把板子翻来覆去查了一圈最后拿到放大镜下一看丝印好家伙这根本就不是一颗正常渠道的 STM32F103。这篇文章就把我排查这类“芯片没反应”问题的完整思路写出来重点讲三件事怎么按顺序排查硬件和软件、怎么用代码识别假芯片以及 FreeRTOS 移植过程中哪些坑看起来像硬件问题、实际是配置问题。如果你正被 STM32F103 FreeRTOS 整得焦头烂额或者刚买了一堆散片准备做产品这篇应该能帮你省下几个通宵。1. 项目概述与问题场景还原1.1 这个组合到底有多常见STM32F103 配 FreeRTOS 几乎是国内嵌入式入门和中小项目的主力配置。F103 价格便宜、外设齐全、资料满天飞FreeRTOS 源码开源、体积小、生态成熟两者加起来能覆盖点灯、串口通信、Modbus RTU 从站、传感器采集、电机控制这些常见场景。我自己接手过的项目里工业网关采集、车载诊断盒、单片机教学板十块有八块是这套组合。正因为用的人多问题也特别集中。绝大多数“芯片没反应”的提问最后查下来无非是三类最小系统硬件没搭对、FreeRTOS 配置踩了低级坑、芯片本身来路不正。前两类是技术问题花时间能查第三类是供应链问题再努力查代码也是白费劲必须学会识别和规避。1.2 “没反应”的几种真实形态先别急着拆芯片你要先明确“没反应”到底属于哪种情况。我遇到过太多人一上来就说“芯片死了”结果连现象都没描述清楚。根据经验STM32F103 的“没反应”通常有三种形态。第一种是彻底没反应上电整板没有任何电流变化LED 不亮SWD 扫描不到内核调试器报 No target connected这种通常是供电、焊接、BOOT 配置或者芯片本身损坏。第二种是能连上但程序不跑SWD 能识别内核程序也能下载但每次下载完不会自动运行手动复位后依然没有任何输出。这种情况要和第一种区分开因为芯片内部逻辑基本是好的问题往往出在复位电路、BOOT 引脚、Flash 内容或者启动文件。第三种最迷惑裸机点灯能亮串口能打印但只要一上 FreeRTOS任务调度器一启动就 HardFault或者任务切换两三次后系统卡死。很多人会怀疑是芯片内部 Flash 有问题或者干脆怀疑是 FreeRTOS 移植出了问题。实际上这两种怀疑都有道理你得有手段把它俩分开。1.3 为什么会怀疑到“假芯片”头上说句难听的在 STM32F103 这个型号上怀疑假芯片不是被害妄想。这芯片出货量太大翻新片、打磨片、Remark 芯片在市场上多到能自成一个产业链。所谓 Remark就是把低配型号或旧芯片表面打磨掉重新印上高配型号的字样所谓翻新片就是从旧板子上拆下来清洗、重新打标再当新片卖。这不是我危言耸听。有一次我为了一个小批量项目采购了 100 片“STM32F103RCT6”到货后随手抽了五片读内部 ID结果发现两片的 ID 和 Flash 容量对不上丝印。从那以后我再也不信散片每次新到芯片第一件事就是验货。这不是说所有散片都是假的但你得默认它们可能是假的才能在出问题时快速定位。2. 芯片没反应先按这条路径排查2.1 最小系统电路自查清单先把硬件挨个过一遍。不要嫌基础很多时候问题就藏在你觉得“肯定没问题”的细节里。供电是第一关。STM32F103 的 VDD 要稳定的 3.3VVDDA 也要接 3.3V而且要加去耦电容。我见过有人只接了 VDD 没接 VDDA芯片也能下载程序但跑起来就是各种随机死机。另外测量电压要在芯片引脚上量不要量在稳压芯片输出端因为板上走线细、接触不良都会导致负载时电压跌到 2.8V 以下这时候芯片可以连 SWD但内部 Flash 读取已经不稳定了。然后是 BOOT0 和 BOOT1。BOOT0 必须通过电阻拉低到 GNDBOOT1 也是。如果 BOOT0 是悬空的芯片上电后可能进入系统存储器启动模式程序根本不会从 Flash 运行表现就是“程序烧录了但没有执行”。这里有个常见误区有些人 BOOT0 接了下拉电阻但下拉电阻用了 100K板子潮湿或者引脚漏电时电平一样会被拉高我用 10K 以下更稳。再查复位脚 NRST。正常工作时 NRST 应该是高电平。如果复位电路里的电容过大比如 1uF会导致上电复位时间太长看起来像没反应如果复位脚被外部干扰拉低芯片会反复复位。最稳妥的做法是先用万用表确认 NRST 在 3.3V然后用手碰一下复位按钮用示波器观察复位波形。晶振也值得专门说。F103 可以不接外部晶振用内部 HSI 跑但很多工程的标准库启动代码 SystemInit 会等待 HSE 就绪如果你的板上没焊外部晶振或者晶振虚焊代码会卡死在启动阶段——注意卡死不代表芯片没反应SWD 照样能连上但程序永远进不了 main。这就是最容易被误判成“假芯片”的场景之一。最后是 SWD 下载接口。很多最小系统板把 SWDIO 和 SWCLK 引出来但如果你把 PA13、PA14 复用成普通 GPIO或者板上有其他外设把这俩引脚拉死SWD 就会连接失败。这个不属于芯片本身问题但排查时容易白费功夫。2.2 软件工程与下载配置自查硬件查完没事再看工程配置。很多人忽略了一个点Keil 里选的芯片型号和实际芯片型号不一致。比如你买了 STM32F103C8T6但工程里选的是 STM32F103RCT6Flash 容量算法、启动文件都不对烧录进去可能能跑但跑到某个地方就崩了尤其容易在进入 RTOS 调度器后崩。启动文件也是重灾区。STM32F103 根据容量不同启动文件分为 low density、medium density、high density 等版本。如果你的芯片是 C8T6中容量却用了 HD 版本的启动文件向量表偏移不对中断一进来就跑飞。反过来RCT6高密度用了 MD 版本启动文件SRAM 和 Flash 的初始化配置不对程序也可能起不来。所以在看芯片之前先确保 Keil Target 里的 Device 型号、C/C 宏定义里的 STM32F10X_MD 还是 HD、启动文件三者一致。下载配置也要看一眼。Keil 的 Settings 页面里有一个 “Reset and Run” 选项如果没勾选下载完成后程序不会自动复位运行你需要手动按一下复位键。这个也能造成“芯片没反应”的假象。另外如果芯片被设置了读保护RDPSWD 连接后你会发现下载速度很慢甚至无法擦除程序烧进去后也可能无法从 Flash 启动表现和没烧录一样。2.3 什么时候才轮到怀疑芯片如果以上这些全都查过了供电稳、BOOT 对、复位正常、晶振起振、SWD 能连、启动文件没错、下载配置正确但芯片还是没反应这时候才把怀疑的目光转向芯片本身。需要补充的信号包括芯片一上电就发烫、同一批芯片部分能跑部分不能跑、把工作频率降到 36M 就稳定但 72M 就死机、串口输出乱码且波特率误差很大、Flash 写入后校验经常失败。我自己的排查顺序固定是硬件最小系统 → 裸机点灯程序 → 串口打印 → FreeRTOS 最小任务 → 全功能。任何一步不过就先用这一层的最简代码去定位而不是直接上完整工程。这样分层的最大好处是你能快速判断问题出在“芯片本身”还是“上层代码”。3. 假芯片的识别与验证别光靠目测3.1 第一关外观丝印与封装判断肉眼判断假芯片不是不行但需要经验和放大镜。原厂 ST 芯片的丝印是激光打标字体均匀、笔画边缘清晰、深浅一致用手摸上去有轻微的凸起感。二次打标通常是先打磨掉原丝印再重新印字字体往往偏粗、发白笔画边缘有熔融的烧灼痕迹或者丝印周围有细微的凹坑。如果你在芯片表面看到一块颜色略深、反光度不同的区域那基本就是打磨过的。封装侧面也要看。翻新片从旧板上拆下来后引脚上会有焊锡残留哪怕清洗过引脚根部也容易有残留的锡珠或腐蚀痕迹。另外原厂引脚镀层颜色均匀、有光泽翻新片引脚可能发暗、粗细不均。还有一个细节芯片表面的定位点圆点和丝印方向是否一致Remark 时如果重新定位了方向偶尔会搞错。不过外观只能作为第一道筛子不能一锤定音。有的翻新片做工很好肉眼根本看不出来所以必须靠后面的代码验证。3.2 第二关代码验货上电就读寄存器代码验证才是实锤。STM32F103 内部有几个寄存器可以直接读出芯片的身份信息不需要任何外部设备一根 SWD 线加一个调试器就能搞定。第一个是 DBGMCU 的 IDCODE 寄存器地址是 0xE0042000。低 12 位是 Device IDSTM32F103 中密度比如 C8T6、RBT6的值是 0x410高密度比如 RCT6、ZET6的值是 0x414。如果你买的是 F103RCT6读出来却是 0x410那就直接实锤了——这颗其实是中密度芯片打磨后冒充的高密度。第二个是 Flash 容量寄存器地址是 0x1FFFF7E0。这个寄存器以 K 字节为单位读出 0x40 就是 64KB0x80 是 128KB0x100 是 256KB0x200 是 512KB。对照丝印型号C8T6 应该是 64KBCBT6 是 128KBRCT6 是 256KBZET6 是 512KB。如果丝印写的是 RCT6读出来只有 0x40假得不能再假了。我再贴一段简单的验证代码通过串口打印出来#include stm32f10x.h #include usart.h int main(void) { uint16_t flash_kb; uint32_t idcode; uint16_t dev_id; NVIC_PriorityGroup_Config(NVIC_PriorityGroup_4); USART1_Init(115200); flash_kb *(__IO uint16_t *)0x1FFFF7E0; idcode *(__IO uint32_t *)0xE0042000; dev_id idcode 0xFFF; printf(Flash : %d KB\r\n, flash_kb); printf(DevID : 0x%03X\r\n, dev_id); while (1); }运行后如果打印出 “Flash: 64 KB, DevID: 0x410”但你买的是 RCT6那不用再犹豫了。还有个更隐蔽的情况有些打磨片用 STM32F103CBT6128KB冒充 RCT6读 Flash 容量会返回 0x80DevID 还是 0x410。这也对不上因为真正的 RCT6 是高密度DevID 应该是 0x414。所以两个寄存器要结合着看。顺手还能读一下 96 位唯一 ID地址在 0x1FFFF7E8。同一批正规芯片的 UID 应该是连续的、互不相同的。如果你发现手里多颗打磨片 UID 一模一样那必然是同一条造假线下来的。3.3 第三关电学、ISP 与 Flash 读写验证代码读 ID 基本能锁定大部分假芯片但有些更狡猾的会把高密度芯片的内核重新打标成另一颗高密度型号这时候 ID 和容量可能都对得上靠寄存器就不灵了。该怎么办第一个方法是测温升和电流。一颗正常的 F103 跑空循环整板电流也就十几毫安到几十毫安芯片外壳只是微温。如果上电没跑什么外设芯片就明显发烫电流异常大多半是晶圆有伤或者内部短路。翻新片因为经历过拆焊、高温封装内部可能有微小裂纹发热问题比全新片常见得多。第二个方法是走串口 ISP。STM32F103 出厂自带 Bootloader把 BOOT0 拉高、BOOT1 拉低上电后通过 USART1 和 PC 通信用原厂的 Flash Loader Demonstrator 或者第三方工具连一下能读到 Bootloader 版本和芯片信息。注意原厂 Bootloader 是出厂固化在系统存储器里的如果一颗芯片连 ISP 命令都不响应或者返回的版本信息明显异常说明它极可能不是原厂流片。第三个方法是做 Flash 读写循环测试。写一段测试代码向芯片末尾的几个扇区反复写入不同模式的数据再读回来比对。翻新片的 Flash 经历过多次擦写电荷保持能力变差写入后读回不一致的概率会明显升高。如果你在测试中发现“写入成功但读出来是 0xFF”或者“写入几十次后开始出错”那这颗芯片的 Flash 寿命已经岌岌可危了。这里顺便提一嘴“掉电保存数据”的排查思路很多人用 STM32F103 内部 Flash 保存运行参数如果保存的地址恰好超过了这片芯片实际容量写入时会失败读回来全是 0xFF。表面上看是代码没写对实际是芯片容量被虚标了。这也是假芯片最坑的地方之一。3.4 我的建议翻新片到底能不能用明确表态你可以用翻新片做学习、验证、跑原型但量产项目我强烈不建议用。我自己吃过亏翻新片最大的问题不是“坏”而是“不稳定”。引脚氧化会导致焊接不良率飙升Flash 寿命不可控会让量产设备用着用着参数丢失HSI 内部振荡器精度漂移会让串口波特率跑歪FreeRTOS 靠 SysTick 做时基如果时钟源不稳定任务调度跑着跑着就乱了。你花在排查这些晦涩问题上的时间远远超过省下的芯片采购成本。4. FreeRTOS 的锅还是芯片的锅四个高频坑4.1 中断优先级分组调度器一跑就崩和假芯片同样常见的问题是 FreeRTOS 移植时踩了中断优先级分组相关的坑。F103 用的 Cortex-M3 内核NVIC 优先级分为抢占优先级和子优先级两部分优先级分组是可配置的。FreeRTOS 在 Cortex-M3 上使用 BASEPRI 寄存器实现临界区保护它要求中断优先级分组必须设置为全部 4 位都用作抢占优先级也就是 NVIC_PriorityGroup_4。如果不这样设置临界区保护就会失效或者过度屏蔽最常见的现象是vTaskStartScheduler() 一启动就进入 HardFault或者任务切换几次后系统卡死。你在裸机上可能一切正常因为裸机程序一般不依赖 BASEPRI 屏蔽逻辑但一上 RTOS 就暴露了。解决办法是在 main 函数最开始进入任何 FreeRTOS API 之前调用NVIC_PriorityGroup_Config(NVIC_PriorityGroup_4);同时检查 FreeRTOSConfig.h 里的几个宏configPRIO_BITS 要等于 4configLIBRARY_LOWEST_INTERRUPT_PRIORITY 通常是 15configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 通常是 5。这三个值要和分组设置配套不然你用中断信号量、消息队列的时候现象会非常随机。4.2 SysTick 与启动文件tick 根本就没走FreeRTOS 的时基默认依赖 SysTick 中断正常情况下 SysTick_Handler 里要调用 xPortSysTickHandler()。如果你在工程里自己又写了一个 SysTick_Handler 函数覆盖了 FreeRTOS 的版本那滴答中断就永远不递增任务永远不会切换。表现就是第一个任务执行完就再也没反应了LED 亮一下就不动串口打印一行就停住。启动文件选错也是同样的现象。如果你用了和你芯片不匹配的 startup 文件向量表里的中断服务函数指针可能错位SysTick 中断根本无法到达正确的处理函数。我在用 Keil 6 编译器AC6重新编译老工程时就踩过这个坑AC6 和新版启动文件配合没问题但如果你把 AC5 工程直接切到 AC6又没有更新启动文件里的指令对齐方式中断向量表可能整个错乱。所以排查时先明确tick 到底走没走。最简单的方法是加一个全局计数的调试变量放在 SysTick_Handler 里累积如果调度器跑起来了它却不变问题就在中断向量。4.3 堆栈配置越界了还不自知FreeRTOS 里创建任务时给的是任务栈大小单位是 word 而不是 byte。configMINIMAL_STACK_SIZE 默认是 128实际就是 512 字节。很多人任务里放了一个大数组或者在中断服务函数里做耗时操作栈直接溢出。溢出后不会立刻报错而是悄悄改写相邻内存等到某个时刻才突然 HardFault。更麻烦的是假芯片的内核 SRAM 如果实际容量小于标称你在任务里申请的总栈空间超出了物理 SRAM调度器启动时会遍历任务列表把任务控制块放到无效内存上表现就是“裸机正常加一个任务就死”。遇到这种情况开启 FreeRTOS 的堆栈溢出检测很有必要。把 FreeRTOSConfig.h 里的 configCHECK_FOR_STACK_OVERFLOW 设为 2并实现 vApplicationStackOverflowHook 钩子函数void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { // 停在这里查看 pcTaskName 和调用栈 while (1); }一旦任务栈溢出程序会自动跳进这个钩子。排查时在钩子函数里打个断点就能立刻确认是不是栈不够用。我见过不少人把“芯片没反应”的锅扣在硬件上最后发现只是任务栈开小了。4.4 HSE 与 PA8 时钟看着像硬件问题实际是时钟问题F103 的很多工程默认使用外部高速晶振 HSE标准库启动代码里的 SystemInit 会等待 HSE 稳定。如果你的板子上晶振没焊、虚焊、或者负载电容不匹配系统会卡在启动阶段表现就是“程序下载了但不运行”。这不是芯片坏了是时钟源没起来。检查方法是先确认板上 HSE 两脚之间有没有 8MHz 正弦波没有的话再用内部 HSI 把系统跑起来看问题是否消失。PA8 这个引脚在 F103 上默认复用为 MCO也就是主时钟输出脚可以输出 SYSCLK、HSE、PLL 二分频等时钟信号。很多最小系统板把 PA8 引出来给外部设备做时钟这本身没问题。但如果你把这个引脚配置成普通 GPIO 推挽输出又把外部时钟线拉得特别长或者负载过大MCO 输出可能被拉偏导致下游设备异常。还有一种情况是初学者看到 PA8 有“引时钟”的功能就以为必须它输出时钟芯片才能跑其实 F103 内部时钟链路和 PA8 的 MCO 输出是两回事——MCO 只负责“观测”不负责给芯片自己供时钟。如果你把 PA8 当普通 IO 用了芯片正常跑但外部从设备没反应这通常不是芯片的问题而是时钟输出的电气特性没处理好。4.5 假芯片在 FreeRTOS 下的特殊表现假芯片遇到 FreeRTOS会有一些特别典型的“症状组合”裸机点灯正常但一旦创建两个以上任务调度器跑一段时间就随机死机使用信号量或消息队列时任务永远等不到数据开启中断优先级分组后临界区依然失效。这些现象单独看像代码 bug但当你把同一份代码放到正规渠道芯片上马上正常时就要回到芯片本身找原因。我实测过的翻新片里有一种特别恶心的情况芯片运行在 72MHz 时Flash 读取不稳定程序偶尔跑飞降到 36MHz 就稳定得多。这是因为 Flash 内部的读出电路老化无法满足高速下的时序要求。FreeRTOS 任务切换比裸机主循环频繁得多每次切换都要从 Flash 读取向量表和任务栈内容所以假芯片的 Flash 不稳定问题在 RTOS 环境下会被放大。你可以做个对照实验把系统主频从 72M 降到 36M如果“没反应”的现象消失了这颗芯片的 Flash 高速特性大概率不合格。另外FreeRTOS 的优先级反转问题也容易被误判成芯片问题。高优先级任务等了很久的信号量一直被低优先级任务占着系统看起来像卡死。这个用优先级继承互斥量可以解决但注意如果你加了互斥量还是一样卡那就别只盯着软件了把芯片来源一并查一查。5. 实战复盘一块“死板”是这么查出假芯片的5.1 第一轮排查硬件逐个测今年年初我帮一个朋友看一块板子STM32F103RCT6 FreeRTOS三个 LED 任务任务是让三盏灯按不同频率闪烁。他描述的现象是程序烧录成功上电后只有一颗 LED 发出微弱的光然后熄灭之后怎么按复位都没反应J-Link 能连上。我拿到板子先不碰代码按最小系统的顺序过了一遍3.3V 供电正常VDDA 也有 3.3VBOOT0 是低电平NRST 高电平外部 8MHz 晶振两脚都有波形幅值正常。我又用 J-Link 连接内核读取 CPU ID 是 0x410——注意丝印明明写的是 RCT6这个 ID 已经不对了但我当时还没下结论因为 0x410 也有可能是我读取方式的问题。5.2 第二轮FreeRTOS 的怀疑硬件基本正常我开始怀疑 FreeRTOS 移植。先检查 FreeRTOSConfig.h发现 configMINIMAL_STACK_SIZE 是 128configTOTAL_HEAP_SIZE 是 8K看起来没问题再检查启动文件工程用的是 startup_stm32f10x_hd.s芯片型号选的是 STM32F103RCT6也没问题中断优先级分组在 main 开头已经设成了 Group 4。我用调试器全速运行然后在 HardFault_Handler 里打断点程序果然停进来了。查看调用栈定位到 vPortStartFirstTask再往上翻是 prvStartFirstTask。这个位置出问题通常就是中断优先级或者内存对齐的问题。我反复改了 FreeRTOSConfig.h 里的优先级宏问题依旧。5.3 第三轮验芯片实锤到这一步我才真正开始验货。先读 Flash 容量寄存器0x1FFFF7E0 返回 0x40也就是 64KB。再看丝印明明白白写着 STM32F103RCT6原厂 RCT6 应该是 256KB。DevID 0x410 对应中容量Flash 64KB 也是中容量这颗芯片其实就是一颗 STM32F103C8T6 级别的裸片被人打磨后重新打标成了 RCT6。为什么 FreeRTOS 跑不起来而裸机能跑因为这颗片子的 Flash 老化严重内部读出时序已经不稳定。我在裸机点灯时程序只用了一个 GPIO 翻转主循环Flash 访问集中在前几条指令勉强能撑住On FreeRTOS要频繁加载任务控制块、栈指针、中断向量Flash 动不动就被再次访问读出来偶尔是错误数据程序自然跑飞。我又把主频降到 36M 试了一下三盏灯居然能正常闪了但闪几下又开始乱——这更加印证了 Flash 高速读取特性不行。最后我把这颗芯片放在显微镜下看表面确定有打磨痕迹丝印边缘发虚不是原厂激光打标的锐利边沿。朋友联系卖家后卖家也没多扯直接退款了。问题不在于芯片用不了而在于你花 RCT6 的钱买回来一颗不知道哪里拆下来的旧片子还以为是新片。5.4 替换后结果与经验教训换了一批正规渠道的 STM32F103RCT6 之后同一套工程代码原封不动烧进去三盏灯按预期闪烁串口打印正常FreeRTOS 任务切换毫无问题。这说明之前的板子硬件设计并没有大问题唯一的问题就是芯片。这次排查的教训很清楚遇到“裸机正常、FreeRTOS 不正常”不要急着改代码也不要急着骂自己先用裸机程序验证芯片基本执行能力再用读 ID 和 Flash 容量的工具脚本验货。如果你连芯片真伪都没确认改再多配置也是白费。6. 常见问题速查与避坑技巧6.1 芯片没反应速查表我把实际工作中遇到过的“没反应”现象、根因和处理方法整理成一个速查表方便各位对照排查。现象可能原因处理方向SWD 连不上整板无电流电源没接好、芯片虚焊、芯片损坏重新焊接检查 VDD/VDDA/GND 是否导通SWD 能连程序下载成功但上电不运行BOOT0 拉高、Reset and Run 未勾选、Flash 内容为空拉低 BOOT0勾选自动复位运行重新烧录程序下载后必须手动复位才能运行Keil 的 Reset and Run 选项没开在 Flash Download 页面勾选 Reset and Run上电后芯片发热严重翻新片内部短路、晶圆损伤测电流如果异常直接换芯片裸机点灯正常FreeRTOS 一跑就 HardFault中断优先级分组错误、任务栈溢出、启动文件不匹配设置 Group4开启栈溢出检测核对启动文件同一程序换板子有时好有时坏芯片为打磨片、Flash 老化读 ID 和 Flash 容量换正规渠道芯片程序偶尔随机死机堆栈溢出、Flash 读取不稳定、电源纹波过大开启溢出检测降低主频测试检查电源纹波CAN 偶发通信失败SJW 同步跳转宽度太小、晶振精度不足调整 SJW 到 1~4 个时间量子检查位时序定时器 PWM 占空比到不了 100%比较值设置等于 ARR 导致输出翻转让 CCRARR1或检查 CCxP 极性配置其中 CAN 的 SJW 问题我想多说一句。SJW 是 CAN 控制器在重同步时最多能跳变的位时间量子数范围是 1 到 4。如果两个节点的时钟偏差比较大SJW 太小时总线上的信号同步跟不上会出现偶发性通信失败。这和芯片没反应无关但很多人在排查“STM32F103 FreeRTOS CAN 通信间断”时会误以为是 RTOS 调度影响了 CAN其实改大 SJW 就能解决。6.2 FreeRTOS 异常速查表FreeRTOS 相关的排查点我单列一张表很多问题和芯片本身无关但表现接近“芯片没反应”。现象可能原因处理方向创建任务返回 NULL堆总大小不足、任务栈分配失败调大 configTOTAL_HEAP_SIZE检查任务栈深度单位是 word调度器启动后只有第一个任务执行SysTick_Handler 被覆盖、启动文件不匹配确认 SysTick_Handler 调用 xPortSysTickHandler信号量等不到、任务卡死优先级反转、中断优先级配置错误使用互斥量检查 MAX_SYSCALL_INTERRUPT_PRIORITY使用队列或信号量后随机 HardFaultBASEPRI 临界区失效、优先级分组不是 Group4设置 NVIC_PriorityGroup_4并核对宏定义程序跑一段时间后无规律死机任务栈溢出、翻新片 Flash 不稳定开 StackOverflowHook降频对照测试串口打印乱码HSE_VALUE 与实际晶振不符、HSI 精度漂移修改 HSE_VALUE 为实际晶振频率检查波特率误差6.3 我买芯片的几条铁律既然这篇文章的核心是“假芯片”最后再分享一下我现在买 STM32F103 的几条规矩都是踩坑踩出来的。第一条不贪便宜。同型号价格明显低于主流渠道报价的直接不买。STM32F103 的价格波动我见多了遇到低得离谱的先想想这里面有多少是翻新片的概率。第二条收货先验货。我手里常备一个最小系统板加一根 ST-Link芯片一到货就抽几片上电读 UID、读 Flash 容量、擦写末尾扇区各一两次。整个流程十分钟不到。如果你买的是批量料最好每批次都抽验不要一颗验完就默认整批没问题。第三条保留溯源。能走目录分销商或者授权代理就走正规渠道订单、批次信息都留好。如果只能在淘宝买散片也要选开店时间长、评价里有人专门做芯片验货的店。万一真出了问题你至少能退货退款而不是自己打碎牙往肚里咽。写在最后我现在拿到任何一块新板子第一件事永远不是跑完整工程而是用一个裸机 GPIO 翻转程序点亮 LED再打印芯片 ID 和 Flash 容量到串口。先证明芯片活着、是真货再往上加 FreeRTOS、加业务逻辑。这套流程帮我筛掉过好几批翻新片也帮我省下了大量排查时间。你也不用怕麻烦这些检查动作写成一个独立的验证工具以后每批料都跑一遍心里踏实多了。如果你现在正被“芯片没反应”折磨建议按文章顺序走一遍先查最小系统再用裸机验证再读 ID最后才是改 FreeRTOS 配置。很多时候问题比你想象的简单——要么是一颗芯片真的走了歪路要么是一个宏定义悄悄坑了你。