3. STM32CubeMX项目创建:从零搭建你的AI推理工程
说实话,很多初学者拿到一块开发板,第一件事就是急着写代码。我当年也是这样,结果往往是灯不亮、串口没输出,折腾半天发现是时钟没配对。做嵌入式AI项目,底子打不好,后面模型推理再牛也跑不起来。
这一章,我们就手把手把STM32项目搭起来。时钟树、GPIO、UART,一个都不能少。
3.1 新建STM32项目——选对芯片是第一步
打开STM32CubeMX,界面很清爽。点击“New Project”,进入芯片选择界面。
我个人习惯用Part Number搜索,直接输入芯片型号。比如我们课程用的STM32F746ZG,输入后下方列表会过滤出来。双击选中,项目就创建了。
创建项目后,你会看到芯片的引脚图。别慌,咱们一步步来配置。
3.2 时钟树配置——芯片的心脏起搏器
时钟树,说白了就是给芯片各个模块分配时钟信号。配错了,外设可能不工作,或者工作频率不对。
点击“Clock Configuration”标签页,进入时钟树配置界面。这里我重点讲三个时钟源:
| 时钟源 | 典型频率 | 用途 |
|---|---|---|
| HSE(高速外部晶振) | 8 MHz / 25 MHz | 系统主时钟、PLL输入 |
| LSE(低速外部晶振) | 32.768 kHz | RTC实时时钟、低功耗模式 |
| PLL(锁相环) | 可倍频至216 MHz(F7) | 将低频时钟倍频到高频 |
配置步骤:
- 选择HSE作为时钟源:在“HSE”下拉框选择“Crystal/Ceramic Resonator”。
- 配置PLL:我一般把PLL Source选为HSE,然后设置倍频系数。比如HSE=8MHz,PLLM=8,PLLN=216,PLLP=2,最终得到216MHz。
- 设置系统时钟:在“System Clock Mux”选择“PLLCLK”。
- 检查APB1/APB2分频:确保总线时钟不超过各自的最大频率。APB1通常最大54MHz,APB2最大108MHz。
配置完成后,CubeMX会自动计算各总线时钟频率。你可以在右上角看到HCLK、APB1、APB2的值。确认无误后,进入下一步。
3.3 GPIO与UART外设配置——让芯片开口说话
时钟配好了,接下来配置外设。我们先配一个LED灯(GPIO输出),再配一个串口(UART),用来打印调试信息和AI推理结果。
3.3.1 GPIO配置——点亮第一盏灯
在Pinout视图里,找到你板子上的LED引脚。以STM32F746G-DISCO为例,LED通常接在PI1(红色)、PI2(绿色)、PI3(蓝色)。
点击PI1,选择“GPIO_Output”。然后右键点击该引脚,选择“Enter User Label”,输入“LED_RED”。这样代码里就能直接用LED_RED这个宏了。
配置GPIO参数:
- Output Level:Low(默认低电平,LED灭)
- Mode:Push-Pull(推挽输出)
- Pull-up/Pull-down:No pull(不拉)
- Maximum output speed:Low(LED不需要高速)
3.3.2 UART配置——串口打印Hello World
回到Pinout视图,找到USART1。点击“USART1”的TX和RX引脚,系统会自动分配引脚(通常是PA9和PA10)。
在“Configuration”面板里,设置UART参数:
| 参数 | 推荐值 | 说明 |
|---|---|---|
| Baud Rate | 115200 | 常用波特率,兼顾速度和稳定性 |
| Word Length | 8 Bits | 标准数据位 |
| Parity | None | 无校验 |
| Stop Bits | 1 | 1个停止位 |
配置完成后,记得在“NVIC Settings”里使能USART1全局中断。这样后续做中断接收时就不用再回头配了。
3.4 生成初始化代码——一键生成,省心省力
所有外设配置完成后,点击右上角的“GENERATE CODE”按钮。CubeMX会弹出一个对话框,让你选择IDE和项目路径。
我一般选“MDK-ARM”或“STM32CubeIDE”,然后点“OK”。几秒钟后,代码就生成好了。
生成的代码结构很清晰:
- Core/Inc:头文件,包含main.h、gpio.h、usart.h等
- Core/Src:源文件,包含main.c、gpio.c、usart.c等
- Drivers:HAL库驱动文件
打开main.c,你会看到CubeMX已经帮我们写好了初始化代码:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
while (1)
{
// 你的AI推理代码将写在这里
}
}
看到没?时钟、GPIO、UART的初始化函数都自动生成了。你只需要在while(1)里添加业务逻辑就行。
3.5 本章知识结构图
下面这张图总结了从创建项目到生成代码的完整流程: