读取STM32定时器值
Reading STM32 timer value
我正在使用 STM32F103 芯片,我正在尝试配置和使用其中一个定时器。我使用 STM32CubeMX 生成初始化定时器 2 的代码。我通过调用 HAL_TIM_Base_Start 启动定时器。然后,在一个循环中,我通过调用 htim2.Instance->CNT 打印出当前计时器值,或者通过调用宏 __HAL_TIM_GetCounter(我相信这只是 returns 相同的值).但是,无论我做什么,计数值都显示为零。我也试过在开始时调用 __TIM2_CLK_ENABLE() ,但没有任何区别。
我已经搜索了解决方案并找到了关于此问题的几个问题,但没有找到解决方案。
有谁知道我做错了什么吗?
谢谢。
下面是初始化定时器的例程。此代码由STM32CubeMX生成,本人未修改:
/* TIM2 init function */
static void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
然后我主要尝试启动计时器并尝试打印出它的值。这是我用来执行此操作的代码:
__TIM2_CLK_ENABLE();;
HAL_TIM_Base_Start(&htim2);
while (true)
{
Serial.println((long) __HAL_TIM_GetCounter(&htim2));
delay(100);
}
'Serial'class是我写的class,通过USB串口与我的PC通信。
不用HAL试试,不复杂
void start_TIM2() {
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 |= TIM_CR1_EN;
}
uint16_t read_TIM2() {
return TIM2->CNT;
}
设置值
htim2.Init.Period = 0;
零初始化自动重载寄存器 (ARR) 不是 cubeMX 的一个非常方便的默认选择,您可能需要 0xFFFFFFFF
的 ARR 值
采纳的答案是0xFFFFFFFF
复位后的ARR值,不提,问我是运气多于智慧
ARR (htim2.Init.Period) 不应为 0。它将尝试计数直到...0!将一些 16 位整数放在那里。祝你好运!
我将向您展示一些要记住的公式:(参考:AN4776)
. Frequency = Fclk(timer) / (prescaler + 1)
比如你选择了prescaler = 0,表示你的定时器在1 / 80MHz的周期内完成[0:count)的计数,如果SystemClock是这样配置的(你应该检查时钟和预分频器来确定更新频率)。
. #1_count(s) = 1 / Frequency
. period(s) = #1_count * (counter + 1)
--> 举个例子来看:
SystemClock = 72MHz,需要 1us 分辨率定时器和 1ms 周期。
。对于 1us 的分辨率 -> 频率 = 1Mhz
'1MHz = 72MHz / (prescaler + 1)' -> prescaler = 71
。为了让定时器每隔一毫秒中断一次,我们必须计算它应该计数多少:
'1ms = 1us * (counter + 1)' -> count = 999
使用这些值,我们配置如下:
htim2.Init.Prescaler = 71;
htim2.Init.Period = 999;
定时器将从 0 开始计数:999,步长为 1uS。
你的代码有两个问题,定时器频率太高,而且它只从0:1开始计数,所以你永远看不到计数的增加。
我正在使用 STM32F103 芯片,我正在尝试配置和使用其中一个定时器。我使用 STM32CubeMX 生成初始化定时器 2 的代码。我通过调用 HAL_TIM_Base_Start 启动定时器。然后,在一个循环中,我通过调用 htim2.Instance->CNT 打印出当前计时器值,或者通过调用宏 __HAL_TIM_GetCounter(我相信这只是 returns 相同的值).但是,无论我做什么,计数值都显示为零。我也试过在开始时调用 __TIM2_CLK_ENABLE() ,但没有任何区别。
我已经搜索了解决方案并找到了关于此问题的几个问题,但没有找到解决方案。
有谁知道我做错了什么吗?
谢谢。
下面是初始化定时器的例程。此代码由STM32CubeMX生成,本人未修改:
/* TIM2 init function */
static void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
然后我主要尝试启动计时器并尝试打印出它的值。这是我用来执行此操作的代码:
__TIM2_CLK_ENABLE();;
HAL_TIM_Base_Start(&htim2);
while (true)
{
Serial.println((long) __HAL_TIM_GetCounter(&htim2));
delay(100);
}
'Serial'class是我写的class,通过USB串口与我的PC通信。
不用HAL试试,不复杂
void start_TIM2() {
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 |= TIM_CR1_EN;
}
uint16_t read_TIM2() {
return TIM2->CNT;
}
设置值
htim2.Init.Period = 0;
零初始化自动重载寄存器 (ARR) 不是 cubeMX 的一个非常方便的默认选择,您可能需要 0xFFFFFFFF
采纳的答案是0xFFFFFFFF
复位后的ARR值,不提,问我是运气多于智慧
ARR (htim2.Init.Period) 不应为 0。它将尝试计数直到...0!将一些 16 位整数放在那里。祝你好运!
我将向您展示一些要记住的公式:(参考:AN4776)
. Frequency = Fclk(timer) / (prescaler + 1)
比如你选择了prescaler = 0,表示你的定时器在1 / 80MHz的周期内完成[0:count)的计数,如果SystemClock是这样配置的(你应该检查时钟和预分频器来确定更新频率)。
. #1_count(s) = 1 / Frequency
. period(s) = #1_count * (counter + 1)
--> 举个例子来看:
SystemClock = 72MHz,需要 1us 分辨率定时器和 1ms 周期。
。对于 1us 的分辨率 -> 频率 = 1Mhz
'1MHz = 72MHz / (prescaler + 1)' -> prescaler = 71
。为了让定时器每隔一毫秒中断一次,我们必须计算它应该计数多少:
'1ms = 1us * (counter + 1)' -> count = 999
使用这些值,我们配置如下:
htim2.Init.Prescaler = 71;
htim2.Init.Period = 999;
定时器将从 0 开始计数:999,步长为 1uS。
你的代码有两个问题,定时器频率太高,而且它只从0:1开始计数,所以你永远看不到计数的增加。