动态改变定时器频率

Changing the timer frequency dynamically

我试图在运行时修改 pwm 计时器的频率,但我不知道 reference manual.

中描述的计数器溢出是如何触发的

在递增计数、边沿对齐模式(参考文献中的第 354 和 372 页)下,输出应为宽度恒定(恒定 TIMx_CCRx)且频率可变(TIMx_ARR)的短脉冲手动的)。 我希望能够比最小可归档输出频率更快地调整频率。

例如。滴答时间 (CK_CNT) 为 1 毫秒,最长时间为 1000 毫秒,我希望能够每 100 毫秒更新一次 ARR 值。 当新的 ARR 值高于当前计数器寄存器值时,定时器应继续向上计数。 当新的 ARR 值小于当前计数器寄存器值时,定时器应产生计数器溢出并从 0 重新启动。 为了能够每 100 毫秒更新一次自动重载寄存器,我禁用了 ARR 预加载 (ARPE=0)。

当我向ARR 寄存器写入一个小于当前计数寄存器值的值时会发生什么? 只有当新的 ARR 值大于 p.356 上的计数器值时的示例。

会不会触发计数器溢出,定时器从0开始计时? 我必须手动创建更新事件 (UEV) 吗? 如果新的 ARR 值较低,我是否必须检查计数器值并手动重新启动计时器?

我在参考手册中没有找到任何内容,但最终在实际硬件上测试了行为:

  • 将 ARR 设置为低于当前计数器值的值不会创建 interrupt/update event/etc,计时器会继续计数
  • 手动创建更新事件会自动重启计数器
  • 将 ARR 设置为当前计数器值会创建一个更新事件

我不想在将 ARR 值设置为高于计数器值时重新启动计数器。 解决方案是在 ARR 值低于计数器值时创建手动更新事件。 设置时计数器达到 ARR 应该没有问题,因为它会自动创建更新事件。

这似乎按预期工作:

void update_arr (TIM_HandleTypeDef* htim, uint16_t arr) {
    __HAL_TIM_SET_AUTORELOAD(htim, arr);
    if (__HAL_TIM_GET_COUNTER(htim) >= __HAL_TIM_GET_AUTORELOAD(htim)) {
        htim->Instance->EGR  |= TIM_EGR_UG;
    }
}