STM32L151C8周期性从待机模式唤醒(RTC Wakeup Timer)
2018-09-10 来源:eefocus
#include 'stm32l1xx.h'
#include 'system_stm32l1xx.h'
#include 'OLED.h'
#include 'delay.h'
void RtcWakeUpConfig(void);
u8 RtcInit(void);
u8 RtcConfig(void);
int main()
{
DelayInit(); //延时初始化
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR时钟
if(PWR_GetFlagStatus(PWR_FLAG_SB)) //从待机模式唤醒
{
PWR_ClearFlag(PWR_FLAG_SB);
PWR_ClearFlag(PWR_FLAG_WU);
}
OLED_Init();
RtcInit();
while(1)
{
OLED_8x16StrP(0,0,'Runing...'); //液晶提示在运行中
DelayS(2); //延时2秒
RtcWakeUpConfig(); //RTC wakeup 配置:间隔500ms自动唤醒
// PWR_WakeUpPinCmd(PWR_WakeUpPin_1,ENABLE); //Periodic auto-wakeup不需要外部唤醒管脚,故不需要这句
PWR_EnterSTANDBYMode(); //进入待机(STANDBY)模式
}
}
void RtcWakeUpConfig(void)
{
RTC_WakeUpCmd(DISABLE);
RTC_ClearFlag(RTC_FLAG_WUTF);
RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div8); //选择时钟为外部32.768KHz 8分频
RTC_SetWakeUpCounter(2047); //间隔500ms
RTC_ClearITPendingBit(RTC_IT_WUT);
RTC_ITConfig(RTC_IT_WUT,ENABLE); //需要使能中断,不需要中断函数
RTC_WakeUpCmd(ENABLE);
}
u8 RtcInit(void)
{
//检查是不是第一次配置时钟
u8 flag = 0;
if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x32F2) //从指定的后备寄存器中读出数据:读出了与写入的指定数据不相乎
{
/* RTC configuration */
flag = RtcConfig();
if(flag == 0)
{
RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2);
}
else
return flag;
}
else
{
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_RTCAccessCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
}
return 0; //ok
}
/**
* @brief Configure the RTC peripheral by selecting the clock source.
* @param None
* @retval None
*/
u8 RtcConfig(void)
{
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to RTC */
PWR_RTCAccessCmd(ENABLE);
/* Enable the LSE OSC */
RCC_LSEConfig(RCC_LSE_ON);
/* Wait till LSE is ready */
u32 temp = 0;
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
{
temp++;
delay_ms(10);
if(temp >= 250) return 1;//初始化时钟失败,晶振有问题,32768晶振起振极限时间1-5S
}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Enable the RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC APB registers synchronisation */
RTC_WaitForSynchro();
/* Configure the RTC data register and RTC prescaler */
RTC_InitTypeDef RTC_InitStructure;
RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
RTC_InitStructure.RTC_SynchPrediv = 0xFF;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure);
return 0;
}
非待机模式,RTC Wakeup timer中断配置及中断处理
void RTC_IRQConfig(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/* EXTI configuration *******************************************************/
EXTI_ClearITPendingBit(EXTI_Line20);
EXTI_InitStructure.EXTI_Line = EXTI_Line20;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable the RTC Wakeup Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_WKUP_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_WUT) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line20);
PWR_RTCAccessCmd(ENABLE);//如果之前禁止了,要重新打开
RTC_ClearITPendingBit(RTC_IT_WUT);
PWR_RTCAccessCmd(DISABLE);//可以再关上
GPIO_ToggleBits( GPIOB, GPIO_Pin_4 );
}
}