【问题标题】:how to read the current value of hardware timer in the STM32L1?如何读取STM32L1中硬件定时器的当前值?
【发布时间】:2020-10-09 14:29:08
【问题描述】:

我正在尝试使用硬件计时器实现两个独立的任务。 我需要任务 1 每 100us 重复一次,另一个重复 10us。我从 STM32cubemx 生成了代码。 定时器功能如下

static void MX_TIM2_Init(void) {
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 100;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 800;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK) {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) {
    Error_Handler();
  }
}

我正在进一步处理如下功能:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim-> Instance == TIM2)
    {
        ledBlueBlink();
    }
}

我有一个任务 ledGreenBlink() 应该在每 10 次任务 ledBlueBlink() 运行后运行。 谁能告诉我如何实现这个?

【问题讨论】:

  • APB总线频率是多少?
  • 频率为 32MHz。
  • 这是 XY 问题的经典示例:您需要以时间间隔的整数比运行两个任务,您可以通过计算计时器中断而不是读取硬件计时器子区间。
  • 每 10us/100us 需要做什么?因为 10us 是一个非常短的时间来完成很多工作 - 这是运行在 32MHz 的 RTOS 的上下文切换的数量级你确定你的时间吗?如果“任务”是 LED 闪烁,您将不会察觉到任何闪烁速度。最好只解释 what 你想做什么,然后让别人告诉你 如何 去做,因为看起来你把这件事复杂化了。

标签: c assembly arm embedded stm32


【解决方案1】:

不确定措辞,如果您真的在寻找任务,因为我没有看到任务“ledBlueBlink()”。

如果您只想在回调的每十次调用中调用一次“ledGreenBlink()”,我建议您只需添加一个计数器变量并每十次触发一次。

static unsigned counter = 0;
if (counter%10)
    ledGreenBlink();

counter++; 

请注意,计数器变量需要是静态的,以便在多次调用回调时保持其值。 此外,它应该是无符号类型,以便在达到最大值时安全翻转。

如果你真的需要任务,你可能想澄清你的代码来支持这个问题。

【讨论】:

  • 您好,任务需要根据定时器值进行切换。目前的任务只是名称缘故“闪烁的 LED”。任务中没有什么事情发生——只是 LED 闪烁。我实际上正在寻找一个可以读取计时器值的解决方案,如果我可以读取计时器值 - 在任务之间切换会更容易并且更兼容未来的开发,有什么想法吗?
  • @Gaurav - 你的方法是错误的。这个答案是你如何实际解决这些问题的方向,实际上它是一个小协作调度程序,它使用最不常见的多个时间间隔来调度频繁和不太频繁的任务。不过,我可能会选择除模运算符以外的其他东西进行测试。
  • 我同意@ChrisStratton 的观点,最常见的方法是让您自己获得所需频率最快的触发器,然后再推导出其他频率。在我的观点中,仅计算回调的调用或实现真正的调度程序是一个设计问题。我认为重要的部分是,您可能不想直接干扰计时器。原因是,直接处理寄存器值会产生一些需要考虑的额外问题。除特殊情况外,您只需使用回调并从那里计算所有内容即可避免这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
相关资源
最近更新 更多