2. STM32CubeMX 项目生成基础:新建工程、配置时钟树与 GPIO、生成 MDK-ARM 工程、初识 .ioc 文件结构

好,咱们正式开始动手了。

这一章,我会带你走一遍 STM32CubeMX 的完整流程。从新建工程,到配置时钟树,再到点个灯,最后生成 MDK 工程。说白了,就是先把开发环境跑通,让你心里有个底。

我个人习惯,拿到一块新板子,第一件事就是先点灯。灯亮了,说明芯片活了,时钟对了,GPIO 也通了。这是嵌入式工程师的“Hello World”。

2.1 新建 STM32CubeMX 工程

打开 STM32CubeMX,你会看到一个欢迎界面。别慌,直接点 “New Project” 就行。

接下来,它会让你选芯片型号。这里有个小技巧:

  • 如果你用的是开发板:直接点 “Board Selector” 选项卡,输入板子型号,比如 “NUCLEO-F767ZI”。CubeMX 会自动帮你配好外设。
  • 如果你是自己画的板子:点 “MCU Selector”,然后输入芯片型号,比如 “STM32F767ZIT6”。

我在项目中遇到过,有人图省事直接选了开发板配置,结果自己画的板子引脚对不上,折腾了半天。所以,自己画板子的话,老老实实选 MCU 型号。

选好后,点 “Start Project”,工程就建好了。

我的习惯: 工程名字不要用中文,路径也不要带空格。否则 MDK 编译时可能会报一些莫名其妙的错误。

2.2 配置时钟树

时钟树,说白了就是给芯片各个部分分配时钟频率。STM32 的时钟系统比较复杂,但 CubeMX 把它图形化了,操作起来很直观。

在 CubeMX 的 “Pinout & Configuration” 视图里,找到 “Clock Configuration” 选项卡。你会看到一张时钟树图。

嗯,这里要注意:

  • HSE(高速外部时钟):一般用 8MHz 或 25MHz 的晶振。开发板上通常已经焊好了。
  • PLL(锁相环):用来倍频。比如 HSE 是 8MHz,你想让芯片跑到 216MHz,就需要通过 PLL 来倍频。
  • SYSCLK(系统时钟):这是芯片的主频,所有外设都基于它。

配置时,你只需要在 “HCLK (MHz)” 那个框里输入你想要的频率,比如 216。CubeMX 会自动帮你算好分频系数和倍频系数。如果算出来是红色,说明这个频率不支持,需要调整。

我曾经有一次,为了省电,把时钟配低了,结果 USB 通信死活不工作。后来才发现,USB 外设需要 48MHz 的时钟,而我的系统时钟太低,分频后给不到 48MHz。所以,配置时钟时,一定要想清楚你的外设需要什么频率。

避坑指南: 我曾经在配置时钟时,不小心把 PLL 的 M、N、P 系数设错了,导致芯片无法启动。后来用 ST-Link Utility 把芯片擦除才救回来。所以,第一次配置时,尽量用 CubeMX 推荐的参数。

2.3 配置 GPIO

时钟配好了,接下来就是点灯了。点灯需要配置 GPIO。

在 “Pinout & Configuration” 视图里,找到你要用的 GPIO 引脚。比如,开发板上的 LED 通常接在 PA5 或 PB0 上。你可以在芯片图上直接点击那个引脚,然后选择 “GPIO_Output”。

配置完成后,点 “GPIO” 选项卡,可以设置引脚的详细参数:

  • Output Level:初始电平,我一般设成 Low,这样上电后灯是灭的。
  • Mode:推挽输出(Push-Pull)还是开漏输出(Open-Drain)。点灯用推挽就行。
  • Pull-up/Pull-down:一般不用,设成 No pull-up/pull-down。
  • Maximum output speed:点灯用 Low 就行,高速信号才需要 High。

你想想看,这些参数其实都是寄存器里的位。CubeMX 帮你图形化了,省得你去翻参考手册。

2.4 生成 MDK-ARM 工程

配置完成后,点 “Project” -> “Generate Code”。

在弹出的对话框里,选择你的 IDE。我用的是 MDK-ARM(Keil),所以选 “MDK-ARM V5”。

这里有个选项叫 “Generate peripheral initialization as a pair of .c/.h files per peripheral”。我建议勾上。这样每个外设的初始化代码都会单独放在一个 .c 和 .h 文件里,方便管理。

点 “Generate”,CubeMX 就会帮你生成完整的工程。生成完成后,点 “Open Project”,MDK 就会自动打开。

我的习惯: 生成代码后,我会先编译一次,确保没有错误。然后再开始写自己的代码。

2.5 初识 .ioc 文件结构

工程根目录下,有一个 .ioc 文件。这个文件是 CubeMX 的配置文件,记录了你的所有配置。

你可以用记事本打开它,看看里面是什么。说白了,就是一个文本文件,里面是键值对:

# 时钟配置
RCC.HSE_VALUE=8000000
RCC.PLLM=8
RCC.PLLN=432
RCC.PLLP=2

# GPIO 配置
PA5.GPIO_Mode=GPIO_MODE_OUTPUT_PP
PA5.GPIO_PuPd=GPIO_NOPULL
PA5.GPIO_Speed=GPIO_SPEED_FREQ_LOW

嗯,这里要注意:

  • 不要手动修改 .ioc 文件:除非你非常清楚自己在做什么。否则,一旦格式错了,CubeMX 可能打不开。
  • .ioc 文件是“活”的:你可以在 CubeMX 里修改配置,然后重新生成代码。CubeMX 会保留你之前写的用户代码(前提是你把代码写在 “USER CODE BEGIN” 和 “USER CODE END” 之间)。

我曾经见过有人直接改 .ioc 文件,结果把引脚的配置写错了,导致芯片短路。所以,还是老老实实用 CubeMX 的图形界面吧。

2.6 写个点灯程序

工程生成好了,我们来写个点灯程序。

在 MDK 里,找到 main.c 文件。在 “USER CODE BEGIN 2” 和 “USER CODE END 2” 之间,加上初始化代码:

/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); // 先灭灯
/* USER CODE END 2 */

在 “USER CODE BEGIN 3” 和 “USER CODE END 3” 之间,加上主循环代码:

/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); // 翻转电平
HAL_Delay(500); // 延时 500ms
/* USER CODE END 3 */

编译、下载。如果一切顺利,你会看到 LED 灯以 1 秒的频率闪烁。

注意: 这里的 LED_GPIO_Port 和 LED_Pin 是 CubeMX 自动生成的宏定义。你可以在 main.h 或 gpio.h 里找到它们。

好了,这一章就到这里。下一章,我们会开始接触 CubeAI,看看怎么把训练好的模型部署到 STM32 上。

公众号:蓝海资料掘金营,微信deep3321