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”,工程就建好了。
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。所以,配置时钟时,一定要想清楚你的外设需要什么频率。
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 秒的频率闪烁。
好了,这一章就到这里。下一章,我们会开始接触 CubeAI,看看怎么把训练好的模型部署到 STM32 上。
公众号:蓝海资料掘金营,微信deep3321