进阶篇 VI [Timer & PWM]
项目&教程仓库:-STM32-RoboMaster-
1.0 什么是Timer?PWM又是什么玩意儿?
1.1 Timer定义
Timer就是定时器,但是与一般我们生活中使用的定时器不同的是,Timer的单位不是s秒,而是Hz赫兹,而且通常是MHz(1,000,000Hz),定时器通常从0开始数数,然后直到占满其16位寄存器,就会告诉CPU,“我已经满得不行了~~”,然后从0开始重新计数。
Timer具体的频率多少通常取决于,其Clock Source,Prescaler,和Period
$$Frequency\ =\ \frac{Clock\ Source}{(Prescaler+1)(Period+1)}$$
这里值得注意的是,虽然Prescaler和Period都可以降频,但是根据笔者实测,两者是不一样的,Prescaler会改变PWM信号的密度,所以不推荐过大的Prescaler,而Period会改变PWM信号的Resolution清晰度/分辨率,过小会导致能选择的Duty Cycle占空比过少,所以不推荐过小的Period。但是具体怎么平衡选择,其实还是需要看你的需求和设备。
如果是高级定时器,还需要考虑Repetition Counter ( RC )
$$Frequency\ =\ \frac{Clock\ Source}{(Prescaler+1)(Period+1)(RC+1)}$$
定时器分为
Basic Timer
- TIM6
- TIM7
General Purpose Timer
- TIM2到TIM5
- TIM9到TIM14
Advanced Timer
TIM1
TIM8
SysTick Timer
因为RoboMaster暂时只用得上Basic Timer和General Purpose Timer,其他Timer都暂时不讲。在RM中,Basic Timer用于计时,General Purpose Timer用于生成PWM,虽然也可以当成普通的Basic Timer来用。
所有Timer的时钟源分布图
在无法确认某个Timer的时钟源在Clock Tree中的位置时,请参考上图!
1.2 PWM定义
PWM ( Pulse Width Modulation ) 脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。PWM控制技术在逆变电路中应用最广,应用的逆变电路绝大部分是PWM型,PWM控制技术正是有赖于在逆变电路中的应用,才确定了它在电力电子技术中的重要地位。PWM能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量通信到功率控制与变换的许多领域中。
最基础最本质的概念:Duty Cycle 占空比
$$D\ =\ \frac{T_{on}}{Period}\times100%$$
$$Period\ =\ T_{on}+T_{off}$$
PWM这项技术的本质其实非常简单,“在不改变最大电压的情况下,通过改变最大电压出现的比率,来改变整体的平均电压”,而这可以顺带传递信息。
PWM通常用于控制电机,舵机,加密信息传递,电压变化控制等等
1.3 PWM的实际应用
1.3.1 呼吸灯
- 这个很好理解,毕竟越大的Duty Cycle占空比,短时间内的平均电压越大,灯也就越亮,所以控制PWM信号的Duty Cycle占空比就可以在不改变电压的情况下调控瞬时平均电压。
1.3.2 舵机控制
- 舵机通常可以用CAN或者PWM来控制,PWM是非常常见的舵机控制方式,基本上没有不支持PWM的舵机。PWM的Duty Cycle占空比的大小对应者着舵机的角度。通常频率为50Hz,如果Period为2000,$T_{on}$为50~250,Duty Cycle占空比为2.5%~12.5%,则对应着舵机的0°~180°/0°~270°。
1.3.3 电机控制
这里以RoboMaster中常见的M3508直流无刷减速电机和C620无刷电机调速器为例
- PWM信号给到C620,然后C620根据其Duty Cycle占空比来控制M3508速度
- M3508用PWM驱动,需要每次都先校验PWM,需要先给最大Duty Cycle占空比,然后在3s内给最小Duty Cycle占空比
- M3508是缓启动,也就是说,速度需要从0开始递增,而不能直接让M3508满速
- M3508能接收的频率为50Hz到500Hz,脉宽从1000us到2000us变化,推荐500Hz,Period为2000
- M3508分为两种模式
- 单向转动模式
- $V_{min}\ =\ 1000us$
- $V_{max}\ =\ 2000us$
- 双向转动模式
- $-V_{max}\ =\ 1000us$
- $V_{0}\ =\ 1500us$
- $V_{max}\ =\ 2000us$
- 单向转动模式
2.0 Timer的用法
1 |
|
- 参数
htim
:指向TIM配置结构体
- 返回值
HAL_StatusTypeDef
:如果开启成功,返回HAL_OK
1 |
|
- 参数
htim
:指向TIM配置结构体
- 返回值
HAL_StatusTypeDef
:如果停止成功,返回HAL_OK
1 |
|
- 在写代码的时候,在
main.c
中创建HAL_TIM_PeriodElapsedCallback
函数 - 在该函数中填写TIM达到预定时间后开启中断,需要执行的代码
3.0 PWM的用法
1 |
|
- 参数
htim
:指向TIM配置结构体Channel
:打开的Channel序号
- 返回值
HAL_StatusTypeDef
:如果开启成功,返回HAL_OK
1 |
|
- 参数
htim
:指向TIM配置结构体Channel
:打开的Channel序号
- 返回值
HAL_StatusTypeDef
:如果停止成功,返回HAL_OK
1 |
|
用于实时设置TIM计时器的复位值,计算公式:
$$\frac{Clock\ Freq}{Output\ Freq}\ -\ 1$$
- 参数
__HANDLE__
:指向TIM配置结构体
1 |
|
用于实时设置PWM的Duty Circle宽度值,计算公式:
$$\frac{Clock\ Freq}{Output\ Freq}\ \times\ Duty\ Circle\ -\ 1$$
- 参数
__HANDLE__
:指向TIM配置结构体__CHANNEL__
:Channel序号__COMPARE__
:新的$T_{on}$值,以此改变Duty Cycle占空比
1 |
|
- 参数
__HANDLE__
:指向TIM配置结构体__COMPARE__
:新的Timer计数器值,如果为0,也就是常见的初始化用法
4.0 练习项目
4.1 项目简介
- 彩灯:按下按键,就开始每0.5s ( 2Hz ) 改变一次所有LED灯状态(交叉点亮)。
- 呼吸灯:灯光在PWM控制电压下完成由亮到暗的逐渐变化,感觉好像是人在呼吸。
- 舵机控制:通过PWM控制舵机的位置
- 电机控制(单向转动模式):通过PWM控制电机的速度
- 电机控制(双向转动模式):通过PWM控制电机的速度
4.2 项目代码
完整的工程文件可以在这里找到!
4.2.1 彩灯
1 |
|
4.2.2 呼吸灯
1 |
|
4.2.3 舵机控制
1 |
|
4.2.4 电机控制(单向转动模式)
1 |
|
4.2.4 电机控制(双向转动模式)
1 |
|
4.3 效果展示
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!