一、问题再现
一天下午,我在开开心心地写代码,结果在学习OLED显示模块时,不知写入了什么魔法代码,导致调试接口无法正常工作。
然后我试着烧录了简单的点灯代码,无法烧录。
报错信息:
DEPRECATED! use 'tcl port' not 'tcl_port'
DEPRECATED! use 'gdb port', not 'gdb_port'
DEPRECATED! use 'tcl port' not 'tcl_port'
Info : clock speed 1000 kHz
Info : STLINK V2J37S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.134536
Error: init mode failed (unable to connect to the target)
in procedure 'program'
** OpenOCD init failed **
shutdown command invoked
接着我更换了一块stm32f103开发板,能够正常烧录点灯代码,于是我便对老开发板的离去表示惋惜。
令人意想不到的是,第二天,我在用新板子烧录同样的代码时,发生了第一天的问题:新板子也烧录不了任何程序!
此时我想到,唉?那就不是硬件的问题了,我的老板子有救了!!于是开始全网搜集信息抢救老板子。
二、问题解决
既然STM32的调试接口SWD被锁死,那么就要寻找解锁的方法。
1.准备工作
硬件:stm32f103c8t6开发板(江协科技买的)、跳线帽(一般自带在板子上)、杜邦线
软件工具:STM32CubeProgrammer
2.BOOT启动模式设置
参考:STM32三种BOOT启动模式详解(全网最全)_stm32boot-CSDN博客

第一种方式:主闪存存储器模式,平时使用STLINK下载程序时用的就是这种
重点来咯
第二种方式:系统存储器模式
原文链接:https://blog.csdn.net/qq_39400113/article/details/116051401
“我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader 中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中”
“开发调试过程中,由于某种原因导致内部Flash锁死,无法连接SWD以及JTAG调试,无法读到设备,可以通过修改BOOT模式重新刷写代码。修改为BOOT0=1,BOOT1=0即可从系统存储器启动,ST出厂时自带Bootloader程序,SWD以及JTAG调试接口都是专用的。重新烧写程序后,可将BOOT模式重新更换到BOOT0=0,BOOT1=X即可正常使用。”
你看懂了吗,我是如懂,总的来说就是要切换到第二种方式启动,那么怎么做呢?
咱们来看一下开发板

以前我没搞懂那个黄黄的东西是啥,现在才明白是跳线帽。上图是初始的情况BOOT0=BOOT1=0,
如下图所示,将BOOT0的跳线帽接在右边,则BOOT0 = 1,BOOT1 = 0
按紧

那么现在STM32被设置为了系统存储器模式,就可以愉快的把之前导致SWD锁死的代码删掉了
3. 复位芯片
按下开发板上的 复位按钮,或者断开并重新连接电源。
此时,芯片会从 系统存储器(System Memory) 启动,而不是从主闪存(Flash)启动。
4. 连接 STM32CubeProgrammer
STM32CubeProg的下载与安装比较简单,此处不再赘述
1.打开 STM32CubeProgrammer。
2.选择正确的连接方式(如 ST-LINK、JTAG、SWD 等)。
点击 “Connect” 按钮,连接目标芯片。

如果连接成功,STM32CubeProgrammer 会显示芯片的信息。
如果连接失败,查看是否是BOOT0,BOOT1没有正确连接跳线帽

5. 擦除芯片
在 STM32CubeProgrammer 中,点击 “Erase” 按钮。
点击确定,擦除整个芯片的闪存。
擦除完成后,芯片的调试接口会恢复正常。
6. 烧录新程序
点击 “Open file” 按钮,选择要烧录的 .hex 或 .elf 文件。

点击 “Download” 按钮,开始烧录程序。
烧录完成后,STM32CubeProgrammer 会显示烧录成功的提示。
注:当CubeProg与开发板连接时,无法通过Clion或者CubeIDE进行烧录,必须先点击Disconnet,之后便可恢复正常烧录。
7. 恢复 BOOT0 引脚
将 BOOT0 引脚从高电平(3.3V)恢复为低电平(GND)。
就是把跳线帽再改回初始的样子
按下复位按钮,芯片会从主闪存(Flash)启动,运行新烧录的程序。
建议烧录一个点灯程序,这时候小灯就一闪一闪的啦。
到此,你已经掌握了通过 BOOT0 引脚强制进入系统存储器模式 的方法,以后遇到类似的问题(比如调试接口被锁死或程序异常导致无法烧录),就可以轻松应对了!
再次看见烧录成功的提示,真🏆亲切~
Info : clock speed 1000 kHz
Info : STLINK V2J37S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.111799
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : [stm32f1x.cpu] Examination succeed
Info : [stm32f1x.cpu] gdb port disabled
[stm32f1x.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
Info : device id = 0x20036410
Info : flash size = 128 KiB
Warn : Adding extra erase range, 0x080012f0 .. 0x080013ff
** Programming Finished **
shutdown command invoked
三、思考原因
我是按照b站up主keysking的教程来写的程序,
详情:【STM32入门教程-2024】第14集 如何在OLED屏幕上挥毫_哔哩哔哩_bilibili
感觉应该是硬件不一样导致的问题,具体是cubemx中哪一项设置,还是写入的oled.c文件中动了谁的蛋糕(寄存器),暂时不得而知。目前怀疑是I2C初始化或者是时钟树的问题,等待各路大佬发表你的见解~
———————————————————————————————————————————
2025.2.9编辑
怀疑对象:I2C硬件问题,会导致总线死锁



2228

被折叠的 条评论
为什么被折叠?



