待机模式:唤醒后复位,从头开始执行主函数,所有时钟关闭,仅有RTC时钟开启
停止模式:除RTC时钟外,所有外设时钟关闭,但保存数据和运行到的位置(PC值),唤醒后需要等时钟同步
睡眠模式:外设时钟开启,CPU时钟关闭,保存数据和运行到的位置(PC值)
void RTC_Init(uint32_t count)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能BPK PWR时钟
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel =RTC_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
PWR_BackupAccessCmd(ENABLE); //系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作,使能 RTC 和后备寄存器以进行写入访问
BKP_DeInit();//复位备份区域,(可选)
//BKP_TamperPinCmd(DISABLE);
RCC_LSICmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);//检查指定的 RCC 标志位设置与否,等待低速晶振就绪
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //选择 LSE 作为 RTC 时钟
RCC_RTCCLKCmd(ENABLE); //使能 RTC 时钟
RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成
RTC_WaitForSynchro(); //等待 RTC 寄存器同步
RTC_SetPrescaler(39999);//设置 RTC 时钟分频数 晶振32.768KHz
RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成
RTC_SetCounter(count);//最后在配置完成之后
RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成
RTC_ITConfig(RTC_IT_SEC,ENABLE); //使能 RTC 秒中断
RTC_WaitForLastTask(); //等待最近一次对 RTC 寄存器的写操作完成
RTC_ClearITPendingBit(RTC_IT_OW);
RTC_ClearITPendingBit(RTC_IT_ALR);
RTC_ClearITPendingBit(RTC_IT_SEC);
}
void stanby_mode(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_ClearFlag(PWR_FLAG_WU);
PWR_WakeUpPinCmd(ENABLE);
RTC_ITConfig(RTC_IT_SEC, DISABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RTC_ClearFlag(RTC_FLAG_RSF);
RTC_ClearFlag(RTC_FLAG_OW);
RTC_ClearFlag(RTC_FLAG_ALR);
RTC_ClearFlag(RTC_FLAG_SEC);
PWR_EnterSTANDBYMode();
}
void stop_mode(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
RTC_ITConfig(RTC_IT_SEC, DISABLE);
PWR_ClearFlag(PWR_FLAG_WU);
PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
}
void sleep_mode(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
RTC_ITConfig(RTC_IT_SEC, DISABLE);
PWR_ClearFlag(PWR_FLAG_WU);
__WFI(); //或__WFE
}
void EXTI0_Configuration(void)
{
EXTI_InitTypeDef EXTI0_InitStruct;
EXTI0_InitStruct.EXTI_Line = EXTI_Line0; //选择哪一条外部中断线,可以选择EXTI_Line0~EXTI_Line19,其中EXTI_Line0~EXTI_Line15为IO口中断
EXTI0_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //选择模式,可选择中断模式或事件模式
EXTI0_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //选择跳变沿触发,可选择上升沿触发或下降沿触发,也可选择上升沿和下降沿共同触发
EXTI0_InitStruct.EXTI_LineCmd = ENABLE; //使能或使能
EXTI_Init(&EXTI0_InitStruct);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel =EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
EXTI_ClearITPendingBit(EXTI_Line0);
}
RTC库函数
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);
//RTC中断配置
/*可选中断
@arg RTC_IT_OW: Overflow interrupt 32位计时器溢出中断
@arg RTC_IT_ALR: Alarm interrupt 警告中断,超过警报值触发中断
@arg RTC_IT_SEC: Second interrupt 秒中断
*/
void RTC_EnterConfigMode(void);
//进入RTC配置模式
void RTC_ExitConfigMode(void);
//退出RTC配置模式
uint32_t RTC_GetCounter(void);
//获取计数值,复位后必须先调用void RTC_WaitForSynchro(void)
//等待直到RTC寄存器(RTC_CNT、RTC_ALR和RTC_PRL)与RTC APB时钟同步,否则容易导致数据损坏
void RTC_WaitForSynchro(void);//等待RTC寄存器与RTC的APB时钟同步
void RTC_SetCounter(uint32_t CounterValue); //设置初始计数值
void RTC_SetPrescaler(uint32_t PrescalerValue); //设置时钟分频
//调用以上两个函数前需要先调用void RTC_WaitForLastTask(void)
//以上两个函数包含了void RTC_EnterConfigMode(void);和void RTC_ExitConfigMode(void);
void RTC_WaitForLastTask(void);//等待RTC寄存器的最后一次写操作完成
void RTC_SetAlarm(uint32_t AlarmValue);//设置报警值
uint32_t RTC_GetDivider(void);//获取分频值
FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG);//获取标志状态值
void RTC_ClearFlag(uint16_t RTC_FLAG); //清零标志位
/*
@arg RTC_FLAG_RTOFF: RTC Operation OFF flag RTC操作关闭标志
@arg RTC_FLAG_RSF: Registers Synchronized flag 寄存器同步标志
@arg RTC_FLAG_OW: Overflow flag 溢出标志
@arg RTC_FLAG_ALR: Alarm flag 警报标志
@arg RTC_FLAG_SEC: Second flag 秒标志
*/
ITStatus RTC_GetITStatus(uint16_t RTC_IT); //获取中断状态
void RTC_ClearITPendingBit(uint16_t RTC_IT);//清零中断标志位
/*
* @arg RTC_IT_OW: Overflow interrupt 溢出中断
* @arg RTC_IT_ALR: Alarm interrupt 警报中断
* @arg RTC_IT_SEC: Second interrupt 秒中断
*/
BKP库函数
void BKP_DeInit(void);//将BKP外设寄存器初始化为默认复位值
void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel);//配置防篡改引脚的有效电平
void BKP_TamperPinCmd(FunctionalState NewState);//使能或失能防篡改引脚
void BKP_ITConfig(FunctionalState NewState);//使能或失能BKP中断
void BKP_RTCOutputConfig(uint16_t BKP_RTCOutputSource);//选择要在防篡改引脚上输出的RTC输出源
/*
* @arg BKP_RTCOutputSource_None: 无RTC输出在防篡改引脚
* @arg BKP_RTCOutputSource_CalibClock: RTC输出64分频的频率在防篡改引脚
* @arg BKP_RTCOutputSource_Alarm: 输出报警脉冲信号在防篡改引脚
* @arg BKP_RTCOutputSource_Second: 输出秒脉冲信号在防篡改引脚
*/
void BKP_SetRTCCalibrationValue(uint8_t CalibrationValue);
//设置RTC时钟校准值,该值必须在0x00~0x7F之间
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);
//写后备寄存器,可选BKP_DR1~BKP_DR42
uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);//读后备寄存器
FlagStatus BKP_GetFlagStatus(void);//获取篡改引脚事件标志,设置了就返回1
void BKP_ClearFlag(void);//清除篡改引脚时间标志
ITStatus BKP_GetITStatus(void);//获取BKP中断状态
void BKP_ClearITPendingBit(void);//清除中断标志位
PWR库函数
void PWR_DeInit(void);//将PWR外设寄存器初始化为默认复位值
void PWR_BackupAccessCmd(FunctionalState NewState);//使能或失能对RTC和备份寄存器的访问
void PWR_PVDCmd(FunctionalState NewState);//使能或失能电源电压检测器
void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel);//配置电源电压检测器(PVD)检测到的电压阈值
void PWR_WakeUpPinCmd(FunctionalState NewState);//使能或失能唤醒引脚功能
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);//进入停止模式
void PWR_EnterSTANDBYMode(void);//进入待命模式
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);//获取标志位状态
/*
@arg PWR_FLAG_WU: Wake Up flag 唤醒标志
@arg PWR_FLAG_SB: StandBy flag 待命标志
@arg PWR_FLAG_PVDO: PVD Output 电源电压检测器(PVD)输出标志
*/
void PWR_ClearFlag(uint32_t PWR_FLAG);//清除标志
EXTI库函数
void EXTI_DeInit(void);//将EXTI外设寄存器初始化为默认值
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);//EXTI初始化
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);//指定初始化
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);//产生软件中断
/*
这个值可以为EXTI_Line0~EXTI_Line19
其中EXTI_Line16连接到PVD输出
EXTI_Line17连接到RTC警报事件
EXTI_Line18连接到USB设备/USB OTG 文件系统
EXTI_Line19连接到以太网唤醒事件
*/
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
void EXTI_ClearFlag(uint32_t EXTI_Line);
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);