你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32L0系列之【LPTIM定时器】

[复制链接]
STMCU小助手 发布时间:2021-11-18 22:00
1.LPTIM介绍
STM32L0系列有个LPTIM定时器,即lowpowertimer,低功耗定时器
20191127140024708.png


可以看到可供LPTIM使用时钟源分为如下:
内部时钟源:LSE,LSI,HSI或APB时钟
外部时钟源:LPTIM输入的外部时钟源
ps:如果以LSE,LSI或外部时钟为时钟源时,能够从停止模式唤醒设备。

本文记录使用LSI为时钟源使用LPTIM

2.配置时钟源并且启动
  1. /**
  2.   * @brief System Clock Configuration
  3.   * @retval None
  4.   */
  5. void SystemClock_Config(void)
  6. {
  7.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  8.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  9.   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  10.   /** Configure the main internal regulator output voltage
  11.   */
  12.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  13.   /** Initializes the CPU, AHB and APB busses clocks
  14.   */
  15.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_MSI;
  16.   RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  17.   RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  18.   RCC_OscInitStruct.MSICalibrationValue = 0;
  19.   RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  20.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  21.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  22.   {
  23.     Error_Handler();
  24.   }
  25.   /** Initializes the CPU, AHB and APB busses clocks
  26.   */
  27.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  28.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  29.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  30.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  31.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  32.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  33.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  34.   {
  35.     Error_Handler();
  36.   }

  37.     PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_LPTIM1;
  38.     PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  39.     PeriphClkInit.LptimClockSelection = RCC_LPTIM1CLKSOURCE_LSI;

  40.     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  41.     {
  42.     Error_Handler();
  43.     }
  44. }
复制代码

以上是完整的时钟配置函数,使用LPTIM最主要的配置由如下构成:

  1. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
  2. RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  3. HAL_RCC_OscConfig(&RCC_OscInitStruct);

  4. PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
  5. PeriphClkInit.LptimClockSelection = RCC_LPTIM1CLKSOURCE_LSI;
  6. HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
复制代码

3.初始化配置LPTIM
  1. /**
  2.   * @brief LPTIM1 Initialization Function
  3.   * @param None
  4.   * @retval None
  5.   */
  6. void MX_LPTIM1_Init(void)  //0.037Mhz  (1+period / 0.037(37000)) = 1s period=36999
  7. {
  8.   hlptim1.Instance = LPTIM1;
  9.   hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  10.   hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
  11.   hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
  12.   hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
  13.   hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
  14.   hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
  15.   if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
  16.   {
  17.     Error_Handler();
  18.   }
  19. }
复制代码

4.LPTIM中断处理函数
  1. void LPTIM1_IRQHandler(void)
  2. {
  3.   HAL_LPTIM_IRQHandler(&hlptim1);
  4. }
复制代码

5.启用LPTIM,中断触发回调函数
启用LPTIM分为多种方式:如脉冲,PWM,计数等。
具体可参考HAL_LPTIM_IRQHandler函数的实现。

  1. /**
  2.   * @brief  Handle LPTIM interrupt request.
  3.   * @param  hlptim LPTIM handle
  4.   * @retval None
  5.   */
  6. void HAL_LPTIM_IRQHandler(LPTIM_HandleTypeDef *hlptim)
  7. {
  8.   /* Compare match interrupt */
  9.   if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_CMPM) != RESET)
  10.   {
  11.     if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_CMPM) != RESET)
  12.     {
  13.       /* Clear Compare match flag */
  14.       __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMPM);

  15.       /* Compare match Callback */
  16. #if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
  17.       hlptim->CompareMatchCallback(hlptim);
  18. #else
  19.       HAL_LPTIM_CompareMatchCallback(hlptim);
  20. #endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
  21.     }
  22.   }

  23.   /* Autoreload match interrupt */
  24.   if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_ARRM) != RESET)
  25.   {
  26.     if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_ARRM) != RESET)
  27.     {
  28.       /* Clear Autoreload match flag */
  29.       __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARRM);

  30.       /* Autoreload match Callback */
  31. #if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
  32.       hlptim->AutoReloadMatchCallback(hlptim);
  33. #else
  34.       HAL_LPTIM_AutoReloadMatchCallback(hlptim);
  35. #endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
  36.     }
  37.   }

  38.   /* Trigger detected interrupt */
  39.   if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_EXTTRIG) != RESET)
  40.   {
  41.     if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_EXTTRIG) != RESET)
  42.     {
  43.       /* Clear Trigger detected flag */
  44.       __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_EXTTRIG);

  45.       /* Trigger detected callback */
  46. #if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
  47.       hlptim->TriggerCallback(hlptim);
  48. #else
  49.       HAL_LPTIM_TriggerCallback(hlptim);
  50. #endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
  51.     }
  52.   }

  53.   /* Compare write interrupt */
  54.   if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_CMPOK) != RESET)
  55.   {
  56.     if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_CMPOK) != RESET)
  57.     {
  58.       /* Clear Compare write flag */
  59.       __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMPOK);

  60.       /* Compare write Callback */
  61. #if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
  62.       hlptim->CompareWriteCallback(hlptim);
  63. #else
  64.       HAL_LPTIM_CompareWriteCallback(hlptim);
  65. #endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
  66.     }
  67.   }

  68.   /* Autoreload write interrupt */
  69.   if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_ARROK) != RESET)
  70.   {
  71.     if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_ARROK) != RESET)
  72.     {
  73.       /* Clear Autoreload write flag */
  74.       __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARROK);

  75.       /* Autoreload write Callback */
  76. #if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
  77.       hlptim->AutoReloadWriteCallback(hlptim);
  78. #else
  79.       HAL_LPTIM_AutoReloadWriteCallback(hlptim);
  80. #endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
  81.     }
  82.   }

  83.   /* Direction counter changed from Down to Up interrupt */
  84.   if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_UP) != RESET)
  85.   {
  86.     if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_UP) != RESET)
  87.     {
  88.       /* Clear Direction counter changed from Down to Up flag */
  89.       __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_UP);

  90.       /* Direction counter changed from Down to Up Callback */
  91. #if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
  92.       hlptim->DirectionUpCallback(hlptim);
  93. #else
  94.       HAL_LPTIM_DirectionUpCallback(hlptim);
  95. #endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
  96.     }
  97.   }

  98.   /* Direction counter changed from Up to Down interrupt */
  99.   if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_DOWN) != RESET)
  100.   {
  101.     if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_DOWN) != RESET)
  102.     {
  103.       /* Clear Direction counter changed from Up to Down flag */
  104.       __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DOWN);

  105.       /* Direction counter changed from Up to Down Callback */
  106. #if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
  107.       hlptim->DirectionDownCallback(hlptim);
  108. #else
  109.       HAL_LPTIM_DirectionDownCallback(hlptim);
  110. #endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
  111.     }
  112.   }
  113. }
复制代码

这里示例TimeOut的方式回调。
开启LPTIM定时器需要调用 HAL_LPTIM_TimeOut_Start_IT

  1. //HAL_LPTIM_TimeOut_Start_IT  <=> HAL_LPTIM_CompareMatchCallback
  2. void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim)
  3. {
  4.     HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
  5. }
复制代码

6.main.c 主函数
  1. int main(void)
  2. {
  3.     HAL_Init();
  4.     /* Configure the system clock */
  5.     SystemClock_Config();

  6.     MX_LPTIM1_Init();
  7.     //(1+period / 0.037(37000)) = 1s period=36999  1s触发一次
  8.     HAL_LPTIM_TimeOut_Start_IT(&hlptim1,36999,1000);
  9.     while(1){
  10.         HAL_Delay(1000);
  11.     }
复制代码




D4NZPI2NOZPKA7BT0@LCCKH.png
收藏 评论0 发布时间:2021-11-18 22:00

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版