STM32单片机示例:多个定时器级联使用

文章目录

  • 目的
  • 基础说明
  • 关键配置与代码
  • 示例链接

目的

有些情况下会遇到单片机的定时器位数不够用,这时候可以使用低定时器级联的方式来处理,这里将对此做个示例说明。

基础说明

这里说的定时器级联是指一个定时器正常计数工作,然后在发生溢出时发送一个时钟信号,这个时钟信号作为另一个定时器的时钟源。这样相当前一个定时器可以表达低数据,后一个定时器可以表达高数据。

定时器之间级联是有一定限制的,不是随便哪个定时器之间都可以随便触发的。对于哪个TIM可以被哪个TIM触发,ITRx是多少可以参考芯片参考手册的 TIMx internal trigger connection (TIMx 内部触发连接) 表格:
STM32单片机示例:多个定时器级联使用_第1张图片

在下面演示中将使用TIM2作为主定时器,使用TIM4作为从定时器。

关键配置与代码

STM32单片机示例:多个定时器级联使用_第2张图片
STM32单片机示例:多个定时器级联使用_第3张图片

除了配置生成的代码,需要手动添加的代码就几行(LL库):

int main(void)
{
  LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_SYSCFG);
  NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
  NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),15, 0));
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM4_Init();

  LL_TIM_EnableCounter(TIM4); // 使能TIM4开始计数(高数据)
  LL_TIM_EnableCounter(TIM2); // 使能TIM2开始计数(低数据)
  // TIM2设置1us计数一次,TIM2计数溢出时TIM4计数一次

  uint64_t pred = 0;
  while (1)
  {
      uint64_t d; // 用于保存当前时间
      uint32_t du = LL_TIM_GetCounter(TIM4); // 读取时间高数据
      uint32_t dl = LL_TIM_GetCounter(TIM2); // 读取时间低数据

      if (du == LL_TIM_GetCounter(TIM4)) // 和前次读取高数据相同, 表明低数据并未发生溢出
      {
          d = ((uint64_t)du * 4096) + dl;
      }
      else // 和前次读取高数据不同, 表明低数据发生溢出
      {
          d = ((uint64_t)LL_TIM_GetCounter(TIM4) * 4096) + LL_TIM_GetCounter(TIM2);
      }

      // 每1000us翻转一次IO输出用作验证
      if ((d - pred) > 1000)
      {
          pred = d;                                // 保存当前时间
          LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_4); // 翻转IO口
      }
  }
}

示例链接

仓库地址: https://github.com/NaisuXu/STM32_MCU_Examples

本示例为仓库中 TIM_Concatenation_LL_H750

你可能感兴趣的:(RTOS与单片机相关,嵌入式,单片机,MCU,定时器,高精度)