[STM32WBA]【STM32WBA52CG测评】-4- 定时器模块TIM例程分析

ST的官方库有非常丰富的外设使用例程,本文体验的就是:STM32Cube_FW_WBA_V1.1.0\Projects\NUCLEO-WBA52CG\Examples\TIM\TIM_TimeBase
该例程配置使用TIM模块产生一个1s的中断,然后再中断服务函数中翻转LED。

初始化外设,Flash和Systick:
复制
HAL_Init();


SystemClock_Config() 函数用于配置STM32WBA52CGUx 设备系统时钟为100 MHz
复制
  /* Configure the system clock */

  SystemClock_Config();

根据官方ReadMe,TIM模块的时钟频率,TIM2模块的计数器时钟频率,以及周期都有相应的公式:


In this example TIM2 input clock (TIM2CLK)  is set to APB1 clock (PCLK1),since APB1 prescaler is equal to 1.  TIM2CLK = PCLK1  PCLK1 = HCLK  => TIM2CLK = HCLK = SystemCoreClockTo get TIM2 counter clock at 10 KHz, the Prescaler is computed as following:Prescaler = (TIM2CLK / TIM2 counter clock) - 1Prescaler = (SystemCoreClock /10 KHz) - 1
SystemCoreClock is set to 100 MHz for STM32WBAxx Devices.
The TIM2 ARR register value is equal to 10000 - 1
Update rate = TIM2 counter clock / (Period + 1) = 1 Hz
So the TIM2 generates an interrupt each 1 s
When the counter value reaches the auto-reload register value, the TIM update interrupt is generated and, in the handler routine, pin PB.4 (connected to LD1 on board NUCLEO-WBA52CG) is toggled. So led blinks at the following frequency: 0.5Hz.
In case of error, LD3 is turned ON.在main.h中,有相应的参数定义:
 

/* Compute the prescaler value to have TIMx counter clock equal to 10000 Hz */

#define PRESCALER_VALUE (uint32_t)(((SystemCoreClock) / (10000)) - 1)

  /* Initialize TIMx peripheral as follows:

       + Period = 10000 - 1

       + Prescaler = (SystemCoreClock/10000) - 1

       + ClockDivision = 0

       + Counter direction = Up

  */

#define PERIOD_VALUE (10000 - 1);


在main.c中,调用如下函数进行TIM模块初始化:
 

/**

  * [url=home.php?mod=space&uid=247401]@brief[/url] TIM2 Initialization Function

  * @param None

  * @retval None

  */

static void MX_TIM2_Init(void)

{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */

  htim2.Instance = TIM2;

  htim2.Init.Prescaler = PRESCALER_VALUE;

  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim2.Init.Period = PERIOD_VALUE;

  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();

  }

  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

如下定义了TIM2模块的中断服务子程序:
 

/**

  * [url=home.php?mod=space&uid=247401]@brief[/url] This function handles TIM2 global interrupt.

  */

void TIM2_IRQHandler(void)

{

  /* USER CODE BEGIN TIM2_IRQn 0 */

  /* USER CODE END TIM2_IRQn 0 */

  HAL_TIM_IRQHandler(&htim2);

  /* USER CODE BEGIN TIM2_IRQn 1 */

  /* USER CODE END TIM2_IRQn 1 */

}

接着调用HAL库中的中断服务子程序:
 

void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)

{

  uint32_t itsource = htim->Instance->DIER;

  uint32_t itflag   = htim->Instance->SR;

  /* Capture compare 1 event */

  if ((itflag & (TIM_FLAG_CC1)) == (TIM_FLAG_CC1))

  {

    if ((itsource & (TIM_IT_CC1)) == (TIM_IT_CC1))

    {

      {

        __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);

        htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;

        /* Input capture event */

        if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)

        {

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

          htim->IC_CaptureCallback(htim);

#else

          HAL_TIM_IC_CaptureCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

        }

        /* Output compare event */

        else

        {

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

          htim->OC_DelayElapsedCallback(htim);

          htim->PWM_PulseFinishedCallback(htim);

#else

          HAL_TIM_OC_DelayElapsedCallback(htim);

          HAL_TIM_PWM_PulseFinishedCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

        }

        htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;

      }

    }

  }

  /* Capture compare 2 event */

  if ((itflag & (TIM_FLAG_CC2)) == (TIM_FLAG_CC2))

  {

    if ((itsource & (TIM_IT_CC2)) == (TIM_IT_CC2))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);

      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;

      /* Input capture event */

      if ((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)

      {

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

        htim->IC_CaptureCallback(htim);

#else

        HAL_TIM_IC_CaptureCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

      }

      /* Output compare event */

      else

      {

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

        htim->OC_DelayElapsedCallback(htim);

        htim->PWM_PulseFinishedCallback(htim);

#else

        HAL_TIM_OC_DelayElapsedCallback(htim);

        HAL_TIM_PWM_PulseFinishedCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

      }

      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;

    }

  }

  /* Capture compare 3 event */

  if ((itflag & (TIM_FLAG_CC3)) == (TIM_FLAG_CC3))

  {

    if ((itsource & (TIM_IT_CC3)) == (TIM_IT_CC3))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);

      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;

      /* Input capture event */

      if ((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)

      {

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

        htim->IC_CaptureCallback(htim);

#else

        HAL_TIM_IC_CaptureCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

      }

      /* Output compare event */

      else

      {

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

        htim->OC_DelayElapsedCallback(htim);

        htim->PWM_PulseFinishedCallback(htim);

#else

        HAL_TIM_OC_DelayElapsedCallback(htim);

        HAL_TIM_PWM_PulseFinishedCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

      }

      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;

    }

  }

  /* Capture compare 4 event */

  if ((itflag & (TIM_FLAG_CC4)) == (TIM_FLAG_CC4))

  {

    if ((itsource & (TIM_IT_CC4)) == (TIM_IT_CC4))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);

      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;

      /* Input capture event */

      if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)

      {

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

        htim->IC_CaptureCallback(htim);

#else

        HAL_TIM_IC_CaptureCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

      }

      /* Output compare event */

      else

      {

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

        htim->OC_DelayElapsedCallback(htim);

        htim->PWM_PulseFinishedCallback(htim);

#else

        HAL_TIM_OC_DelayElapsedCallback(htim);

        HAL_TIM_PWM_PulseFinishedCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

      }

      htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;

    }

  }

  /* TIM Update event */

  if ((itflag & (TIM_FLAG_UPDATE)) == (TIM_FLAG_UPDATE))

  {

    if ((itsource & (TIM_IT_UPDATE)) == (TIM_IT_UPDATE))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->PeriodElapsedCallback(htim);

#else

      HAL_TIM_PeriodElapsedCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

  /* TIM Break input event */

  if ((itflag & (TIM_FLAG_BREAK)) == (TIM_FLAG_BREAK))

  {

    if ((itsource & (TIM_IT_BREAK)) == (TIM_IT_BREAK))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->BreakCallback(htim);

#else

      HAL_TIMEx_BreakCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

  /* TIM Break2 input event */

  if ((itflag & (TIM_FLAG_BREAK2)) == (TIM_FLAG_BREAK2))

  {

    if ((itsource & (TIM_IT_BREAK)) == (TIM_IT_BREAK))

    {

      __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_BREAK2);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->Break2Callback(htim);

#else

      HAL_TIMEx_Break2Callback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

  /* TIM Trigger detection event */

  if ((itflag & (TIM_FLAG_TRIGGER)) == (TIM_FLAG_TRIGGER))

  {

    if ((itsource & (TIM_IT_TRIGGER)) == (TIM_IT_TRIGGER))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->TriggerCallback(htim);

#else

      HAL_TIM_TriggerCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

  /* TIM commutation event */

  if ((itflag & (TIM_FLAG_COM)) == (TIM_FLAG_COM))

  {

    if ((itsource & (TIM_IT_COM)) == (TIM_IT_COM))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->CommutationCallback(htim);

#else

      HAL_TIMEx_CommutCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

  /* TIM Encoder index event */

  if ((itflag & (TIM_FLAG_IDX)) == (TIM_FLAG_IDX))

  {

    if ((itsource & (TIM_IT_IDX)) == (TIM_IT_IDX))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_IDX);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->EncoderIndexCallback(htim);

#else

      HAL_TIMEx_EncoderIndexCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

  /* TIM Direction change event */

  if ((itflag & (TIM_FLAG_DIR)) == (TIM_FLAG_DIR))

  {

    if ((itsource & (TIM_IT_DIR)) == (TIM_IT_DIR))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_DIR);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->DirectionChangeCallback(htim);

#else

      HAL_TIMEx_DirectionChangeCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

  /* TIM Index error event */

  if ((itflag & (TIM_FLAG_IERR)) == (TIM_FLAG_IERR))

  {

    if ((itsource & (TIM_IT_IERR)) == (TIM_IT_IERR))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_IERR);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->IndexErrorCallback(htim);

#else

      HAL_TIMEx_IndexErrorCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

  /* TIM Transition error event */

  if ((itflag & (TIM_FLAG_TERR)) == (TIM_FLAG_TERR))

  {

    if ((itsource & (TIM_IT_TERR)) == (TIM_IT_TERR))

    {

      __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_TERR);

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)

      htim->TransitionErrorCallback(htim);

#else

      HAL_TIMEx_TransitionErrorCallback(htim);

#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */

    }

  }

}

注意其中有个函数调用:

HAL_TIM_PeriodElapsedCallback(htim);

这个回调函数的定义如下:

/**

  * [url=home.php?mod=space&uid=247401]@brief[/url]  Period elapsed callback in non blocking mode

  * @param  htim : TIM handle

  * @retval None

  */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

        BSP_LED_Toggle(LD1);

}


烧录后,可以看到LD1以1s频率闪烁。

---------------------
作者:南来之风
链接:https://bbs.21ic.com/icview-3318482-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值