1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > STM32F030的低功耗案例(RTC闹钟中断定时唤醒喂狗+按键外部中断唤醒)

STM32F030的低功耗案例(RTC闹钟中断定时唤醒喂狗+按键外部中断唤醒)

时间:2019-06-19 20:46:53

相关推荐

STM32F030的低功耗案例(RTC闹钟中断定时唤醒喂狗+按键外部中断唤醒)

最近使用到低功耗方案,采用的是STM32F030C8T6芯片,由于任务开启了看门狗,进入休眠后(采用的是STOP模式),需要及时喂狗,故而使用RTC闹钟中断定时唤醒来喂狗。

对比三种休眠模式:就设备的使用情况和功能需求,采用STOP模式

/* 三种休眠模式说明-各有不同1.Sleep modeIn Sleep mode, only the CPU is stopped. All peripherals continue to operate and can wake up the CPU when an interrupt/event occurs.2.Stop modeStop mode achieves very low power consumption while retaining the content of SRAM and registers. All clocks in the 1.8 V domain are stopped, the PLL, the HSI RC and the HSE crystal oscillators are disabled. The voltage regulator can also be put either in normal or in low power mode.The device can be woken up from Stop mode by any of the EXTI lines. The EXTI line source can be one of the 16 external lines or the RTC alarm.3.Standby modeThe Standby mode is used to achieve the lowest power consumption. The internal voltage regulator is switched off so that the entire 1.8 V domain is powered off. The PLL, the HSI RC and the HSE crystal oscillators are also switched off. After entering Standby mode, SRAM and register contents are lost except for the Standby circuitry.The device exits Standby mode when an external reset (NRST pin), an IWDG reset, a rising edge on the WKUP pins, or an RTC alarm occurs.*/

见如下代码:

/*RTC定时唤醒设置*/static void rtc_wakeup_set(void){/*RTC属于备份域,需要使能设备总线时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);/* Enable Access To The RTC & Backup Registers */PWR_BackupAccessCmd(ENABLE);RCC_LSICmd(ENABLE); /*启动LSI晶振*/while(RESET==RCC_GetFlagStatus(RCC_FLAG_LSIRDY)){} /*等待LSI就绪*/RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);/*配置RTC时钟:选择LSI时钟*/RCC_RTCCLKCmd(ENABLE); /*使能RTC时钟 */RTC_WaitForSynchro(); /*等待RTC时间寄存器与RTC的APB总线时钟同步*/RTC_InitTypeDef RTC_InitStructure;#if 1/*RTC的时钟源有3个:> LSE(32.768kHz)> LSI(40kHz)> HSE/32。> 秒输出计算:Tsec=LSI/[(RTC_AsynchPrediv+1)*(RTC_SynchPrediv +1)]*///RTC_InitStructure.RTC_HourFormat=RTC_HourFormat_12;RTC_InitStructure.RTC_SynchPrediv=0x18F;//399RTC_InitStructure.RTC_AsynchPrediv=0x63;//99RTC_Init(&RTC_InitStructure);#elseRTC_StructInit(&RTC_InitStructure);//缺省配置,主要应用于LSE(32.768KHz) #endifRTC_TimeTypeDef RTC_TimeStructure;#if 0//YYMMDDRTC_DateTypeDef RTC_DateStructure;RTC_DateStructure.RTC_Year=21;RTC_DateStructure.RTC_Month=RTC_Month_August;RTC_DateStructure.RTC_Date=1;RTC_DateStructure.RTC_WeekDay=RTC_Weekday_Monday;RTC_SetDate(RTC_Format_BCD,&RTC_DateStructure);RTC_DateStructInit(&RTC_DateStructure);//HHMMSSRTC_TimeStructure.RTC_H12=RTC_H12_AM;RTC_TimeStructure.RTC_Hours=0;RTC_TimeStructure.RTC_Minutes=0;RTC_TimeStructure.RTC_Seconds=0;RTC_SetTime(RTC_Format_BCD,&RTC_TimeStructure);#elseRTC_TimeStructInit(&RTC_TimeStructure);/*缺省配置 (Time = 00h:00min:00sec).*/#endifRTC_GetTime(RTC_HourFormat_12,&RTC_TimeStructure);//获取配置的时间参数RTC_AlarmTypeDef RTC_AlarmStructure;/*屏蔽日期和时分参数,仅采用秒参数*/RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay|RTC_AlarmMask_Hours|RTC_AlarmMask_Minutes;RTC_AlarmStructure.RTC_AlarmTime.RTC_H12= RTC_TimeStructure.RTC_H12;//RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = RTC_TimeStructure.RTC_Hours;//RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = RTC_TimeStructure.RTC_Minutes;RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = RTC_TimeStructure.RTC_Seconds+RTC_WKUP_TIME;RTC_SetAlarm(RTC_Format_BIN,RTC_Alarm_A,&RTC_AlarmStructure);//配置参数数据是BIN格式RTC_AlarmCmd(RTC_Alarm_A,DISABLE);//先关闭闹钟,等待一切先配置完成后再开启。/*EXTI线17是连接到RTC闹钟事件的,配置其中断也就是配置RTC闹钟中断*/EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line17;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//采用的是上升沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); /*开始前,先清除干扰残留以防误触发*/RTC_ClearFlag(RTC_FLAG_ALRAF);RTC_ClearITPendingBit(RTC_IT_ALRA);//清除RTC闹钟A的标志 EXTI_ClearITPendingBit(EXTI_Line17);//清除LINE17上的中断标志位RTC_ITConfig(RTC_IT_ALRA,ENABLE);//配置RTC闹钟中断并使能RTC_AlarmCmd(RTC_Alarm_A,ENABLE);//开启闹钟中断//PWR_BackupAccessCmd(DISABLE);PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);//设置中断唤醒方式,并且设备随之进入停止模式而休眠}

#define RTC_WKUP_TIME (10) /*定时唤醒时间:10s*/static void dev_sleep_set(void){//1.配置所有IO引脚为模拟输入方式,实现引脚0消耗#define GPIO_ALL_PIN(GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7\|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15)GPIO_InitTypeDef GPIO_InitStructure;GPIO_DeInit(GPIOA);//关闭所有设备时钟GPIO_DeInit(GPIOB);GPIO_DeInit(GPIOC);GPIO_DeInit(GPIOF);GPIO_InitStructure.GPIO_Pin = GPIO_ALL_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_Init(GPIOA,&GPIO_InitStructure);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_ALL_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_Init(GPIOB,&GPIO_InitStructure);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_ALL_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_Init(GPIOC,&GPIO_InitStructure);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_ALL_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_Init(GPIOF,&GPIO_InitStructure); //2.配置中断唤醒引脚GPIO_InitStructure.GPIO_Pin = KEY_FUNC_PIN;//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_Init(GPIOA,&GPIO_InitStructure);NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;NVIC_InitStructure.NVIC_IRQChannelPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Line =EXTI_Line5;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//原理图上按键是上拉的,故而采用下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);}

/*设备正常状态初始化*/static void dev_normal_init(void){f0xx_rcc_configuration();timer15_init();batt_init();all_adc_init();led_init();//buzzer_init(&buzzer);key_init();at24c_register(AT24C02,&at24c02);lcd_init(&lcd);uart1_init();}/*正常模式*/static void dev_normal_entry(void){while(0==lcd.sleep_flag){task_handler();iwtd_feed();}iwtd_feed();//跳出主任务,进入休眠前先喂狗一次 }/*休眠模式*/static void dev_sleep_entry(void){dev_sleep_set();//设备休眠设置rtc_wakeup_set();//RTC唤醒设置dev_normal_init();//唤醒后->恢复IO引脚功能}

/*入口函数*/int main(void){dev_normal_init();iwtd_init();HR_DEBUG("Hey,I was born today!\r\n");__TODO:dev_normal_entry();//正常状态任务HR_DEBUG("Nothing to do, I'm going to sleep!\r\n");dev_sleep_entry();//休眠状态HR_DEBUG("Call me? I have wokenup!\r\n");goto __TODO;}

/*外部中断入口*/void EXTI4_15_IRQHandler(void){if((SET==EXTI_GetITStatus(EXTI_Line4))||(SET==EXTI_GetITStatus(EXTI_Line5))){lcd.sleep_flag=0;lcd.sleep_timer=0;EXTI_ClearITPendingBit(EXTI_Line4);EXTI_ClearITPendingBit(EXTI_Line5);}}/*RTC中断*/void RTC_IRQHandler(void){if(SET==RTC_GetITStatus(RTC_IT_ALRA)){iwtd_feed();//喂狗//测试//lcd.sleep_flag=0;//lcd.sleep_timer=0;RTC_TimeTypeDef RTC_TimeStructure;RTC_TimeStructInit(&RTC_TimeStructure);//使用缺省函数 重置RTC时间 (RTC_Time = 00h:00min:00sec).RTC_GetTime(RTC_HourFormat_12,&RTC_TimeStructure);//获取重置的时间参数RTC_AlarmTypeDef RTC_AlarmStructure;//重置闹钟 (Alarm_Time = 00h:00min:10sec).RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = RTC_TimeStructure.RTC_Seconds+RTC_WKUP_TIME;RTC_SetAlarm(RTC_Format_BIN,RTC_Alarm_A,&RTC_AlarmStructure);RTC_ClearFlag(RTC_FLAG_ALRAF);RTC_ClearITPendingBit(RTC_IT_ALRA);}/*EXTI线17连接到RTC闹钟事件,所以发生中断后需要手动清除标志*/EXTI_ClearITPendingBit(EXTI_Line17);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。