<< All versions

Skill v1.0.0

currentAutomated scan100/100
kukucaicndy/embedded_ai_skills/stm32-project-init
──Details
PublishedOctober 30, 2026 at 11:00 AM
Content Hashsha256:f99b7d12189def41...
Git SHA306d42a2b27b
──Files
Files (1 file, 13.0 KB)
SKILL.md13.0 KBactive
SKILL.md · 425 lines · 13.0 KB

name: "stm32-project-init" description: "Initialize a new STM32 development project. 交互式收集芯片型号、开发模式(HAL/CMSIS, C/C++)、时钟方案、外设需求,生成 CMakeLists.txt 和 hal_conf.h,编译验证,烧录。Call after stm32-dev-setup is complete." metadata: version: "1.0.0"


STM32 项目初始化

引导用户通过人机交互方式完成新项目的创建、配置、编译和烧录。

跨平台支持:Windows / macOS / Linux。
先确保 stm32-dev-setup 已完成。

Pre-flight: 确保开发环境到位

bash
arm-none-eabi-gcc --version 2>/dev/null | head -1
cmake --version 2>/dev/null | head -1
ls ~/stm32-tools/stm32-cmake/cmake/stm32_gcc.cmake 2>/dev/null
检查项缺失时的操作
arm-none-eabi-gcc 缺失调用 stm32-dev-setup
~/stm32-tools/stm32-cmake 缺失调用 stm32-dev-setup

Step 1: 芯片型号

AI: "请确认你的 STM32 芯片型号(看芯片表面丝印)?"
示例回答: "STM32L431VCTx" / "STM32F103C8T6"
从丝印可以确定:Flash 大小、RAM 大小、封装。常见型号见文末芯片型号速查。

Step 2: 开发模式(核心决策)

AI: "你希望用哪种方式开发?"
┌──────────────────────────────────────────────────────────────┐
│ [1] HAL 库 + C ← 推荐新手/快速开发 │
│ 入口 main.c │ project(C C ASM) │ 需 hal_conf.h │
│ │
│ [2] HAL 库 + C++ ← 面向对象封装 HAL │
│ 入口 main.cpp │ project(C CXX ASM)│ 需 hal_conf.h │
│ ⚠️ HAL 回调必须 extern "C" │
│ │
│ [3] CMSIS 寄存器 + C ← 极致精简、学习底层 │
│ 入口 main.c │ project(C ASM) │ 无需 hal_conf.h │
│ │
│ [4] CMSIS 寄存器 + C++ ← C++ 风格底层编程 │
│ 入口 main.cpp │ project(C CXX ASM)│ 无需 hal_conf.h │
│ ISR 必须 extern "C" │
└──────────────────────────────────────────────────────────────┘

四种模式的 CMakeLists.txt 关键差异

配置项HAL + CHAL + C++CMSIS + CCMSIS + C++
project(...)C C ASMC CXX ASMC ASMC CXX ASM
find_package(HAL)✅ 必需✅ 必需❌❌
hal_conf.h✅ 必需✅ 必需❌❌
入口文件main.cmain.cppmain.cmain.cpp
extern "C" ISR不需要✅ 必需不需要✅ 必需

Step 3: 时钟配置

AI: "期望的系统主频是多少?使用什么时钟源?"

时钟配置速查

系列可用内部时钟PLL 输入范围VCO 范围最高主频
STM32F1HSI 8MHz4-16MHz—72MHz
STM32F4HSI 16MHz1-2MHz100-432MHz168MHz
STM32L4MSI 100k-48M / HSI 16MHz4-16MHz64-344MHz80MHz
STM32G0HSI 16MHz2.66-8MHz96-344MHz64MHz
STM32H7HSI 64MHz1-16MHz150-836MHz550MHz

常用时钟方案

方案芯片PLL 链结果FLASH_LATENCY
MSI 内部STM32L4MSI 4M /1 ×40 /280MHz4
HSI 内部STM32F1HSI 8M /2 ×1248MHz1
HSE 外部STM32F1HSE 8M ×972MHz2
HSI 内部STM32G0HSI 16M /1 ×8 /264MHz2

PLL 计算公式

PLL_IN = PLL_SRC / PLLM → 必须落在 PLL 输入范围内
PLL_VCO = PLL_IN * PLLN → 必须落在 VCO 范围内
PLL_R = PLL_VCO / PLLR → SYSCLK(系统主频)

STM32L4 电压缩放

c
// L4 系列 80MHz 必须先设置电压等级
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
// SCALE1 支持 ≤ 80MHz │ SCALE2 支持 ≤ 26MHz

Step 4: 中间件选择

AI: "需要 RTOS 吗?"
中间件引入方式
FreeRTOSfind_package(CMSIS COMPONENTS {chip} RTOS::FreeRTOS REQUIRED)
FatFS通过 CMSIS + HAL SD/SPI 手动集成
lwIP通过 HAL ETH + 手动集成
USB Stack通过 HAL PCD + 手动集成
⚠️ 使用 FreeRTOS 时,HAL 时基不能再使用 SysTick(FreeRTOS 占用),需用硬件定时器替代。

Step 5: 外设配置

AI: "需要哪些外设?"
示例回答: "UART1, PA9/PA10, 115200" 或 "SPI1 + TIM3 CH1 PWM"
可一次列出多个。
AI 根据回答自主判断是否追问具体引脚、波特率等参数。

Step 6: 确认 + 生成项目

AI 完成交互后,输出配置汇总并让用户确认:
── 项目配置汇总 ──
芯片 : STM32L431VCTx
模式 : HAL + C++
时钟 : MSI 4MHz → PLL 80MHz
中间件 : 无
外设 : UART1 (PA9/PA10, 115200) + GPIO (PB0, 推挽输出)
确认以上配置?我将开始生成 CMakeLists.txt 和 hal_conf.h。

Step 7: 生成项目框架

目录结构

<project>/
├── CMakeLists.txt
├── code/
│ ├── include/
│ │ └── stm32xxx_hal_conf.h ← HAL 模式必需
│ └── src/
│ └── main.c / main.cpp ← 按开发模式
└── build/ ← cmake -B build 自动生成

CMakeLists.txt 模板(按 4 种模式生成)

模式 1: HAL + C

cmake
cmake_minimum_required(VERSION 3.22)
set(CMAKE_TOOLCHAIN_FILE "$ENV{HOME}/stm32-tools/stm32-cmake/cmake/stm32_gcc.cmake")
project(my-project C C ASM)
stm32_fetch_cube({FAMILY})
find_package(CMSIS COMPONENTS {CHIP} REQUIRED)
find_package(HAL COMPONENTS {FAMILY} REQUIRED)
file(GLOB_RECURSE PROJECT_SOURCES code/src/*.c)
add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
target_include_directories(${PROJECT_NAME} PRIVATE code/include)
target_link_libraries(${PROJECT_NAME} PRIVATE
CMSIS::STM32::{TYPE}
HAL::STM32::{FAMILY}
STM32::NoSys
# 按启用的外设添加 HAL modules
)

模式 2: HAL + C++(外设同上,额外加 C++ 选项)

cmake
project(my-project C CXX ASM) # ⚠️ 必须包含 C
file(GLOB_RECURSE PROJECT_SOURCES code/src/*.cpp)
target_compile_options(${PROJECT_NAME} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-std=c++17>
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
$<$<COMPILE_LANGUAGE:CXX>:-fno-threadsafe-statics>
)

模式 3: CMSIS + C

cmake
project(my-project C ASM)
stm32_fetch_cube({FAMILY})
find_package(CMSIS COMPONENTS {CHIP} REQUIRED)
# 不加 find_package(HAL)
target_link_libraries(${PROJECT_NAME} PRIVATE
CMSIS::STM32::{TYPE}
STM32::NoSys
)

模式 4: CMSIS + C++(同 CMSIS+C + C++编译选项)

hal_conf.h(HAL 模式必需)

从 ~/stm32-tools/stm32-cmake/examples/ 下对应家族的模板复制,根据启用的外设去掉对应 `#define` 注释。

c
// 示例:启用 UART 和 DMA
#define HAL_UART_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED // ⚠️ UART 驱动内部引用 DMA
// STM32L4 必须定义完整振荡器值
#define HSE_VALUE 8000000U
#define HSI_VALUE 16000000U
#define MSI_VALUE 4000000U
#define LSE_VALUE 32768U

Step 8: 编译

bash
cmake -S . -B build -G Ninja
cmake --build build 2>&1
# 首次编译时 stm32_fetch_cube() 自动下载 CMSIS+HAL,约 30-60 秒
CMakeLists.txt 编译通过后,AI 才开始写 code/src/main.c(pp)。

Step 9: 应用代码(按模式生成模板)

HAL + C 入口

c
#include "stm32xxx_hal.h"
static void SystemClock_Config(void) { /* 根据时钟配置生成 */ }
int main(void) {
HAL_Init();
SystemClock_Config();
/* 外设 init */
while (1) { /* 用户逻辑 */ }
}

HAL + C++ 入口

cpp
#include "stm32xxx_hal.h"
// ⚠️ ISR 和 HAL 回调必须 extern "C"
extern "C" void SysTick_Handler(void) { HAL_IncTick(); }
int main(void) {
HAL_Init();
/* 时钟 + 外设 init(含电压缩放等) */
while (1) { /* 用户逻辑 */ }
}

CMSIS + C 入口

c
#include "stm32f1xx.h"
static void delay_ms(uint32_t ms) {
SysTick->LOAD = 72000 - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
for (uint32_t i = 0; i < ms; i++) {
while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
}
SysTick->CTRL = 0;
}
int main(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC->CRH &= ~(0xF << 20);
GPIOC->CRH |= (0x3 << 20); // PC13 推挽输出
while (1) {
GPIOC->ODR ^= (1 << 13);
delay_ms(500);
}
}

CMSIS + C++ 入口

cpp
#include "stm32f1xx.h"
extern "C" void SysTick_Handler(void) {}
int main(void) {
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
/* 寄存器操作 */
while (1) { /* ... */ }
}

Step 10: 烧录

路径 A(CubeProgrammer CLI)

bash
CUBEIDE_ROOT=$(ls -d /c/ST/*/STM32CubeIDE /d/ST/*/STM32CubeIDE 2>/dev/null | head -1)
PROGRAMMER=$(ls "$CUBEIDE_ROOT/plugins/.../cubeprogrammer..."_*/tools/bin/STM32_Programmer_CLI.exe | head -1)
"$PROGRAMMER" -c port=SWD -w build/my-project.elf -v -rst -run

路径 B(st-flash)

bash
arm-none-eabi-objcopy -O binary build/my-project.elf build/my-project.bin
st-flash --reset write build/my-project.bin 0x08000000
🔥 st-flash 必须烧 `.bin` 不是 `.elf`! 烧 .elf 会把 ELF 头写入 flash,CPU 读到垃圾 SP/PC,程序完全不执行但显示 verified OK。

硬件接线

ST-Link 目标板
SWDIO ────────────────→ SWDIO
SWCLK ────────────────→ SWCLK
GND ────────────────→ GND
3.3V ────────────────→ 3.3V(如不独立供电)

外设模块速查

HAL 模块名 = HAL 驱动文件名去掉前缀后全大写。如 stm32l4xx_hal_uart.c → HAL::STM32::L4::UART
分类模块CMake Target
必选RCC / GPIO / CORTEX / DMA / FLASH / PWRHAL::STM32::{F}::{MOD}
通信UART / USART / SPI / I2C / CANHAL::STM32::{F}::{MOD}
定时TIM / RTCHAL::STM32::{F}::{MOD}
模拟ADC / DACHAL::STM32::{F}::{MOD}
看门狗IWDG / WWDGHAL::STM32::{F}::{MOD}
存储SD / QSPIHAL::STM32::{F}::{MOD}
USBPCDHAL::STM32::{F}::PCD
扩展RCCEx / PWRExHAL::STM32::{F}::{MOD}

芯片型号速查

系列芯片FlashRAM封装CMSIS 类型
F1F103C8T664KB20KBLQFP48F103xB
F1F103RCT6256KB48KBLQFP64F103xE
F1F103VCT6512KB64KBLQFP100F103xG
L4L431VCTx256KB64KBLQFP100L431xx
L4L476RGTx1MB128KBLQFP64L476xx
F4F407VGT61MB192KBLQFP100F407xx
F4F429ZIT62MB256KBLQFP144F429xx

故障排错

编译错误

#报错原因修复
1UART_HandleTypeDef undeclaredhal_conf.h 中对应 #define 被注释去注释
2undefined reference to HAL_xxxCMakeLists 未链接对应 HAL module添加 HAL::STM32::{F}::xxx
3cannot find -lSTM32::NoSys未链接 NoSys添加 STM32::NoSys
4fatal error: stm32xxx_hal.hinclude 路径不对target_include_directories
5'-std=c++17' is valid for C++ but not for CC++ 选项传给 C用 $<$<COMPILE_LANGUAGE:CXX>:...>
6C++ 项目 undefined reference to HAL_xxxproject 只写了 CXX 没 C改为 project(... C CXX ASM)
7XferAbortCallback not in structDMA 模块未启用hal_conf.h 中启用 HAL_DMA_MODULE_ENABLED

运行时问题

#现象原因修复
8HAL_Delay 不工作PLL 后 SysTick 未重配HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000)
9L4 PLL 80MHz 死机未设置电压等级HAL_PWREx_ControlVoltageScaling(SCALE1)
10烧录 verified 但程序不跑st-flash 烧了 .elfobjcopy -O binary 后烧 .bin
11串口乱码时钟配置与实际不符检查 SystemClock_Config
12FreeRTOS + HAL_Delay 都不工作HAL 时基用 SysTick(被 FreeRTOS 占用)改为硬件定时器

烧录问题

#现象修复
13chipid: 0x000 + Failed to enter SWDSWD 被锁。断电 → BOOT0=1 上电 → 擦除 → BOOT0=0
14st-flash LIBUSB_ERROR_TIMEOUT检查 ST-Link 驱动
All versions