f4的待机模式和唤醒代码

STM32 Standby 低功耗模式示例
1.  基本流程
1)  初始化 RTC
2)  配置外部中断(不是必需的)
3)  设置 Alarm 时间
4)  进入 Standby
2.  几个需要注意的问题
1)  从 Standby 退出后,代码将重新运行,相当于执行了软复位。其实也容易理解,因
为进入 Standby 后,内核的所有功能都已经停止(断电) ,RAM 内的所有数据将消
除,因此,从 Standby 退出后,需要重新执行所有程序。
2)  如果有必要,可在进入 Standby 之前将重要数据存入 BACKUP RAM 或 RTC 的 19 个
备份寄存器中,退出 Standby 时再将数据读出。
3)  进入 Standby 后,如果 Alarm 事件发生,虽然可以退出 Standby 模式,但即使配置
了外部中断,发系统也无法响应外部中断,因为,从 Standby 退出后发生了系统复
位。
4)  虽然,导致系统从 Standby 退出的 Alarm 事件不能用于触发外部中断(注:仅仅是
导致系统从 Standby 退出的那个特定事件不能触发外部中断,而系统正常运行后,
Alarm 事件还是可以正常触发外部中断的) ,但即使不需要 Alarm 触发外部中断的
功能,也必须配置使能 Alarm 中断,否则系统将无法从 Standby 退出。
5)  使能 Alarm 中断之前,最好先清除中断标志位,否则在循环进入或推出 Standby 的
操作就会失败(原因有待研究) 。
3.  示例代码
3.1. 初始化 RTC
static int32u DrvRtcInit(void)
{
RTC_InitTypeDef RTC_InitStructure;
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_BackupAccessCmd(ENABLE);
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Calendar Configuration with LSI supposed at 32KHz */
RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
RTC_InitStructure.RTC_SynchPrediv  = 0xFF; /* (32KHz / 128) - 1 = 0xFF*/
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
RTC_ClearITPendingBit(RTC_IT_ALRA);
RTC_ITConfig(RTC_IT_ALRA,ENABLE);
/* Disable the RTC Clock */
PWR_BackupAccessCmd(DISABLE);
return NCC_OK;
}
3.2. 配置外部中断
void RTC_EXTI_INITIAL(FunctionalState newState)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
// Enable SYSCFG clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//------------EXTI 配置 -------------------
EXTI_InitStructure.EXTI_Line=EXTI_Line17;
EXTI_InitStructure.EXTI_LineCmd=newState;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure);
//------------设置 中断-------------------
NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;//RTC_Alarm_IRQn RTC_WKUP_IRQn
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = newState;
NVIC_Init(&NVIC_InitStructure);
}
/*********************************************************************/
/*
*外部中断响应函数
*/
void RTC_Alarm_IRQHandler(void)
{
if(SET==RTC_GetITStatus(RTC_IT_ALRA))
{
RTC_ClearITPendingBit(RTC_IT_ALRA);
EXTI_ClearITPendingBit(EXTI_Line17);
// DrvLedCmd(GPIO_Pin_3,bLedState);
}
}
3.3. 设置 Alarm 时间
void RTC_SET_ALARM(uint8_t sec)
{
RTC_TimeTypeDef RTC_TimeStructure;
RTC_DateTypeDef RTC_DateStructure;
RTC_AlarmTypeDef RTC_AlarmStructure;
PWR_BackupAccessCmd(ENABLE);
// Fills each RTC_TimeStruct member with its default value
RTC_TimeStructInit(&RTC_TimeStructure);
// Fills each RTC_DateStruct member with its default value
RTC_DateStructInit(&RTC_DateStructure);
//set rtc time
RTC_SetTime(RTC_Format_BCD,&RTC_TimeStructure);
//set rtc data
RTC_SetDate(RTC_Format_BCD,&RTC_DateStructure);
//set alarm time by add some sec
RTC_TimeStructure.RTC_Seconds+=sec;
//Fill the RTC_AlarmStructure
RTC_AlarmStructure.RTC_AlarmDateWeekDay=RTC_DateStructure.RTC_Date;
RTC_AlarmStructure.RTC_AlarmDateWeekDaySel=RTC_AlarmDateWeekDaySel_Date;
RTC_AlarmStructure.RTC_AlarmMask=RTC_AlarmMask_None;
RTC_AlarmStructure.RTC_AlarmTime=RTC_TimeStructure;
//Disable alarm A
if((RTC_AlarmCmd(RTC_Alarm_A,DISABLE))==ERROR)
{
return;
}
//set the alarm A
RTC_SetAlarm(RTC_Format_BCD,RTC_Alarm_A,&RTC_AlarmStructure);
//Enable alarm A
if((RTC_AlarmCmd(RTC_Alarm_A,ENABLE))==ERROR)
{
return;
}
}
3.4. 进入 Standby
PWR_EnterSTANDBYMode();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值