2. STM32CubeMX 工程创建与配置

好,咱们正式开始动手。这一章我会带着你,从零创建一个 STM32H747 的项目。别小看这一步,很多坑其实都埋在这里。我见过不少新手,代码写了大半,回头发现时钟配错了,或者调试口被占用了,那才叫一个头疼。

咱们的目标很明确:把基础环境搭稳,后面跑 AI 模型才不会出幺蛾子。

2.1 新建 STM32H747 项目

打开 STM32CubeMX,界面很直观。点击 “New Project”,进入芯片选择窗口。

在搜索框输入 STM32H747,你会看到一堆型号。别慌,咱们选的是 STM32H747XIH6 或者 STM32H747I-DISCO 板载的那颗。我个人习惯直接搜 H747XI,然后挑带 H6 后缀的,因为它是 BGA 封装,引脚多,方便折腾。

小提示: 如果你用的是官方开发板,比如 STM32H747I-DISCO,可以直接在 Board Selector 里选,CubeMX 会自动帮你配好大部分外设。但咱们是实战课,我建议你从 MCU Selector 开始,这样对底层更清楚。

选好后,点 “Start Project”。系统会弹出一个初始化对话框,问你要不要初始化所有外设。点 “No” —— 咱们自己来配,心里有数。

2.2 时钟树配置(HSE + PLL)

时钟是芯片的心脏。H747 有两个内核:一个 Cortex-M7(主核,跑 AI 推理),一个 Cortex-M4(辅核,做控制)。咱们主要用 M7,所以时钟得给它喂饱。

切换到 Clock Configuration 标签页。默认用的是 HSI(内部高速振荡器),精度一般,跑不了高频。咱们要换成 HSE(外部高速晶振)。

  1. 选择 HSE 作为时钟源:在 HSE 下拉框里选 Crystal/Ceramic Resonator。H747 开发板上通常焊了一个 25MHz 的晶振。
  2. 配置 PLL1:H747 的 PLL 很强大,可以独立给 M7 和 M4 供时钟。咱们主要配 PLL1,它负责给 M7 内核和系统总线提供时钟。
    • 输入源:HSE(25MHz)
    • 分频系数 M:5(25 / 5 = 5MHz 进入 PLL)
    • 倍频系数 N:96(5 * 96 = 480MHz)
    • 系统输出分频 P:2(480 / 2 = 240MHz,这是 M7 的内核频率)
  3. 确认 AHB 总线时钟:在 AHB Prescaler 里选 /1,这样 AHB 总线也是 240MHz。外设总线 APB1 和 APB2 可以适当分频,比如 APB1 设 /2 得到 120MHz,APB2 设 /2 得到 120MHz。
注意: H747 的 M7 内核最高支持 480MHz,但那是极限值。我建议稳定跑 400MHz 或 240MHz。240MHz 对于图像识别来说完全够用,而且发热和功耗都低很多。我曾经在项目里试过 480MHz,散热没做好,芯片烫得能煎鸡蛋。

配好之后,时钟树大概长这样:

时钟树配置流程(HSE → PLL1 → 系统时钟) HSE 晶振 (25MHz) M = 5 PLL1 N = 96 P = 2 M7 内核时钟:240MHz 说明:HSE 经 M 分频后进入 PLL1,再经 N 倍频,最后经 P 分频输出 240MHz。 APB1 = 120MHz,APB2 = 120MHz,AHB = 240MHz。

2.3 调试接口配置(SWD)

调试接口是咱们和芯片沟通的桥梁。H747 支持 JTAG 和 SWD 两种模式。我强烈建议用 SWD,它只需要两根线(SWDIO + SWCLK),省引脚,而且速度不慢。

在 Pinout & Configuration 标签页里,找到 SYS 分类下的 Debug 选项。默认可能是 JTAG (5 pins),咱们改成 Serial Wire (SWD)。

重要: 如果你用的是开发板,SWD 引脚通常已经连到了板载的 ST-Link。但如果你是自己画的板子,一定要确认 SWDIO 和 SWCLK 没有和其他外设共用。我曾经犯过这个错,把 SWDIO 复用成了 GPIO,结果第一次烧录完就再也连不上了,只能按住复位键擦除芯片。

改完之后,你会发现 PA13(SWDIO)和 PA14(SWCLK)自动被分配了功能。别动它们,这是保命线。

2.4 串口配置(USART1)

串口是咱们的“日志输出口”。AI 模型跑起来之后,打印推理结果、打印帧率,全靠它。我选 USART1,因为它通常映射到 PA9(TX)和 PA10(RX),这两个引脚在开发板上很容易接出来。

在 Connectivity 分类下找到 USART1,勾选 Asynchronous 模式。然后配置参数:

参数 值 说明
Baud Rate 115200 标准波特率,够用
Word Length 8 Bits 标准数据位
Parity None 无校验,省事
Stop Bits 1 标准停止位

配完之后,记得在 NVIC Settings 标签页里,把 USART1 全局中断的 Enabled 勾上。这样咱们才能用中断方式收发数据,不阻塞 CPU。

经验之谈: 波特率 115200 是通用选择。如果你要打印大量图像数据(比如调试时输出像素值),可以提到 921600。但要注意,你的串口工具也得支持这么高的速率。

2.5 GPIO 配置(LED + 按键)

LED 和按键是嵌入式开发的“Hello World”。咱们用 LED 指示系统状态,用按键触发拍照或推理。

在开发板上,LED 通常接在 PB0 或 PI8(具体看板子)。咱们以 PB0 为例:

  • 在 Pinout 视图里找到 PB0,右键选择 GPIO_Output。
  • 在 GPIO 配置页面里,把 Maximum output speed 设为 Low(LED 不需要高速)。
  • 把 User Label 改成 LED_GREEN,这样代码里直接引用这个名字,清晰明了。

按键呢?开发板上的用户按键通常接在 PC13 或 PA0。咱们以 PC13 为例:

  • 找到 PC13,右键选择 GPIO_Input。
  • 在 GPIO 配置里,把 Pull-up/Pull-down 设为 Pull-up(按键按下时读到低电平)。
  • User Label 改成 KEY_USER。
注意: 按键消抖!硬件上可以加一个 100nF 电容,软件里也要做 10-20ms 的延时消抖。我见过有人没做消抖,按一次按键触发了十几次中断,模型推理被反复调用,直接卡死。

2.6 生成初始化代码

所有配置都确认无误后,点 Project Manager 标签页。这里有几个关键设置:

设置项 推荐值 原因
Project Name AI_Image_Recognition 见名知意
Toolchain / IDE MDK-ARM V5 咱们用 Keil,兼容性好
Minimum Firmware Version V1.9.0 或更高 H747 的 HAL 库更新很快,老版本可能有 bug
Generate peripheral initialization as a pair of .c/.h files 勾选 每个外设单独文件,好维护

点 GENERATE CODE,CubeMX 会帮你生成完整的工程。打开 Keil 或者你喜欢的 IDE,编译一下,应该零错误零警告。

检查清单:
  • 时钟树:HSE 25MHz → PLL1 → 240MHz
  • 调试口:SWD(PA13, PA14)
  • 串口:USART1(PA9, PA10),115200 8N1
  • LED:PB0,输出,低电平点亮
  • 按键:PC13,输入,上拉,按下低电平