最近使用到低功耗方案,采用的是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);
#else   RTC_StructInit(&RTC_InitStructure); //缺省配置,主要应用于LSE(32.768KHz)
#endif  RTC_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);
//HHMMSS    RTC_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);
}

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

  1. cortex_m3_stm32嵌入式学习笔记(十五):待机唤醒实验(WK_UP外部中断)

    cortex_m3_stm32嵌入式学习笔记(十五):待机唤醒实验(WK_UP外部中断) https://blog.csdn.net/qq_16255321/article/details/43086 ...

  2. 蓝桥杯单片机之独立按键+外部中断

    独立按键原理 一般情况下,独立按键有两个引脚,其中一个通过上拉电阻接到单片机的I/O端口,另外一端接地.也就是说,平时按键没有动作的时候,输出的是高电平,如果有按下动作发生,则输出的是低电平.那么,我 ...

  3. 51单片机外部中断实验 设置中断优先级寄存器,当有外部中断0请求中断时,中断程序执行发光二极管程序,在此过程中,外部中断1也有中断请求,外部中断0的中断程序将被中断去执行外部中断1的中断程序(数码管

    设置中断优先级寄存器,当有外部中断0请求中断时,中断程序执行发光二极管程序,在此过程中,外部中断1也有中断请求,外部中断0的中断程序将被中断去执行外部中断1的中断程序(数码管加1显示程序). #inc ...

  4. 51单片机实验——按键外部中断实现四进制计数器

    1.实验题目: 设计一个通过触发外部中断INT1实现的在0-3之间计数(四进制)的计数器,并通过P1.6和P1.7端口上的LED,显示计数的值. 2.KEIL代码 #include <reg51 ...

  5. nrf52840 gpiote如何配置中断输入_STM32第四章外部中断管理

    点击上方"果果小师弟",选择"置顶/星标公众号"干货福利,第一时间送达!STM32F4 的每个 IO 都可以作为外部中断的中断输入口,这点也是 STM32F4 ...

  6. 单片机c语言 外部中断,单片机C语言代码:外部中断,按下中断按键LED不亮,LED1正常亮...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 * 名称:外部中断 * 日期:2013-9-10 * 晶振:11.0592MHZ ************************************ ...

  7. c语言按键怎么用中断防抖,按键外部中断的时候如何防抖?

    本帖最后由 275891381 于 2018-3-1 21:36 编辑 volatile u64 xitong_haomiao;           //2^64/1000/3600/24/365=5 ...

  8. 02讲 | 51单片机按键外部中断实现LED灯的亮灭

    前言 专栏内容持续补充更新,目前正在进行优惠活动! 目录 一.按键中断控制原理 二.外部中断实现 LED 灯亮灭功能代码

  9. 龙芯1B:按键外部中断例程

    目录 前言 一.什么是外部中断? 1.外部中断:单片机实时地处理外部事件的一种内部机制. 二.外部中断程序开发步骤 1.步骤 2.函数介绍 GPIO中断API函数介绍: ​编辑 3.外部中断代码 总结 ...

最新文章

  1. android 调用系统相机
  2. spring mvc DispatcherServlet详解之一---处理请求深入解析
  3. Remoting 配置格式说明(转)
  4. 冠榕智能灯光控制协议分析(node-controller)
  5. 数据结构-树2-二叉树各种函数实现
  6. java多线程信息共享 多线程管理
  7. 几个简单的Makefile
  8. CRM中复制记录的方法
  9. 忽然发现自己少了很多爱好。。。。。。。。。
  10. Keil(MDK) 5 软件安装教程
  11. 坚果云云盘告诉你如何保护自己的文件不被泄露?
  12. php菱形,PHP 打印菱形
  13. selenium 浏览器打开新标签页
  14. win7重装系统后计算机打不开,win7系统重装后进不了系统怎么办
  15. Dragonfly——一款功能强大的在线家庭装潢设计软件
  16. java 交易金额转换分,java金额元与分转换工具种
  17. Mysql数据库MMM实现高可用架构
  18. 敏捷研发(Scrum)
  19. ValueError: With n_samples=0, test_size=0.2 and train_size=None, the resulting train set will be emp
  20. c++中find函数解析

热门文章

  1. html设置弹性盒子分配自适应比例,移动端弹性布局flex,CSS3自适应
  2. python什么是形参?
  3. PGSQL 日期时间的比较
  4. 利达主机联网接线端子_利达主机怎么编辑中文 利达主机接线端子说明
  5. js清除cookie有时无法清除
  6. 【大数据开发】大数据开发的一些基本概念
  7. 【Java集合】集合是什么?为什么要用集合?
  8. 一个基于Web服务器的PoW区块链案例
  9. [note]如何删除linux内核
  10. 今天又get到一个小技能,collect_set函数