打印
[STM32L4]

STM32L4的LPTIM怎么用

[复制链接]
2026|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhenxizhou|  楼主 | 2019-11-20 14:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我们自己的STM32L431板子正常能进入stop2模式,我想在这基础上加入LPTIM的功能定时唤醒。从官方的例程中拷贝下面的代码到程序中:
/* Set the Maximum value of the counter (Auto-Reload) that defines the Period */
#define Period               (uint32_t) 65535

/* Set the Timeout value */
#define Timeout              (uint32_t) (32768 - 1)


LPTIM_HandleTypeDef             LptimHandle;
RCC_PeriphCLKInitTypeDef        RCC_PeriphCLKInitStruct;

static void LSE_ClockEnable(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  
  /* Enable LSE clock */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
      //Error_Handler();
          printf("LSE_ClockEnable error\r\n");
  }
}

/**
* @brief  LPTIM MSP Init
* @param  hlptim : LPTIM handle
* @retval None
*/
void HAL_LPTIM_MspInit(LPTIM_HandleTypeDef *hlptim)
{
  //GPIO_InitTypeDef     GPIO_InitStruct;
   
  /* ## - 1 - Enable LPTIM clock ############################################ */
  __HAL_RCC_LPTIM1_CLK_ENABLE();
  
  /* ## - 2 - Force & Release the LPTIM Periheral Clock Reset ############### */  
  /* Force the LPTIM Periheral Clock Reset */
  __HAL_RCC_LPTIM1_FORCE_RESET();
  
  /* Release the LPTIM Periheral Clock Reset */  
  __HAL_RCC_LPTIM1_RELEASE_RESET();
  
  /* ## - 3 - Enable & Configure LPTIM Ultra Low Power Input ################# */
  /* Configure PB.06 (LPTIM1_ETR) in alternate function,
  Low speed push-pull mode and pull-up enabled.
  Note: In order to reduce power consumption: GPIO Speed is configured in
  LowSpeed */
#if 0
  /* Enable GPIO PORT(s)*/
  LPTIMx_GPIO_PORT_ENABLE;
  
  /* Configure PB.06 */
  GPIO_InitStruct.Pin = GPIO_PIN_ETR;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PUPD_ETR;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
  GPIO_InitStruct.Alternate = GPIO_AF_LPTIMx_ETR;  
  HAL_GPIO_Init(LPTIMx_ETR_GPIO_PORT, &GPIO_InitStruct);
#endif
  /* Enable and set LPTIM Interrupt to the highest priority */
  HAL_NVIC_SetPriority(LPTIM1_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(LPTIM1_IRQn);  
  
}

void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
  /* Timeout was reached, toggle LED2 */
  printf("LPTIME wakeup\r\n");
}

void LPTIM1_IRQHandler(void)
{
  HAL_LPTIM_IRQHandler(&LptimHandle);
}

在main函数中加入:
HAL_Init();

        /* Enable the LSE source */
  LSE_ClockEnable();

  /* ### - 1 - Re-target the LSE to Clock the LPTIM Counter ################# */
  /* Select the LSE clock as LPTIM peripheral clock */
  RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
  RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSE;
  HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);

  /* ### - 2 - Initialize LPTIM peripheral ################################## */
  /*
   *  Instance        = LPTIM1.
   *  Clock Source    = APB or LowPowerOSCillator
   *  Counter source  = Internal event.   
   *  Clock prescaler = 1 (No division).
   *  Counter Trigger = Trigger1: PC.03
   *  Active Edge     = Rising edge.
   */

  LptimHandle.Instance = LPTIM1;
  
  LptimHandle.Init.Clock.Source       = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  LptimHandle.Init.Clock.Prescaler    = LPTIM_PRESCALER_DIV1;  
  LptimHandle.Init.Trigger.Source     = LPTIM_TRIGSOURCE_0;
  LptimHandle.Init.Trigger.ActiveEdge = LPTIM_ACTIVEEDGE_RISING;
  LptimHandle.Init.CounterSource      = LPTIM_COUNTERSOURCE_INTERNAL;
  LptimHandle.Init.Input1Source       = LPTIM_INPUT1SOURCE_GPIO;
  LptimHandle.Init.Input2Source       = LPTIM_INPUT2SOURCE_GPIO;
  
  /* Initialize LPTIM peripheral according to the passed parameters */
  if (HAL_LPTIM_Init(&LptimHandle) != HAL_OK)
  {
    printf("error1\r\n");
    //Error_Handler();
  }

  /* ### - 3 - Start the Timeout function in interrupt mode ################# */
  /*
   *  Period = 65535
   *  Pulse  = 32767
   *  According to this configuration (LPTIMER clocked by LSE & compare = 32767,
   *  the Timeout period = (compare + 1)/LSE_Frequency = 1s
   */
  if (HAL_LPTIM_TimeOut_Start_IT(&LptimHandle, Period, Timeout) != HAL_OK)
  {
    printf("error2\r\n");
    //Error_Handler();
  }

没加入代码HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);是因为我们自己的程序已经有
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
  LL_LPM_EnableDeepSleep();
  __WFI();

但是进不了LPTIM1_IRQHandler,LPTIM不起作用。
请问玩过LPTIM1的大大,我是不是缺少了什么步骤?
还有我在HAL_LPTIM_MspInit注释掉的PB6是起什么作用的?
谢谢

使用特权

评论回复
沙发
香水城| | 2019-11-20 16:37 | 只看该作者
我刚才基于内部APB时钟配置了下LPTIM,进入中断很顺利。

另外,你提到的PB6是可以从外部引入触发信号启动定时器的。 我刚才是基于软件启动。

  hlptim1.Instance = LPTIM1;
  hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
  hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
  hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
  hlptim1.Init.UpdateMode = LPTIM_UPDATE_ENDOFPERIOD;
  hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
  hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
  hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
  if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
  {
    Error_Handler();
  }

使用特权

评论回复
板凳
zhenxizhou|  楼主 | 2019-11-21 14:12 | 只看该作者
香水城 发表于 2019-11-20 16:37
我刚才基于内部APB时钟配置了下LPTIM,进入中断很顺利。

另外,你提到的PB6是可以从外部引入触发信号启动 ...

谢谢版主。
我把LptimHandle.Init.Trigger.Source     = LPTIM_TRIGSOURCE_0;
改成你那样
LptimHandle.Init.Trigger.Source     = LPTIM_TRIGSOURCE_SOFTWARE;
就可以了。
再请教一下,这个LPTIM的最大定时时间只能到2秒吗?
我们想设置1个24小时的定时时长,用这个LPTIM能实现吗?
还是只能用RTC来实现?

使用特权

评论回复
地板
香水城| | 2019-11-21 17:13 | 只看该作者
它的时钟源可以很多,也可以分频。 24小时一般也不是一个计数周期完成的。

使用特权

评论回复
5
zjq985062714| | 2019-11-30 10:23 | 只看该作者
可以看下官方文档

使用特权

评论回复
6
keaibukelian| | 2019-12-10 13:55 | 只看该作者
根据城主的试了试 应该没有问题

使用特权

评论回复
7
heimaojingzhang| | 2019-12-10 13:59 | 只看该作者
顺便学习下

使用特权

评论回复
8
guanjiaer| | 2019-12-10 14:05 | 只看该作者
官方有相关文档吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

76

帖子

2

粉丝