STM32 PWM 控制舵机学习记录
·
STM32 PWM 控制舵机学习记录
今天主要学习了定时器 PWM 的基本概念,以及如何用 STM32 HAL 库控制 SG90 舵机。
一、几个核心概念
1. PSC 是什么
PSC 是 预分频器。
它的作用是把定时器输入时钟先分频,再送给计数器。
可以理解成:
- 时钟跑得太快
- PSC 先把速度降下来
- CNT 才能慢慢数
2. CNT 是什么
CNT 是 计数器当前值。
它就像一个正在数数的小人:
- 从 0 开始数
- 一直数到 ARR
- 然后重新回到 0
3. ARR 是什么
ARR 是 自动重装载值。
它决定 CNT 数到多少时结束一轮计数。
也可以理解为:
- CNT 数到 ARR
- 就产生一次更新事件
- 然后重新开始数
二、PWM 的本质
PWM 就是 脉冲宽度调制。
在定时器里可以简单理解成:
- ARR 决定周期
- CCR 决定占空比
1. ARR 决定周期
PWM 信号多久重复一次,由 ARR 决定。
2. CCR 决定占空比
CCR 决定高电平持续多久,也就是脉宽。
三、PWM 控制函数
1. 开启 PWM
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
作用:开启定时器 3 的 3 通道 PWM 输出。
2. 设置比较值
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sg90_angle);
作用:设置比较寄存器 CCR 的值,也就是 PWM 的占空比。
四、PWM 控制舵机的方法步骤
第一步:开启定时器 PWM 运行
放在 /* USER CODE BEGIN 2 */ 里面:
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
第二步:设置比较寄存器的值
还是在初始化后设置初始脉宽:
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sg90_angle);
第三步:定义初始值
sg90_angle 是你当前输出的比较值,通常提前定义:
uint16_t sg90_angle = 500;
这个值就是舵机上电后的初始脉宽。
五、舵机为什么能转
SG90 舵机不是看电压大小,而是看 PWM 脉宽。
一般来说:
- 0.5 ms 左右,对应一个方向极限
- 1.5 ms 左右,对应中间位置
- 2.5 ms 左右,对应另一个方向极限
所以你改变 CCR 的值,舵机就会转到不同角度。
六、我的按键控制思路
这次的逻辑是:
- 按 K1,舵机角度增加
- 按 K2,舵机角度减小
- 每次改变后重新写入比较值
- 通过 PWM 改变舵机位置
#define SG90_MIN 500
#define SG90_MAX 2500
#define SG90_STEP 500
uint16_t sg90_angle = 500;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sg90_angle);
while (1)
{
if (HAL_GPIO_ReadPin(GPIOA, K1_Pin) == GPIO_PIN_SET)
{
if (sg90_angle + SG90_STEP <= SG90_MAX)
{
sg90_angle += SG90_STEP;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sg90_angle);
}
HAL_Delay(300);
while (HAL_GPIO_ReadPin(GPIOA, K1_Pin) == GPIO_PIN_SET);
}
if (HAL_GPIO_ReadPin(GPIOA, K2_Pin) == GPIO_PIN_SET)
{
if (sg90_angle - SG90_STEP >= SG90_MIN)
{
sg90_angle -= SG90_STEP;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sg90_angle);
}
HAL_Delay(300);
while (HAL_GPIO_ReadPin(GPIOA, K2_Pin) == GPIO_PIN_SET);
}
}
}
七、今天最重要的记忆点
1. PWM 三个关键值
PSC:分频ARR:周期CCR:占空比
2. 舵机控制本质
- 改变
CCR - 改变脉宽
- 改变舵机角度
3. 最常用的两个函数
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, sg90_angle);
八、容易写错的地方
1. 函数名不要写错
正确的是:
__HAL_TIM_SET_COMPARE
不是:
_HAL_TIM_SET_COMPARE
2. 条件判断方向要对
比如减小角度时,应该判断:
sg90_angle - SG90_STEP >= SG90_MIN
不是加号。
九、总结
今天学到的 PWM 控舵机流程可以记成一句话:
开 PWM,改 CCR,看舵机转。
以后只要记住:
PSC控速度ARR控周期CCR控脉宽- 舵机靠 PWM 脉宽定位
就能很快上手这类项目。
更多推荐



所有评论(0)