STM32 CUbeIDE 低功耗模式 ——待机模式 RTC /WakeUp 唤醒

  达到的效果,使用RTC定时中断唤醒待机,设置定时15S,设备上电开始工作(LED灯开始亮,串口发送RTC时间),工作结束进入待机模式,RTC定时时间到,唤醒设备,或者在设备进入待机模式下使用WakeUp按键唤醒。

1、低功耗模式

  在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。

STM32F10xxx有三种低功耗模式:

● 睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时钟(SysTick)等仍在运行) 
● 停止模式(所有的时钟都已停止) 
● 待机模式(1.8V电源关闭) 
此外,在运行模式下,可以通过以下方式中的一种降低功耗: 
● 降低系统时钟 
● 关闭APB和AHB总线上未被使用的外设时钟。

低功耗模式:
在这里插入图片描述
进入待机模式:
可以通过设置独立的控制位,选择以下待机模式的功能:
● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了独立看门狗,除了系统复位,它不能再被停止。
● 实时时钟(RTC):通过备用区域控制寄存器(RCC_BDCR)的RTCEN位来设置。
● 内部RC振荡器(LSI RC):通过控制/状态寄存器(RCC_CSR)的LSION位来设置。
● 外部32.768kHz振荡器(LSE):通过备用区域控制寄存器(RCC_BDCR)的LSEON位设置。
退出待机模式:
当一个外部复位(NRST引脚)、IWDG复位、WKUP引脚上的上升沿或RTC闹钟事件的上升沿发生时,微控制器从待机模式退出。
在这里插入图片描述
待机模式下的输入/输出端口状态:
在待机模式下,所有的I/O引脚处于高阻态,除了以下的引脚:
● 复位引脚(始终有效)
● 当被设置为防侵入或校准输出时的TAMPER引脚
● 被使能的唤醒引脚

2、代码编写

2.1、创建工程

需要开启的外设 USART1 、RTC 以及RTC中断和LED(PA8)。

开启调试:
在这里插入图片描述
开启时钟,包括RTC时钟:
在这里插入图片描述
在这里插入图片描述

开启RTC和中断:
在这里插入图片描述
开启USART1 串口发送信息:
在这里插入图片描述

2.2、代码

定义变量和printf重定向:
在这里插入图片描述

/* USER CODE BEGIN Includes */
RTC_DateTypeDef yTime ;//年份
RTC_TimeTypeDef nTime; //时 分 秒    时间
RTC_AlarmTypeDef aTime; //闹钟定时
#include <string.h>
#include <stdio.h>
#define printf(...)  HAL_UART_Transmit((UART_HandleTypeDef *)&huart1, (uint8_t *)u_buf,\
		                                sprintf((char*)u_buf,__VA_ARGS__), 0xFFFF);
uint8_t u_buf[256];
/* USER CODE END Includes */

在这里插入图片描述

nTime.Hours = 0;
  nTime.Minutes = 0;
  nTime.Seconds = 0;
  HAL_RTC_SetTime(&hrtc,&nTime,RTC_FORMAT_BIN);

  yTime.Year = 20;
  yTime.Month = 9;
  yTime.Date = 8 ;
  yTime.WeekDay = 1;
  HAL_RTC_SetDate(&hrtc, &yTime, RTC_FORMAT_BIN);

  //闹钟 时间设置
  aTime.Alarm = 1;
  aTime.AlarmTime.Hours = 0;
  aTime.AlarmTime.Minutes = 0;
  aTime.AlarmTime.Seconds = 10;
  HAL_RTC_SetAlarm_IT(&hrtc,&aTime,RTC_FORMAT_BIN);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
    

	  //获取时间
	  HAL_RTC_GetTime(&hrtc,&nTime,RTC_FORMAT_BIN);
	  printf("Time--%d:%d:%d\r\n",nTime.Hours,nTime.Minutes,nTime.Seconds); //输出时间
	  //获取日期
	  HAL_RTC_GetDate(&hrtc,&yTime, RTC_FORMAT_BIN);
	  printf("yTime--%d:%d:%d:%d \r\n",2000 + yTime.Year,yTime.Month,yTime.Date,yTime.WeekDay); //输出日期

	  if(nTime.Seconds==1)
	  {
    
     //设置闹钟
		aTime.Alarm = 1;
		aTime.AlarmTime.Hours =nTime.Hours;
		aTime.AlarmTime.Minutes = nTime.Minutes;
		aTime.AlarmTime.Seconds = 10;
		HAL_RTC_SetAlarm_IT(&hrtc,&aTime,RTC_FORMAT_BIN);
	  }
	  HAL_Delay(1000);
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
     printf("检查唤醒\r\n");
	if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)//检查并检查系统是否从待机模式恢复
	  {
    
    
		/* Clear Standby flag */
		__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
	  }

	HAL_Delay(2000);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
	HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);//禁用所有使用的唤醒源:PWR_WAKEUP_PIN1 connected to PA.00
	 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);//清除所有相关的唤醒标志

	 __HAL_RCC_APB2_FORCE_RESET();       //复位所有IO口
	 __HAL_RCC_PWR_CLK_ENABLE();         //使能PWR时钟
	 // 取消下面注释 使用WakeUp按键也可以唤醒
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);//启用连接到PA.00的WakeUp Pin 
	// 进入待机模式, 此时所有1.8V域的时钟都关闭,HIS和HSE的振荡器关闭, 电压调节器关闭.
	// 只有WKUP引脚上升沿,RTC警告事件,NRST引脚的外部复位,IWDG复位.
	HAL_PWR_EnterSTANDBYMode();//进入待机模式
   //如果没有进入待机模式 代码下面执行
	 printf("未进入待机\r\n");
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);

添加中断回调函数
在这里插入图片描述

//中断回调函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *nhrtc) //鍙ユ焺 瑕佸彇鏂板悕閬垮厤涓巋rtc鍐茬獊
{
    
    
  HAL_RTC_GetTime(nhrtc,&nTime,RTC_FORMAT_BIN);
  printf("Alarm--%d:%d:%d  ----------------\r\n",nTime.Hours,nTime.Minutes,nTime.Seconds);

 /*
//设置为24小时闹钟定时--------------------
  nTime.Minutes+=1;
  if(nTime.Minutes==60)
    {
      nTime.Hours += 1;
	  if(nTime.Hours == 24)
	    {
	      nTime.Hours = 0;
	    }
      nTime.Minutes=0;
    }
  aTime.AlarmTime = nTime;
  HAL_RTC_SetAlarm_IT(&hrtc,&aTime,RTC_FORMAT_BIN);
  */
//--------------------------------------------------------
}

在rtc.c 文件里面 添加备份
在这里插入图片描述

/* USER CODE BEGIN Check_RTC_BKUP */
  //判断是否第一次配置
    if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)==0X5050)
    {
    
    //写入数据 不再配置时间
      return;
    }
    //备份寄存器中写入数据  标记已经初始化过了
    HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1,0X5050);


    //    //修改中断优先级
    //	  HAL_NVIC_SetPriority(RTC_IRQn, 2, 0);
    //	  HAL_NVIC_EnableIRQ(RTC_IRQn);
    //	  HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 1, 0);
    //	  HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);

  /* USER CODE END Check_RTC_BKUP */

2.3 、效果显示:

在这里插入图片描述

3、下载链接

 有需要的自己下载。下载: https://www.lanzoui.com/ivLZDggiwtg 密码:8buk

猜你喜欢

转载自blog.csdn.net/weixin_45488643/article/details/108475717
今日推荐