ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

嵌入式调试笔记<3>使用VScdoe开发STM32单片机

2026/9/2 8:28:05 拓冰建站 浏览量
嵌入式调试笔记<3>使用VScdoe开发STM32单片机 嵌入式调试笔记一、MAX13487芯片产生数据回环问题二、Keil在线调试过程中遇到的问题三、使用VScdoe开发STM32单片机四、VANTPEK可调电源接负载电压被拉低五、用CD74HC4067扩展16路ADC采集及两个调试坑文章目录嵌入式调试笔记前言一、软件安装1.安装STM32CubeMX。2.安装Visual Studio Code。二、工具下载配置1.MinGW2.arm-none-eabi-gcc3.OpenOCD4.配置环境变量三、使用STM32CubeMX生成代码四、使用stm32-for-vscode 插件方式开发1.插件安装2.代码编写3.下载程序烧录4.在线调试5.添加用户文件及目录6.C/C 混合编程五、自己配置 Makefile 方式开发1.C 语言工程2.C/C 混合编程六、常见问题及解决办法1.找不到头文件或宏定义编译能过但 VSCode 飘红2.每次编译都要手敲命令总结前言尝试使用VScdoe开发STM32单片机。一、软件安装1.安装STM32CubeMX。STM32CubeMX 是一种图形工具通过分步过程可以非常轻松地配置 STM32 微控制器和微处理器以及为 Arm® Cortex®-M 内核或面向 Arm® Cortex®-A 内核的特定 Linux® 设备树生成相应的初始化 C 代码。下载地址STM32CubeMX - STM32Cube initialization code generator - STMicroelectronics2.安装Visual Studio Code。Visual Studio Code简称VSCode是一款轻量级但功能强大的代码编辑器支持多种编程语言并内置了Git版本控制。下载地址Visual Studio Code - Code Editing. Redefined二、工具下载配置1.MinGWMinGW-w64 是“Minimalist GNU for Windows 64-bit”的缩写它把 Linux 下常见的 GCC、G、GDB 等一整套 GNU 开发工具搬到 Windows让你不用装虚拟机就能在 Win 上直接编译 C/C 源码并生成 exe。MinGW-w64 只依赖微软自带的 C 运行库编译出的程序体积小拷到别的 Win 电脑就能跑不用拖一堆额外 DLL真正做到了绿色跨平台。下载地址MinGW-w642.arm-none-eabi-gccarm-none-eabi-gcc 是一种交叉编译器是 ARM 官方维护的开源编译器工具链专门用于 ARM Cortex-M 和 Cortex-R 处理器的裸机和 RTOS 应用开发。下载地址Downloads | GNU Arm Embedded Toolchain Downloads – Arm Developer3.OpenOCDOpenOCDOpen On-Chip Debugger开源片上调试器是一款开源软件OpenOCD的功能是在仿真器的辅助下完成的仿真器是能够提供调试目标的电信号的小型硬件单元。仿真器是必须的因为调试主机运行OpenOCD的主机通常不具备这种电信号的直接解析功能。下载地址Download OpenOCD for Windows (gnutoolchains.com)4.配置环境变量下载上面提到的3个工具的ZIP版本解压出来放到同一个文件夹配置系统环境变量路径后即可使用。配置完成后打开CMD命令窗口验证输入make -v命令验证MinGW输入arm-none-eabi-gcc -v命令验证arm-none-eabi-gcc输入openocd -v验证OpenOCD 三、使用STM32CubeMX生成代码打开STM32CubeMX根据手头上单片机型号新建LED工程选择Makefile生成代码。将生成的工程文件夹用VScode打开可以将文件夹拖动到VSCode应用程序上也可以在文件夹根目录打开终端输出code .来加载四、使用stm32-for-vscode 插件方式开发1.插件安装首先需要安装的是C/C的高亮以及自动补全插件在VSCode拓展库中搜索C/C选择图示中的安装stm32-for-vscode 是VSCode中的一款个人开发的插件通过配置Makefile文件来帮助开发者快速搭建工程。首先在VSCode拓展库中搜索stm32-for-vscode选择图示中的安装如果之前的环境变量都没问题的话安装完成后可以看到侧边栏的图标打开后是这样的2.代码编写main函数增加指示灯闪烁的代码cfg配置文件中增加说明使用Jlink的SWD接口,默认是STlink。点击STM 32 For VSCode 插件中的bulid编译工程编译通过会在工程目录下生成build文件夹里面有.bin、.elf等文件烧录和调试用的就是它们。**问题**编译时出现错误:106: non constant or forward reference address expression for section .ARM.extabcollect2.exe: error: ld returned 1 exit statusmake.EXE: *** [STM32Make.make:300: build/debug/test.elf] Error 1如下图**原因**之前用CubeMX6.1.2生成没有问题后来升级6.18版本后报错。报错 non constant or forward reference address expression for section .ARM.extab 不是代码问题而是链接脚本与工具链版本不匹配报错的工程用了 CubeMX 2025 生成的脚本里面给 .ARM.extab、.ARM、.preinit_array、.init_array、.fini_array 这 5 个段加了 (READONLY) 关键字。该关键字脚本里自己都写了注释“only supported in GCC11 and later”。 make 时没指定 ARM_GCC_PATH走的是 PATH 上的旧 ARM GCCSystem Workbench 自带GCC 7–10。旧链接器不识别 READONLY于是把 .ARM.extab 段的地址当成了前向引用/非常量表达式直接 ld returned 1。**解决办法**两种修法任选其一改脚本STM32F103xx_FLASH.ld中去掉 五处READONLY —— 兼容现有旧工具链无需动环境。升级工具链把 make 指向 GCC 11 的 arm-none-eabi-例如 make ARM_GCC_PATH/path/to/gcc11/bin脚本原样也能过。3.下载程序烧录插件侧边栏有 “Flash STM32” 按钮点一下就能把程序下到单片机。前提是下载器J-Link 或 ST-Link接好并且 cfg 里接口配对了。我用的是 J-Link 的 SWD 接口cfg 里interface填jlink、transport填swd即可换 ST-Link 把 interface 改成stlink即可。下载成功板子上的 LED 就该闪了。没反应先查下载器驱动有没有装、接线对不对SWDIO / SWCLK / GND / VCC 四根。4.在线调试点侧边栏的 “Debug STM32”插件会自己调起 OpenOCD Cortex-Debug 进调试模式。几个常用操作1 左边变量监视窗口看变量实时值2 行号左边点一下加断点程序跑到这就停3 顶部继续 / 单步 / 步入 / 步出控制执行4 调试控制台里能直接敲 GDB 命令。第一次进调试如果报错多半是 OpenOCD 没找到下载器或 cfg 里芯片型号不对。核对一下选型即可比如STM32F103C8T6对应stlinktarget/stm32f1x.cfg。5.添加用户文件及目录工程不可能所有代码都堆在main.c。新建自己的.c/.h时改STM32-for-VSCode.config.yaml就行includeDirectories:-Inc-Drivers/CMSIS/Include-User/Inc# 新增头文件目录sourceFiles:-Src/main.c-User/Src/led.c# 新增源文件路径写相对工程的加源文件要同步加它的头文件目录否则编译报找不到头文件。插件本质就是帮你配好 Makefile加了文件重新点一下 Build 即可不用手动改 Makefile。6.C/C 混合编程想用 C 写逻辑比如类封装又不想动 CubeMX 生成的 C 代码可以混编。yaml 里把语言改一下language:ClinkerFlags:--specsnosys.specs插件会把main.c复制成main.cpp并生成对应 Make 规则。注意两点1 C 里要调 CubeMX 生成的 C 函数如HAL_GPIO_TogglePin必须用extern C包一下声明否则链接阶段找不到符号2 头文件里这么写#ifdef__cplusplusexternC{#endifvoidLED_Toggle(void);// C 函数声明#ifdef__cplusplus}#endif混编的坑基本在链接阶段。-specsnosys.specs是指定用 newlib-nano 的 nosys 桩少了这条会报_sbrk之类的未定义引用。具体为什么这么配作者也没深究照着加一般没错。五、自己配置 Makefile 方式开发插件虽好但它把 Makefile 藏起来自动生成了新手容易会用但不懂。想把编译下载这套流程搞明白建议再走一遍手动写 Makefile。手动方式不依赖 stm32-for-vscode 插件纯靠 Makefile OpenOCD能让你看清每一步在干什么。1.C 语言工程1编译工程根目录打开终端输入make// 编译生成 .o 和目标文件make-j16// 多核并行加快编译2全量重新编译makeclean // 清掉上次编译产物make-j16// 重新全编3下载程序Makefile 末尾手动加一个flash目标用 OpenOCD 烧录flash: openocd -f interface/stlink.cfg -f target/stm32f1x.cfg \ -c program build/xxx.elf verify reset exitxxx.elf换成你实际生成的 elf 名下载器是 J-Link 就把interface/stlink.cfg换成interface/jlink.cfg。之后make flash即可一键烧录。4调试装Cortex-Debug插件新建.vscode/launch.json{version:0.2.0,configurations:[{type:cortex-debug,request:launch,name:Debug STM32,executable:./build/xxx.elf,servertype:openocd,configFiles:[interface/stlink.cfg,target/stm32f1x.cfg]}]}按 F5 进调试用法和插件方式一样。5添加用户文件手动方式要自己改 Makefile1C_INCLUDES里加-IUser/Inc指定新头文件目录2C_SOURCES里加User/Src/led.c \注意每行末尾的\续行符不能少最后一行不加。C_SOURCES \ Core/Src/main.c \ User/Src/led.c2.C/C 混合编程手动混编就是给 Makefile 加 C 规则1 定义 C 源文件列表CPP_SOURCES Src/main.cpp2 指定 C 编译器CXX $(PREFIX)g3C_INCLUDES追加 C 头目录4LDFLAGS加-specsnosys.specs5OBJECTS用追加.cpp.o规则注意 OBJECTS 只能定义一次后面一律用OBJECTS $(addprefix $(BUILD_DIR)/,$(notdir $(CPP_SOURCES:.cpp.cpp.o)))6 CubeMX 的 C 头文件里用extern C包住声明和插件方式同理。C 调 C 的函数必须有extern C否则 C 的名字改编name mangling会让链接器找不到符号这是混编最常见的报错来源。六、常见问题及解决办法1.找不到头文件或宏定义编译能过但 VSCode 飘红编译其实没问题是 VSCode 的智能感知没找到 include 路径。新建.vscode/c_cpp_properties.json{configurations:[{name:STM32,includePath:[${workspaceFolder}/**],defines:[USE_HAL_DRIVER,STM32F103xx],compilerPath:C:/toolchain/gcc-arm-none-eabi-10.3/bin/arm-none-eabi-gcc.exe}],version:4}defines里把芯片宏补上飘红基本就消了。具体值看 CubeMX 生成的main.h里怎么定义的即可。2.每次编译都要手敲命令嫌麻烦就把常用操作配成任务。新建.vscode/tasks.json{version:2.0.0,tasks:[{label:build,type:shell,command:make -j16},{label:clean,type:shell,command:make clean},{label:flash,type:shell,command:make flash}]}之后CtrlShiftB选任务即可或者装个Task Runner插件任务列表直接点。总结到这里用 VSCode 开发 STM32 的整条路就通了装好 STM32CubeMX / VSCode / 工具链CubeMX 生成 Makefile 工程插件方式快速上手手动方式摸清原理再加上常见问题排查。两种方式都走一遍体会比较明显插件法几乎零配置装好就能写、能烧、能调适合想快点把活干完的时候用手动配 Makefile 费点劲但能搞清楚arm-none-eabi-gcc怎么编、openocd怎么下、launch.json怎么调遇到问题心里有底。我个人现在日常用插件法偶尔手动走一遍防手生。新手建议两者都试先插件跑通点灯再手动把同一份工程编出来理解会扎实很多。关于C混编部分请看参考文章更详细一些。如有表述错误、介绍模糊的地方欢迎交流指正。参考文章【STM32】VSCode 开发 STM32(支持C) - 知乎STM32CubeMX - STMicroelectronicsVisual Studio Code - Code Editing. Redefined