STM32 HRTIM PWM 仅在主比较 > 70ns 时工作

STM32 HRTIM PWM only work when master compare is > 70ns

STM32G474

STM32CubeIDE 1.7.0

我需要实现四个不同的 PWM 通道,它们可以以 5 度的间隔移动(例如 A = 0°,B = 5°,C = 10°,D = 180°)。 PWM 输出占空比为 50%。重要的只是通道之间的转换。

实施:

计时大师

计时器 A 到 D

主定时器比较事件将触发相应定时器(例如 A)输出为高电平,定时器 (A) 比较事件会将输出 (A) 设置为低电平。

如果所有偏移均为 8°/70ns,则输出符合预期。低于此阈值(例如 A 移动 5°)有时没有输出。似乎 A 的比较不起作用。

A(红色)2° B(蓝色)5° C(绿色)7° D(黄色)10°

  // static void MX_HRTIM1_Init(void)
  // Master Timer
  LL_HRTIM_TIM_SetPrescaler(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_PRESCALERRATIO_MUL32);
  LL_HRTIM_TIM_SetCounterMode(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_MODE_CONTINUOUS);
  LL_HRTIM_TIM_SetPeriod(HRTIM1, LL_HRTIM_TIMER_MASTER, TIMM_PERIOD);
  LL_HRTIM_TIM_SetRepetition(HRTIM1, LL_HRTIM_TIMER_MASTER, 0x00);
  LL_HRTIM_TIM_DisableHalfMode(HRTIM1, LL_HRTIM_TIMER_MASTER);
  LL_HRTIM_TIM_SetInterleavedMode(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_INTERLEAVED_MODE_DISABLED);
  LL_HRTIM_TIM_DisableStartOnSync(HRTIM1, LL_HRTIM_TIMER_MASTER);
  LL_HRTIM_TIM_DisableResetOnSync(HRTIM1, LL_HRTIM_TIMER_MASTER);
  LL_HRTIM_TIM_SetDACTrig(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_DACTRIG_NONE);
  LL_HRTIM_TIM_DisablePreload(HRTIM1, LL_HRTIM_TIMER_MASTER);
  LL_HRTIM_TIM_SetUpdateGating(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_UPDATEGATING_INDEPENDENT);
  LL_HRTIM_TIM_SetUpdateTrig(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_UPDATETRIG_NONE);
  LL_HRTIM_TIM_SetBurstModeOption(HRTIM1, LL_HRTIM_TIMER_MASTER, LL_HRTIM_BURSTMODE_MAINTAINCLOCK);
  LL_HRTIM_ForceUpdate(HRTIM1, LL_HRTIM_TIMER_MASTER);
  LL_HRTIM_TIM_SetCompare1(HRTIM1, LL_HRTIM_TIMER_MASTER, TIMM_Compare1);
  LL_HRTIM_TIM_SetCompare2(HRTIM1, LL_HRTIM_TIMER_MASTER, TIMM_Compare2);
  LL_HRTIM_TIM_SetCompare3(HRTIM1, LL_HRTIM_TIMER_MASTER, TIMM_Compare3);
  LL_HRTIM_TIM_SetCompare4(HRTIM1, LL_HRTIM_TIMER_MASTER, TIMM_Compare4);

  // Timer A
  LL_HRTIM_TIM_SetPrescaler(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_PRESCALERRATIO_MUL32);
  LL_HRTIM_TIM_SetCounterMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_MODE_CONTINUOUS);
  LL_HRTIM_TIM_SetPeriod(HRTIM1, LL_HRTIM_TIMER_A, TIMM_PERIOD);
  LL_HRTIM_TIM_SetRepetition(HRTIM1, LL_HRTIM_TIMER_A, 0x00);
  LL_HRTIM_TIM_SetUpdateGating(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_UPDATEGATING_INDEPENDENT);
  LL_HRTIM_TIM_SetCountingMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_COUNTING_MODE_UP);
  LL_HRTIM_TIM_SetComp1Mode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_GTCMP1_GREATER);
  LL_HRTIM_TIM_SetDACTrig(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_DACTRIG_NONE);
  LL_HRTIM_TIM_DisableHalfMode(HRTIM1, LL_HRTIM_TIMER_A);
  LL_HRTIM_TIM_SetInterleavedMode(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_INTERLEAVED_MODE_DISABLED);
  LL_HRTIM_TIM_DisableStartOnSync(HRTIM1, LL_HRTIM_TIMER_A);
  LL_HRTIM_TIM_DisableResetOnSync(HRTIM1, LL_HRTIM_TIMER_A);
  LL_HRTIM_TIM_DisablePreload(HRTIM1, LL_HRTIM_TIMER_A);
  LL_HRTIM_TIM_DisableResyncUpdate(HRTIM1, LL_HRTIM_TIMER_A);
  LL_HRTIM_TIM_SetUpdateTrig(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_UPDATETRIG_NONE|LL_HRTIM_UPDATETRIG_NONE);
  LL_HRTIM_TIM_SetResetTrig(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_RESETTRIG_NONE);
  LL_HRTIM_TIM_DisablePushPullMode(HRTIM1, LL_HRTIM_TIMER_A);
  LL_HRTIM_TIM_DisableDeadTime(HRTIM1, LL_HRTIM_TIMER_A);
  LL_HRTIM_TIM_SetBurstModeOption(HRTIM1, LL_HRTIM_TIMER_A, LL_HRTIM_BURSTMODE_MAINTAINCLOCK);
  LL_HRTIM_ForceUpdate(HRTIM1, LL_HRTIM_TIMER_A);
  LL_HRTIM_TIM_SetCompare1(HRTIM1, LL_HRTIM_TIMER_A, TIMA_Compare1);
  LL_HRTIM_OUT_SetPolarity(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_POSITIVE_POLARITY);
  LL_HRTIM_OUT_SetOutputSetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTSET_MASTERCMP1);
  LL_HRTIM_OUT_SetOutputResetSrc(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUTPUTRESET_TIMCMP1);
  LL_HRTIM_OUT_SetIdleMode(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_NO_IDLE);
  LL_HRTIM_OUT_SetIdleLevel(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_IDLELEVEL_INACTIVE);
  LL_HRTIM_OUT_SetFaultState(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_FAULTSTATE_NO_ACTION);
  LL_HRTIM_OUT_SetChopperMode(HRTIM1, LL_HRTIM_OUTPUT_TA1, LL_HRTIM_OUT_CHOPPERMODE_DISABLED);

  // Timer B
  // Timer C
  // Timer D

2021-10-15 Added __disable_irq() to see if the problem is related to reload some register in the timers. Doesn't seem to be the case.

2021-10-15 LL_HRTIM_TIM_SetCompare1() function indicates that the compare value must be above or equal to 3 periods of the fHRTIM clock. fHRTIM is 170 MHz -> 5.88 ns. 3 x 5.88 ns = 17.65 ns This seems to be the case... 10° (which works) I can measure a delta of about 12+ ns (when the 0° occasionally works)

更新了上面的问题,我想我找到了问题。

查看LL_HRTIM_TIM_SetCompare1()函数的代码,说明比较值必须大于或等于fHRTIM时钟的3个周期。

fHRTIM is 170 MHz -> 5.88 ns. 3 x 5.88 ns = 17.65 ns

这似乎是这种情况...10°(有效)我​​可以测量大约 12+ ns 的增量时间(当 0° 偶尔有效时)

/**
  * @brief  Set the compare value of the compare unit 1.
  * @rmtoll MCMP1R      MCMP1       LL_HRTIM_TIM_SetCompare1\n
  *         CMP1xR      CMP1x       LL_HRTIM_TIM_SetCompare1
  * @param  HRTIMx High Resolution Timer instance
  * @param  Timer This parameter can be one of the following values:
  *         @arg @ref LL_HRTIM_TIMER_MASTER
  *         @arg @ref LL_HRTIM_TIMER_A
  *         @arg @ref LL_HRTIM_TIMER_B
  *         @arg @ref LL_HRTIM_TIMER_C
  *         @arg @ref LL_HRTIM_TIMER_D
  *         @arg @ref LL_HRTIM_TIMER_E
  *         @arg @ref LL_HRTIM_TIMER_F
  * @param  CompareValue Compare value must be above or equal to 3
  *         periods of the fHRTIM clock, that is 0x60 if CKPSC[2:0] = 0,
  *         0x30 if CKPSC[2:0] = 1, 0x18 if CKPSC[2:0] = 2,...
  * @retval None
  */
__STATIC_INLINE void LL_HRTIM_TIM_SetCompare1(HRTIM_TypeDef *HRTIMx, uint32_t Timer, uint32_t CompareValue)