STM32F4 定时器 - 预分频器或周期值必须除以二才能得到我期望的结果

Posted

技术标签:

【中文标题】STM32F4 定时器 - 预分频器或周期值必须除以二才能得到我期望的结果【英文标题】:STM32F4 Timers - Prescaler or period value must be divided by two to get what I expect 【发布时间】:2021-12-03 12:52:03 【问题描述】:

我正在研究 STM32F4,我注意到 Timers 有一些奇怪的行为。

我需要三个定时器:第一个必须每 1ms 产生一个中断(我选择 TIMER 1,高级控制定时器),第二个必须每 10ms 产生一个中断(TIMER2,通用中断),第三个必须其 CNT 计数器每 1µs 递增一次(因此每 65.535 ms 产生一次中断,因为我为此使用 TIMER 3 而 CNT 为 16 位)。

为了计算 PSC(预分频器)和 ARR(周期)值,我使用了 thread。所以我使用的公式是(以毫秒为单位):

Period = 1000 * (PSC+1)*(ARR+1) / TmerClockFreq

这给出了:

ARR = ((Period * TmerClockFreq) / (1000*(PSC + 1)) - 1

在我的例子中,TmerClockFreq = 168 MHz = 168 x 10^6 Hz

对于 TIMER1,一切都按预期工作。我选择了 PSC=11,它给了我 ARR=13999,相应的中断实际上是每 1 毫秒调用一次。

使用 TIMERS 2 和 3 会使事情变得复杂。

TIMER 2:我想要 Period = 10 ms。如果我取,PSC = 39,它给我 ARR = 41999。问题:使用这些参数,我的中断每 20 毫秒调用一次。 为了得到我想要的周期,我必须将 PSC 除以 2。所以 PSC = 19 和 ARR = 41999。

TIMER 3 也是如此。对于 Period=65.535 ms 和 ARR = 65535,PSC = 167(请注意,在这种情况下,计算是近似值,但我不需要非常高的精度)。但同样,中断的调用速度是我预期的两倍(大约每 131.064 毫秒)我添加到选择 PSC = 83 以使我的中断每 65.535 毫秒调用一次。

所以我的问题是:为什么我需要将 TIMER 2 和 TIMER 3 的预分频器除以 2 才能获得预期的中断周期调用?

这是我设置 TIMER 3 的方法:

/* Get clock speed */
u32_ticks = (HAL_RCC_GetHCLKFreq() / 1000000); // = 168

pst_TimerHandle->Instance = TIM3;
pst_TimerHandle->Init.Prescaler = (u32_ticks - 1) / 2;
pst_TimerHandle->Init.CounterMode = TIM_COUNTERMODE_UP;
pst_TimerHandle->Init.Period = 0xFFFF;
pst_TimerHandle->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
pst_TimerHandle->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(pst_TimerHandle) != HAL_OK)

    //error handling

st_ClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(pst_TimerHandle, &st_ClockSourceConfig) != HAL_OK)

    //error handling

st_MasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
st_MasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

这是我如何在 IRQ 处理程序中生成一些脉冲来检查中断的周期:

void TIM3_IRQHandler(void)

    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);

    HAL_TIM_IRQHandler(HAL_TIMER3_GetHandle());

Oscilloscope output for TIMER 3, ARR=0xFFFF and PSC = 167 (value computed from formula, output NOT as expected)

Oscilloscope output for TIMER 3, ARR=0xFFFF and PSC = (167 / 2) = 83 (PSC divided by 2, output as expected)

【问题讨论】:

【参考方案1】:

Timer1 是高级定时器,timer2 & 3 是通用定时器。 Timer1 来自 APB2,定时器 2,3 来自 APB1。您可以查看参考书或检查您的时钟设置以查看更多详细信息。

【讨论】:

以上是关于STM32F4 定时器 - 预分频器或周期值必须除以二才能得到我期望的结果的主要内容,如果未能解决你的问题,请参考以下文章

基于STM32F030F4P9和STM32 CUBEMX 输出PWM波形

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)

STM32F4 HAL库开发 -- 独立看门狗(IWDG)