一、最近在搞stm32L151C8T6的低功耗模式。

项目场景:

提示:这里简述项目相关背景:
LoRa低功耗,用到stm32L151C8T6+sx1278,SPI通信。本文主要讲述stm32L151低功耗问题——待机模式。
以下代码理论10s唤醒一次,时间可自由设置,详细配置之代码注释有


问题描述:

不废话直接上代码:
LowPower.c文件:

#include "LowPower.h"
#include "stm32l1xx_rtc.h"
#include "stm32l1xx.h"
#include "stm32l1xx_exti.h"
#include "misc.h"
#include "stm32l1xx_rcc.h"
#include "stm32l1xx_pwr.h"//RTC 时钟配置
void rtc_init(void) {RTC_InitTypeDef RTC_InitStructure;RTC_TimeTypeDef  RTC_TimeStruct;EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;/* Enable the PWR clock */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);/* Allow access to RTC */PWR_RTCAccessCmd(ENABLE);RTC_WaitForSynchro();/* Reset RTC Domain */RCC_RTCResetCmd(ENABLE);RCC_RTCResetCmd(DISABLE);/* Enable the LSI OSC */RCC_LSICmd(ENABLE);/* Wait till LSE is ready */while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);/* Select the RTC Clock Source */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);//选用LSI是低速内部时钟,RC振荡器,频率为40kHz/* Configure the RTC data register and RTC prescaler */RTC_InitStructure.RTC_AsynchPrediv = 0x7F;RTC_InitStructure.RTC_SynchPrediv = 0xFF;RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;RTC_Init(&RTC_InitStructure);/* Set the time to 00h 00mn 00s AM */RTC_TimeStruct.RTC_H12     = RTC_H12_AM;RTC_TimeStruct.RTC_Hours   = 0x00;RTC_TimeStruct.RTC_Minutes = 0x00;RTC_TimeStruct.RTC_Seconds = 0x00;  RTC_SetTime(RTC_Format_BIN, &RTC_TimeStruct);/* Enable the RTC Clock */RCC_RTCCLKCmd(ENABLE);/* Wait for RTC APB registers synchronisation */RTC_WaitForSynchro();}// 设置RTC 报警时间间隔
void RtcAlarmTime_Set(void)
{RTC_AlarmTypeDef RTC_AlarmStructure;RTC_GetTime(RTC_Format_BIN, &(RTC_AlarmStructure.RTC_AlarmTime));//10在分钟的时候可以换成任意值;但是当要秒,屏蔽分钟时必须是5的倍数,这和RTC_AlarmSubSecondConfig函数有关。/***注意:实际测试时间在lora板上总是比理论设置的时间要快,基本上10s要快上1s;这是由于晶振或者电容不匹配原因,本人猜测电容原因很大***/// RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = (RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes+10);   //实际唤醒时间为:9min左右唤醒一次RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = (RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds+10);       //秒唤醒时间,必须为5的倍数printf("rtc %d, %d, %d", RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours, RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes, RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds);/* Set the alarmA Masks *///RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay|RTC_AlarmMask_Hours|RTC_AlarmMask_Seconds;  //屏蔽不需要的参数RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay|RTC_AlarmMask_Hours|RTC_AlarmMask_Minutes;  //屏蔽不需要的参数RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
}//RTC定时器A的配置
void platform_rtc_set_alarmA(void) {EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RTC_AlarmTypeDef RTC_AlarmStructure;EXTI_ClearITPendingBit(EXTI_Line17);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; //使能LINE17EXTI_Init(&EXTI_InitStructure);/* Enable the RTC Wakeup Interrupt */NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn; //RTC_Alarm_IRQn RTC_WKUP_IRQnNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);RtcAlarmTime_Set();RTC_GetTime(RTC_Format_BIN, &RTC_AlarmStructure.RTC_AlarmTime);RTC_AlarmSubSecondConfig(RTC_Alarm_A, 0xFF, RTC_AlarmSubSecondMask_SS14_5);/* Enable AlarmA interrupt */RTC_ITConfig(RTC_IT_ALRA, ENABLE);RTC_AlarmCmd(RTC_Alarm_A, ENABLE); //开启闹钟ARTC_ClearITPendingBit(RTC_IT_ALRA); //清除RTC闹钟A的标志EXTI_ClearITPendingBit(EXTI_Line17); //清除LINE17上的中断标志位}
void Sys_Standby1(void) {PWR_ClearFlag(PWR_FLAG_WU);RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);        //使能PWR外设时钟printf("\r\n entry stop mode!\n ");PWR_EnterSTANDBYMode();   ///进入待命(STANDBY)模式
}//定时器唤醒处理中断,待机模式不进入中断,stop模式才会进入//void RTC_Alarm_IRQHandler(void) {//    if (RTC_GetITStatus(RTC_IT_ALRA) != RESET) {//
//        RTC_ClearITPendingBit(RTC_IT_ALRA);
//           RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
//        RtcAlarmTime_Set();
//        EXTI_ClearITPendingBit(EXTI_Line17);
//              printf("请求111111n");
//    }
//}

main.c函数:

int main()
{//系统初始化//串口初始化//。。。初始化rtc_init();   //RTC初始化platform_rtc_set_alarmA();   //RTC闹钟唤醒配置while(1){//要执行的程序............Sys_Standby1(); //进入待机模式}
}

注意事项:

  1. 时钟问题
    在第二部分为什么说是理论10s呢?因为我在测试的时候发现真正唤醒的时间是8s/9s的样子,基本上设置10s会快上1s左右,2min快上12s左右,10min快上一分钟。这就有点离谱了,后来有看到网有在网上说这是因为晶振或者电容不匹配导致的,内部时钟好像确实不准确。可以换为外部晶振更加精准,电容的话就需要在焊板子的时候选用了,这暂时超纲了,不谈。
  2. 是否进入中断
    standy待机模式不进入中断,stop模式进入,详细见网有博客:停机和待机唤醒程序入口
  3. 中断标志清除
    对于Alarm唤醒来说,主要是Alarm初始化是要注意中断标志位。
    对于停机唤醒要格外注意在中断服务函数种清除用到的中断标志位。

心得:

  1. wakeup唤醒,最多可实现33s左右时间的唤醒,想要达到更高时间就无法使用。Alarm使用这样的计算方法一样可以达到周期性唤醒单片机:
RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = (RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds+10);  //秒唤醒时间,必须为5的倍数
  1. Alarm唤醒,Alarm唤醒不进入闹钟中断函数,到时间就自动唤醒后,自动重新设置Alram。stop模式更复杂,会进入中断函数,必须进行中断标志位的清除,否则会影响下一次唤醒。

stm32L151低功耗学习——Alarm闹钟周期唤醒(10s/10min/10h)相关推荐

  1. [STM32F1]STM32 低功耗待机模式与RTC周期唤醒

    STM32等类似Cortex-M3的MCU在系统或电源复位以后,MCU就会处于程序运行状态.当用户不需继续运行程序时,可以利用进入低功耗模式来节省电池电量,当需要重新运行时,可以通过特定条件进行唤醒程 ...

  2. 【STM32笔记】低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER)

    [STM32笔记]低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_5340 ...

  3. 【极海APM32替代笔记】低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER)

    [极海APM32替代笔记]低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_ ...

  4. STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例)

    STM32CubeMX | STM32 F1系列HAL库低功耗STOP和STANDBY模式唤醒(RTC时钟唤醒+外部中断唤醒示例) 目录 STM32CubeMX | STM32 F1系列HAL库低功耗 ...

  5. 【STM32笔记】HAL库低功耗模式配置(ADC唤醒无法使用、低功耗模式无法烧录解决方案)

    [STM32笔记]HAL库低功耗模式配置(ADC唤醒无法使用.低功耗模式无法烧录解决方案) [STM32笔记]低功耗模式配置及避坑汇总 一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需 ...

  6. React学习:生命周期、过滤器、event、axios-学习笔记

    文章目录 React学习:生命周期.过滤器.event.axios-学习笔记 生命周期 过滤器 webapp小例子: event - 和原生JavaScript写法一样的 axios React学习: ...

  7. Ubuntu的快乐学习2——SnowBoy语音唤醒

    Ubuntu的快乐学习2--SnowBoy语音唤醒 学习前言 安装步骤 一.麦克风检测部分 1.安装pulseaudio和sox 2.安装其它软件依赖 二.获取源代码 学习前言 为了部落! 安装步骤 ...

  8. STM32L151低功耗项目笔记(CO传感器TGS5042)

    这是以前做过的一个项目,我们理论不多说,直接上代码,根据代码来记录 CO传感器型号为TGS5042,使用STM32L151 ADC采样,计算CO的数值,使用Standby模式. 本文工程源码下载地址 ...

  9. STM32GX低功耗学习笔记一

    最近要用到低功耗功能,看了下手册,把学习过程记录下,其中也有一些不明白的地方期望和大家进行交流. 首先来看看低功耗模式有哪些: 再看看怎么进入低功耗: 在这里我选择了STOP0模式: 在这里,我有一点 ...

  10. android Alarm闹钟发送广播播放音乐

    MusicService.java service播放音乐 MainActivity.java package com.yqy.yqy_alarm; import java.util.Calendar ...

最新文章

  1. 计算机怎么设置本地硬盘启动不了,电脑bios怎么设置硬盘启动
  2. Android之BaseAdapter使用
  3. 用 Flask 来写个轻博客 (34) — 使用 Flask-RESTful 来构建 RESTful API 之三
  4. python怎么画条形图-python使用Matplotlib画条形图
  5. 什么是时间管理,一个大四学生的简单理解
  6. Breaking the Ledger Security Model
  7. 服务器指定网卡进行备份数据避免影响业务口
  8. COCOS2D-X 不反复随机数
  9. 自动化测试方案_2第二章、自动化测试是什么?(What)
  10. lua语言实现阴阳师自动脚本(内含可运行程序)
  11. 转 可以word ,excel ,pdf ,ppt 导入和导出的思维导图
  12. h5调用手机相机和录音机_html5 调用手机摄像头以及录音的方法
  13. WYSE S10、WYSE V90、HP T5740瘦客机评测
  14. JavaEE - 集合 - Collection集合
  15. 使用蓝牙模块和笔记本自带蓝牙通讯
  16. ArcEngine中的ICommand和ITool
  17. win10电脑声音调节图标上有个红叉
  18. ioc的概念和实现原理
  19. 代码阅读——十个C开源项目
  20. 普通二本,学这些东西,也能进大厂

热门文章

  1. 关于入门小白对java这种面向对象编程语言的封装、继承、多态的理解
  2. 什么是锁?有几种锁?怎么用锁?
  3. 一个页面中有两个iframe
  4. 《大学之路》读后感(1)
  5. html:制作简易京东导航栏
  6. 狐吧吧刊——遇见最好的浏览器(1-6期)
  7. silvaco仿真遇到的bug和解决方案
  8. 2015年终总结和2016年的计划
  9. MPEG音频文件格式(包括MP3文件格式)详解
  10. windows平台Emacs单实例原理、设置及右键菜单的添加