繁体   English   中英

读取STM32定时器值

[英]Reading STM32 timer value

我正在使用 STM32F103 芯片,我正在尝试配置和使用其中一个定时器。 我已经使用 STM32CubeMX 生成初始化定时器 2 的代码。我通过调用 HAL_TIM_Base_Start 来启动定时器。 然后,在循环中,我通过调用 htim2.Instance->CNT 或通过调用宏 __HAL_TIM_GetCounter(我相信它只是返回相同的值)打印出当前计时器值。 但是,无论我做什么,计数值都显示为零。 我也试过在开始时调用 __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' 类是我编写的一个类,它通过 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 

. 为了让计时器每 1 毫秒中断一次,我们必须计算它应该计数多少:

'1ms = 1us * (counter + 1)' -> count = 999

使用这些值,我们配置以下内容:

htim2.Init.Prescaler = 71;

htim2.Init.Period = 999;

其中计时器将从 0: 999 以 1uS 的步长计数。

你的代码有两个问题,定时器频率太高,它只从 0:1 开始计数,所以你永远看不到计数的增加。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM