TM32L0系列之02 RTC唤醒待机模式

STM32L0系列之02 RTC唤醒待机模式

前言

使用芯片:STM32L051R8T6
软件平台:KEIL V5、STM32CubeL0
库函数:HAL

一、硬件介绍

1、单片机的系统时钟为:32Mhz,由PLL时钟提供
2、PLL通过8MHz的高速外部晶振(HSE)经过8倍频,2分频后得到
3、RTC始终源选择32.768KMz的石英晶体振荡器(LSE),是的RTC在停机和待机两种低功耗模式下工作,并可以用作唤醒源;
4、如果 RTC 的时钟由 LSE 提供,则 RTC 在系统复位后仍可获得时钟并保持正常工作。

二、待机模式介绍

1、待机模式下I/O状态

在待机模式下,除以下各部分以外,所有 I/O 引脚都处于高阻态:
(1) 复位引脚
(2)唤醒引脚(WKUP1、 WKUP2、 WKUP3)
(3)以下 I/O 上的 RTC 功能(入侵、时间戳、 RTC 闹钟输出、 RTC 时钟校准输出):
– 类别 3: PC13、 PA0
– 类别 5: PC13、 PA0、 PE6

2、进入待机模式

  PDDS 位 +SLEEPDEEP 位 +WFI,从 ISR 返回或 WFE

3、退出待机模式

WKUP 引脚上升沿、RTC 闹钟(闹钟 A 或闹钟 B)、 RTC 唤醒事件、RTC 入侵事件、RTC 时间戳事件、NRST 引脚外部复位、IWDG 复位

三、程序代码

1、 系统时钟配置

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /**Configure the main internal regulator output voltage 
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /**Initializes the CPU, AHB and APB busses clocks 
  */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;

	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  //RCC_OscInitStruct.HSIState = RCC_HSI_ON; //ADC的时钟源
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;


  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /**Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

2、 RTC时钟配置

void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;

  /*##-1- Configue the RTC clock soucre ######################################*/
#ifdef RTC_CLOCK_SOURCE_LSE
  /* -a- Enable LSE Oscillator */
  RCC_OscInitStruct.OscillatorType =  RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  { 
    while(1);
  }

  /*##-2- Enable the RTC peripheral Clock ####################################*/
  /* Enable RTC Clock */
  __HAL_RCC_RTC_ENABLE();
  
  /*##-3- Configure the NVIC for RTC Alarm ###################################*/
  HAL_NVIC_SetPriority(RTC_IRQn, 0x0, 0);
  HAL_NVIC_EnableIRQ(RTC_IRQn);
}

3、 RTC初始化配置配置

void SystemPower_Config(void)
{
	__HAL_RCC_PWR_CLK_ENABLE(); 

  HAL_PWREx_EnableUltraLowPower();
  
  /* Enable the fast wake up from Ultra low power mode */
  HAL_PWREx_EnableFastWakeUp();

  /* Configure RTC */
  RTCHandle.Instance = RTC;
  /* Set the RTC time base to 1s */
  /* Configure RTC prescaler and RTC data registers as follow:
  - Hour Format = Format 24
  - Asynch Prediv = Value according to source clock
  - Synch Prediv = Value according to source clock
  - OutPut = Output Disable
  - OutPutPolarity = High Polarity
  - OutPutType = Open Drain */
  RTCHandle.Init.HourFormat = RTC_HOURFORMAT_24;
  RTCHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
  RTCHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
  RTCHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
  RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  HAL_RTC_Init(&RTCHandle) ;
	
	    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);	// 清除唤醒标志
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);	// 清除待机标志
	
    HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 8192, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
		__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

}

写程序的时候忘记配置 __HAL_RCC_PWR_CLK_ENABLE(); 导致RTC不能正常工作

4、 进入待机模式

void LowPower_enter_standby(void)
{
    printf("=== Power standby ===\r\n");
    HAL_Delay(50);


    //UART1;	减少16uA
    HAL_UART_MspDeInit(&huart);
    HAL_UART_MspDeInit(&huart2);

	
    __HAL_RCC_GPIOA_CLK_DISABLE();
    __HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();
    __HAL_RCC_GPIOH_CLK_DISABLE();

    // 禁用 调试端口 少800uA,下面2句函数功能一样!
    //HAL_DBGMCU_DisableDBGStandbyMode();
	HAL_DBGMCU_DBG_DisableLowPowerConfig(DBGMCU_SLEEP | DBGMCU_STOP | DBGMCU_STANDBY);
	
	// 若需要在低功耗模式下调试程序,可以打开此函数
	//HAL_DBGMCU_DBG_EnableLowPowerConfig(DBGMCU_SLEEP | DBGMCU_STOP | DBGMCU_STANDBY);
	
    // PIN1 连接到 PWR->CR 的 PWR_FLAG_WU 标记
    // 用于待机模式IO唤醒,唤醒后判断WKUP按钮状态
	//		WKUP pin 1 (PA00) if enabled.
	//      WKUP pin 2 (PC13) if enabled.
	//      WKUP pin 3 (PE06) if enabled, for stm32l07xxx and stm32l08xxx devices only.
	//      WKUP pin 3 (PA02) if enabled, for stm32l031xx devices only.
    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);

    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);	// 清除唤醒标志
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);	// 清除待机标志
	   
    /*## Setting the RTC Wake up time ########################################*/
    /*  RTC Wakeup Interrupt Generation:
    Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI))
    Wakeup Time = Wakeup Time Base * WakeUpCounter
    = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI)) * WakeUpCounter
    ==> WakeUpCounter = Wakeup Time / Wakeup Time Base

    To configure the wake up timer to 4s the WakeUpCounter is:
    RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16
    Wakeup Time Base = 16 /(~32768Hz) = ~488.3us
    Wakeup Time = ~4s = 0,410ms  * WakeUpCounter
    ==> WakeUpCounter = 4s/488.3us = 8192  */
#ifdef __rtc_H
	// 该功能可以用Cubme RTC内配置,代码可以参考rtc.c文件内
    // rtc 唤醒采用LSE时钟,第一参数,计数溢出唤醒;第二参数:进行16分配
    HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 8192, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
		__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
#endif
    /* Enter Standby Mode */
    HAL_PWR_EnterSTANDBYMode();
	
}

三、测试结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值