2. 开发环境搭建:Keil MDK安装、STM32CubeMX配置、HAL库工程模板建立、串口打印调试
做电机控制,说白了就是跟硬件和代码打交道。环境搭不好,后面全是坑。我见过不少新手,代码写得挺漂亮,结果一烧录就黑屏,最后发现是工程配置错了。所以这一章,咱们把地基打牢。
2.1 工具链总览
先看看我们要用哪些家伙。别急着装,心里有个数先。
| 工具 | 版本建议 | 干什么用 |
|---|---|---|
| Keil MDK-ARM | V5.38 或更新 | 写代码、编译、调试 |
| STM32CubeMX | V6.10+ | 图形化配置外设、生成HAL初始化代码 |
| HAL库 | F4 V1.28+ | 硬件抽象层,不用直接操作寄存器 |
| 串口助手 | 任意 | 看打印信息,调试PID参数 |
我个人习惯用 Keil V5.38,稳定,兼容性好。CubeMX 版本别太老,不然有些外设配置选项找不到。
2.2 Keil MDK 安装与注册
安装过程其实没啥好说的,下一步下一步就行。但有几点我得提醒你:
- 路径不要有中文。我吃过这个亏,编译报错找半天,结果是路径里有个“项目”两个字。
- 安装时勾选所有器件支持包。虽然我们只用 STM32F407,但万一以后换芯片呢?
- 注册用管理员权限运行。不然注册信息写不进去,编译到一半弹 license 错误,很烦。
2.3 STM32CubeMX 配置与工程生成
CubeMX 这东西,说白了就是个代码生成器。你点点鼠标,它帮你把 HAL 库的初始化代码全写好。省下的时间,用来调 PID 不香吗?
咱们的配置流程,我画了张图,你跟着走就行:
2.4 关键外设配置详解
这里我重点讲三个外设,电机控制离不开它们。
2.4.1 时钟配置(RCC)
F407 最高能跑 168MHz。怎么配?HSE 外部 8MHz 晶振,通过 PLL 倍频到 168MHz。我建议你直接用 CubeMX 的 Clock Configuration 页面,拖拽滑块就行。别手动算分频系数,容易算错。
2.4.2 定时器配置(TIM)
电机控制里,定时器干两件事:
- 产生 PWM 波:驱动电机。用 TIM1 或 TIM8,它们是高级定时器,支持互补输出和死区插入。
- 编码器接口:读取电机转速。用 TIM2~TIM5,它们支持编码器模式。
配置时,预分频器(PSC)和自动重装载值(ARR)决定了 PWM 频率。公式很简单:
PWM频率 = 定时器时钟 / (PSC + 1) / (ARR + 1)
比如 APB2 是 84MHz,想要 20kHz 的 PWM,PSC=0,ARR=4199。算出来刚好 20kHz。
2.4.3 串口配置(USART)
串口用来打印调试信息。PID 调参时,你要看当前转速、目标值、误差,全靠它。我习惯用 USART1,PA9(TX) 和 PA10(RX),波特率 115200。
2.5 HAL 库工程模板建立
CubeMX 生成代码后,你会得到一个 MDK-ARM 工程。但别急着写代码,先做几件事:
- 整理文件结构:把用户代码放到 User 文件夹,别跟 HAL 库混在一起。我习惯建一个
App/目录,放 motor.c、pid.c 这些。 - 配置调试器:Keil 里点 Project → Options for Target → Debug,选 ST-Link Debugger。然后点 Settings,把 SWD 速度调到 4MHz,下载快很多。
- 添加宏定义:在
stm32f4xx_hal_conf.h里,确保HAL_TIM_MODULE_ENABLED和HAL_UART_MODULE_ENABLED是打开的。
嗯,这里要注意。CubeMX 生成的 main.c 里有一段 /* USER CODE BEGIN */ 和 /* USER CODE END */ 的注释。你的代码一定要写在这两个注释之间。不然下次重新生成代码,你写的东西会被覆盖掉。我刚开始用 HAL 库时,没注意这个,写了一大堆初始化代码,重新生成后全没了……从那以后,我再也不敢乱放代码了。
2.6 串口打印调试实现
串口打印,说白了就是把数据从芯片里吐出来,让你看到。咱们用重定向 printf 的方式,方便。
在 usart.c 里添加这段代码:
/* USER CODE BEGIN 0 */
#include <stdio.h>
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
return ch;
}
/* USER CODE END 0 */
然后在 Keil 里勾选 "Use MicroLIB"。不然 printf 会占用大量资源,电机控制这种实时性要求高的场景,扛不住。
测试一下:
/* USER CODE BEGIN 2 */
printf("STM32F407 电机控制工程启动\r\n");
printf("系统时钟: %lu Hz\r\n", HAL_RCC_GetSysClockFreq());
/* USER CODE END 2 */
打开串口助手,波特率 115200,你应该能看到打印信息。如果没显示,先检查接线,再检查波特率。我遇到过最奇葩的问题,是串口助手用的 USB 转 TTL 模块,TX 和 RX 接反了……
2.7 工程验证清单
环境搭完,别急着往下走。花 5 分钟验证一下:
| 检查项 | 预期结果 | 如果不对怎么办 |
|---|---|---|
| 编译无错误 | 0 Error, 0 Warning | 检查 Pack 版本、路径 |
| 下载成功 | Flash Download Finished | 检查调试器驱动、接线 |
| 串口打印 | 看到系统时钟信息 | 检查波特率、TX/RX 是否接反 |
| LED 闪烁 | 板载 LED 以 1Hz 闪烁 | 检查 GPIO 配置、时钟使能 |
核心要点: 环境搭建不是一次性的。每加一个新外设,都要重新确认工程配置是否正确。尤其是时钟树,改一次就要验证一次。我见过有人改了时钟忘了改定时器分频,电机转得忽快忽慢,还以为是 PID 参数没调好……