STM32使用RTC+BKP+PWR+EXTI

待机模式:唤醒后复位,从头开始执行主函数,所有时钟关闭,仅有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);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值