STM32F4 定时器 - 预分频器或周期值必须除以二才能得到我所期望的
STM32F4 Timers - Prescaler or period value must be divided by two to get what I expect
我正在研究 STM32F4,我注意到定时器有一些奇怪的行为。
我需要三个定时器:第一个必须每 1ms 产生一个中断(我选择 TIMER 1,一个高级控制定时器),第二个必须每 10ms 产生一个中断(TIMER2,通用中断)和第三个一个必须使其 CNT 计数器每 1µs 递增一次(因此每 65.535 毫秒产生一次中断,因为我为此使用定时器 3,而 CNT 是 16 位)。
为了计算 PSC(预分频器)和 ARR(周期)值,我使用了这个 。所以我使用的公式是(以毫秒为单位的一段时间):
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 使事情变得复杂。
定时器 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)
Timer1 是高级定时器,timer2 和 3 是通用定时器。定时器 1 来自 APB2,定时器 2,3 来自 APB1。您可以查看参考书或查看您的时钟设置以查看更多详细信息。
我正在研究 STM32F4,我注意到定时器有一些奇怪的行为。
我需要三个定时器:第一个必须每 1ms 产生一个中断(我选择 TIMER 1,一个高级控制定时器),第二个必须每 10ms 产生一个中断(TIMER2,通用中断)和第三个一个必须使其 CNT 计数器每 1µs 递增一次(因此每 65.535 毫秒产生一次中断,因为我为此使用定时器 3,而 CNT 是 16 位)。
为了计算 PSC(预分频器)和 ARR(周期)值,我使用了这个
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 使事情变得复杂。
定时器 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)
Timer1 是高级定时器,timer2 和 3 是通用定时器。定时器 1 来自 APB2,定时器 2,3 来自 APB1。您可以查看参考书或查看您的时钟设置以查看更多详细信息。