编者按:路漫漫其修远兮,吾将上下而求索。这句从小学在“日积月累”模块背下来的话,是对屈原最深刻的印象了。昨晚又看了三毛的《撒哈拉的故事》,人生的最大的感动,左不过就是在广袤的天地间看见一朵玫瑰了。编者要时常告诉自己,要在STM32和Linux之中去寻找一朵玫瑰,一朵需要屏风去呵护的玫瑰,理工科也可以有那么一些哲学和浪漫的。

(神经病编者hhhhh)

学习参考资料:
正点原子:STM32中文参考手册
Z小旋的博客:【STM32】HAL库 STM32CubeMX教程六----定时器中断
Z小璇的博客:【STM32】HAL库 STM32CubeMX教程七—PWM输出(呼吸灯)

1. 定时器中断的基本流程

  1. 首先进入中断函数 void TIM3_IRQHandler(void)
  2. 之后进入定时器中断处理函数 HAL_TIM_IRQHandler(&htim2);
  3. 判断产生的是哪一类定时器中断(溢出中断/PWM中断…) 和定时器通道
  4. 进入相对应中断回调函数 void HAL_TIM_PeriodElapsedCallback(&htim2);在中断回调函数中添加用户代码
    ————
    以上部分来自Z小璇的原创文章。

说一下自己的粗俗理解,定时器就是当开启了HAL_TIM_Base_Start_IT(&htim2);的时候,它就自己悄咪咪地开始计数,等计数到预定值溢出的时候,就向CPU发起中断,喊CPU进来它的中断函数。还是很好理解的。

所以有个重点需要注意,在CubeMX设定好定时器的种种参数之后,一定要在主函数里面加上定时器开启函数(例如HAL_TIM_Base_Start_IT(&htim2);),这时定时器才会开始真正工作。

2. PWM

“脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。”

HAL库学STM32 关于定时器的几个问题

  • ​在PWM输出模式下,除了CNT(计数器当前值)、ARR(自动重装载值)之外,还多了一个值CCRx(捕获/比较寄存器值)。
  • 当CNT小于CCRx时,TIMx_CHx通道输出低电平;
  • 当CNT等于或大于CCRx时,TIMx_CHx通道输出高电平。

​PWM的一个周期

  • 定时器从0开始向上计数 当0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
  • t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平
  • 当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数…循环此过程
    ————————————————
    版权声明:以上部分来自CSDN博主「Z小旋」的原创文章

看到这里基本就可以理解PWM的原理了。占空比和频率的计算也显得很简单了。
TIMx_ARR寄存器确定PWM频率,TIMx_CCRx寄存器确定占空比

PWM频率:
Fpwm =Tclk / ((arr+1)*(psc+1))(单位:Hz)
arr 是计数器值
psc 是预分频值

占空比:
duty circle = TIM3->CCR1 / arr(单位:%)
TIM3->CCR1 用户设定值

配置基本上也没有什么问题,有一点要注意的是,在正点原子战舰开发板上(STM32F103ZET6),定时器3的通道2可以映射到LED0也就是引脚PB5上,在开启定时器3的通道2时,默认开启的是PA7,这时需要手动选择PB5作为TIM3_CH2的输出,可以看到PA7被自动关闭。
还有,可能是HAL库版本的原因,在工程中找不到函数__HAL_TIM_SetCompare(),直接操作寄存器htim3.Instance->CCR2就可。

相关文章: