创建工程
目标:得到一个可重复打开、可重新生成、可编译的工程骨架。
1. 用 CubeMX 建项目
启动并选择芯片
打开 STM32CubeMX:

选择 STM32F103C8(或你板子实际型号):

打开 SWD 调试口
在 SYS 中把 Debug 配成 Serial Wire,否则下载器往往连不上:

工程设置
在 Project Manager 里:
- 工程名、路径选你能长期放得住的位置
- Toolchain / IDE 选 CMake(与本教程一致)
- 生成选项里建议勾选「为每个外设生成独立的
.c/.h」(若界面提供),目录更干净

生成代码

生成后请先不要急着在随机文件里大段涂改。
CubeMX 会在关键位置留下 USER CODE BEGIN / END 保护区——后面闪灯会演示:逻辑写在这些区块里,下次改时钟或引脚再生成,你的代码还在。
2. 用 VS Code 打开

.vscode/settings.json
按本机 CubeCLT 安装路径 修改(下列为 Windows 示例):
.vscode/settings.json
{
"cmake.cmakePath": "D:/ST/STM32CubeCLT_1.18.0/CMake/bin/cmake.exe",
"cmake.generator": "Ninja",
"cmake.configureOnOpen": true,
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.environment": {
"PATH": "${env:PATH};D:/ST/STM32CubeCLT_1.18.0/GNU-tools-for-STM32/bin;D:/ST/STM32CubeCLT_1.18.0/Ninja/bin;"
}
}
macOS / Linux 把路径换成你的 cmake 与 arm-none-eabi-* 所在目录即可。
.vscode/c_cpp_properties.json
帮助跳转与补全(路径同样按本机调整):
.vscode/c_cpp_properties.json
{
"configurations": [
{
"name": "STM32F103C8T6",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/Core/Inc",
"${workspaceFolder}/Drivers/STM32F1xx_HAL_Driver/Inc",
"${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32F1xx/Include",
"${workspaceFolder}/Drivers/CMSIS/Include"
],
"defines": [
"STM32F103xB",
"USE_HAL_DRIVER"
],
"compilerPath": "D:/ST/STM32CubeCLT_1.18.0/GNU-tools-for-STM32/bin/arm-none-eabi-gcc.exe",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-arm"
}
],
"version": 4
}
defines 须与芯片匹配;选错系列会出现「能打开工程但满屏飘红」或链接怪异。
3. 生成 hex / bin(方便下载)
在根目录 CMakeLists.txt 末尾追加(若生成模板尚未包含类似逻辑):
CMakeLists.txt(追加)
# 构建后打印体积,并生成 hex / bin,便于烧录脚本引用
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${CMAKE_PROJECT_NAME}>
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${CMAKE_PROJECT_NAME}> ${CMAKE_PROJECT_NAME}.hex
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${CMAKE_PROJECT_NAME}> ${CMAKE_PROJECT_NAME}.bin
)
这样每次编译都能直接看到代码/数据占用,也避免手搓 objcopy 命令不一致。
4. 先编译一次空工程
在 VS Code 里配置并编译:

能通过,再往下写业务。
空工程都编不过,先查工具链 PATH、生成器与芯片宏,不要急着加闪灯代码「一起爆」。
5. 烧录脚本(先就位)
在工程根目录放一个小脚本,路径指向你的 STM32_Programmer_CLI 与产物。
Windows 示例(工程名、build 子目录以你生成为准):
flash.bat
@echo off
set CLI=D:\ST\STM32CubeCLT_1.18.0\STM32CubeProgrammer\bin\STM32_Programmer_CLI.exe
set HEX=%~dp0build\Release\%CMAKE_PROJECT_NAME%.hex
REM 若 hex 路径不同,改成实际位置,例如 build\gsk.hex
if not exist "%HEX%" (
echo hex not found: %HEX%
exit /b 1
)
"%CLI%" -c port=SWD -w "%HEX%" -v -rst
更稳妥的做法是:编译成功后看一眼 build 目录里 真实的 .hex 文件名,把脚本改成那个路径,并写进团队说明。
「脚本里写死一个猜的名字」是下载失败的高频原因。
下一步:在工程里接上 LED,写闪灯逻辑 → 第一个闪灯程序。