达到的效果,使用RTC定时中断唤醒待机,设置定时15S,设备上电开始工作(LED灯开始亮,串口发送RTC时间),工作结束进入待机模式,RTC定时时间到,唤醒设备,或者在设备进入待机模式下使用WakeUp按键唤醒。
在系统或电源复位以后,微控制器处于运行状态。当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引脚
● 被使能的唤醒引脚
需要开启的外设 USART1 、RTC 以及RTC中断和LED(PA8)。
/* USER CODE BEGIN Includes */
RTC_DateTypeDef yTime ;//年份
RTC_TimeTypeDef nTime; //时 分 秒 时间
RTC_AlarmTypeDef aTime; //闹钟定时
#include
#include
#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);
*/
//--------------------------------------------------------
}
/* 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 */
有需要的自己下载。下载: https://www.lanzoui.com/ivLZDggiwtg 密码:8buk