STM32F103单片机实现RTC待机唤醒功能
单片机型号: STM32F103ZET6
正点原子战舰开发板
工程主体截图
该程序是根据正点原子提供的RTC实验程序修改得来
主要代码
//实时时钟配置
//初始化RTC时钟,同时检测时钟是否工作正常
void RTC_Init(){
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);//使能PWR和BKP外设时钟
//默认情况下,RTC 所属的备份域禁止访问,可使用库函数 PWR_BackupAccessCmd 使能访问
PWR_BackupAccessCmd(ENABLE);//允许访问备份区域,后备区域解锁
if(PWR_GetFlagStatus(PWR_FLAG_SB)!=RESET) //如果现在处于待机模式
{
PWR_ClearFlag(PWR_FLAG_SB); //清除待机模式
RTC_ITConfig(RTC_IT_SEC, ENABLE); //打开RTC中断
RTC_WaitForSynchro(); //等待RTC寄存器同步
}
else
{
BKP_DeInit();//复位备份区域 使用此函数必须调用RCC_APB1PeriphClockCmd()函数
RCC_LSEConfig(RCC_LSE_ON);//设置外部低速晶振(LSE),外部32.768KHZ晶振开启
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) //等待稳定
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //设置RTC时钟(RTCCLK),选择LSE(晶振频率为 32.768KHz)作为RTC时钟
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
RTC_WaitForLastTask(); //等待RTC寄存器同步,因为RTC时钟是低速的,内环时钟是高速的,所以要同步
RTC_WaitForSynchro(); //写寄存器之前要确保上一次RTC的操作完成
//下面这两条语句是开启RTC秒中断的函数,每过1秒钟产生一次中断,就进入了中断服务函数
RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中断
RTC_WaitForLastTask(); //确保上一次 RTC 的操作完成
RTC_EnterConfigMode(); //进入RTC配置模式
RTC_SetCounter(0); //初始值设定为0s 在使用本函数前必须先调用函数RTC_WaitForLastTask();等待标志位RTOFF被设置
RTC_WaitForLastTask();
RTC_SetPrescaler(32767); //设置RTC分频: 使 RTC周期为1s RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) = 1HZ 在使用本函数前必须先调用函数RTC_WaitForLastTask();等待标志位RTOFF被设置
RTC_WaitForLastTask(); //确保上一次 RTC 的操作完成
RTC_ExitConfigMode(); //退出RTC 配置模式
}
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_IRQHandler(){
if(RTC_GetITStatus(RTC_IT_SEC)!=RESET) //是否秒中断发生
{
printf(" Time is =%d \r\n",RTC_GetCounter()); //输出此时的秒数
}
RTC_WaitForLastTask();
RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW); //清除秒中断标志位和溢出位
}
程序主函数代码
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "usmart.h"
#include "rtc.h"
int main(void){
// int Distance_data=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC优先级分组2
delay_init(); //延时函数初始化
uart_init(115200); //串口1初始化 PA9-RX PA10-TX
LED_Init(); //LED端口初始化
// Beep_Init(); //BEEP端口初始化
// OLED_Init() ; //OLED端口初始化
RTC_Init();
while(1)
{
RTC_IRQHandler();
delay_ms(100);
printf("\r\n");
printf("进入休眠!\r\n");
RTC_IRQHandler();
RTC_SetAlarm(RTC_GetCounter()+10); //闹钟在此时刻加上10秒
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
PWR_EnterSTANDBYMode(); //进入待机(STANDBY)模式
}
}
运行结果
每隔10秒从休眠状态唤醒,在进入休眠