第二章 开发环境搭建:Keil/STM32CubeIDE安装、工程模板创建、GPIO与PWM外设初始化
好,咱们正式开始动手了。这一章,说白了就是磨刀。刀磨快了,后面砍柴才不费劲。我见过不少新手,上来就急着写算法,结果环境没配好,一个编译错误卡半天,心态直接崩了。咱们别干那傻事。
2.1 开发工具的选择:Keil还是STM32CubeIDE?
这个问题,几乎每个初学者都会问。我的答案是:两个都要会,但初期建议从STM32CubeIDE入手。
为什么?因为STM32CubeIDE是ST官方出的,免费,而且集成了CubeMX图形化配置工具。你想想看,配置时钟树、GPIO、定时器这些,点点鼠标就能生成初始化代码,多省心。我个人习惯用CubeIDE做项目的前期配置和调试,效率确实高。
那Keil呢?Keil MDK是老牌工具,生态成熟,很多企业项目都在用。但它是收费的,虽然有代码大小限制的免费版(32KB),做咱们这个按摩仪项目也够用。不过,我建议你直接上STM32CubeIDE,省去破解的麻烦。
2.2 安装STM32CubeIDE(手把手版)
安装过程其实没啥技术含量,但有几个坑我得提前跟你说。
- 去官网下载: 搜索“STM32CubeIDE”,找到ST官网的下载页面。别去第三方网站下,容易中招。
- 版本选择: 下载最新稳定版就行。我当时装的是1.13.0,现在可能更新了,无所谓。
- 安装路径: 路径不要有中文!不要有空格!我见过有人装在“D:\软件\STM32CubeIDE”,结果编译报错,查了半天是路径问题。老老实实用英文路径。
- 安装组件: 安装过程中会提示你选择要支持的芯片系列。咱们做按摩仪,用STM32F103系列,所以把F1系列勾上就行。其他的暂时用不到,以后需要再装。
2.3 创建你的第一个工程模板
安装好了,咱们来建个工程。这一步很关键,因为后面所有章节的代码,都会基于这个模板。
打开STM32CubeIDE,点击 File > New > STM32 Project。在芯片选择界面,输入“STM32F103C8T6”,选中它,点Next。给工程起个名字,比如“MassageChair_MotorCtrl”,点Finish。
这时候,CubeMX的图形化界面就打开了。你会看到一个芯片的引脚图。别慌,咱们一步步来。
2.3.1 配置时钟树(RCC)
时钟是芯片的心脏。配置不对,外设跑不起来。咱们按摩仪电机控制,需要比较精准的PWM波形,所以时钟要配好。
- 在
Pinout & Configuration标签页,找到RCC,把High Speed Clock (HSE)设置为Crystal/Ceramic Resonator。咱们板子上一般有个8MHz的晶振。 - 切换到
Clock Configuration标签页。这里就是时钟树了。把HSE设为8MHz,然后配置PLL,让系统时钟SYSCLK跑到72MHz。具体操作:在HCLK输入框里输入72,回车,软件会自动帮你算好分频系数。
2.3.2 配置GPIO
GPIO就是芯片的引脚。咱们按摩仪需要控制电机,那肯定要输出PWM信号。我习惯用定时器的PWM输出功能,这样不占CPU。
假设咱们用定时器TIM2的通道1输出PWM,对应的引脚是PA0。在引脚图上找到PA0,右键,选择 TIM2_CH1。然后,在左侧的 Timers 菜单里,找到 TIM2,把 Channel1 设置为 PWM Generation CH1。
嗯,这里要注意,GPIO的模式要配成 Alternate Function Push-Pull(复用推挽输出),速度选 High。这样PWM信号才能快速翻转。
2.3.3 配置PWM参数
PWM有两个关键参数:频率和占空比。频率决定了电机转动的细腻程度,占空比决定了电机的速度。
在TIM2的 Parameter Settings 里,咱们来算一下:
- Prescaler (PSC): 预分频器。假设咱们想要PWM频率为20kHz(20,000Hz),那么PSC+1 = 72MHz / (20,000 * (ARR+1))。咱们先设PSC=71,也就是72分频,那么定时器时钟就变成了1MHz。
- Counter Period (ARR): 自动重装载值。ARR+1 = 1MHz / 20kHz = 50。所以ARR=49。
- Pulse: 这就是占空比了。比如设成25,那么占空比就是25/50 = 50%。
你看,算起来很简单。我刚开始学的时候,总是搞混PSC和ARR的关系。后来我总结了一句话:PSC决定计数速度,ARR决定计数范围。你想想看,是不是这个理?
// 代码示例:PWM初始化(由CubeMX自动生成,但你要理解)
// 这段代码在 tim.c 里
void MX_TIM2_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71; // 72分频,定时器时钟1MHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 49; // ARR=49,PWM频率20kHz
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 25; // 初始占空比50%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
2.4 生成代码并验证
配置完成后,点击工具栏上的小锤子图标(Generate Code)。CubeMX会自动帮你生成初始化代码。然后,在 main.c 的 main() 函数里,加上启动PWM的代码:
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
编译,下载到板子里。用示波器或者逻辑分析仪量一下PA0引脚,你应该能看到一个20kHz的方波。如果没有,检查一下时钟配置和GPIO模式。
2.5 本章小结
这一章,咱们把开发环境搭好了,也生成了第一个PWM工程模板。你可能会觉得,这不就是点点鼠标吗?没错,但关键是你要理解每一步背后的原理。时钟怎么配的?PWM频率怎么算的?这些基础打牢了,后面写FOC算法、PID控制,你才不会发懵。
下一章,咱们就要开始写真正的电机控制代码了。到时候,这个模板就是咱们的起点。