博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32——项目需求之低功耗的停机模式
阅读量:6991 次
发布时间:2019-06-27

本文共 2903 字,大约阅读时间需要 9 分钟。

在说低功耗之前,先要明白一个东西,那就是stm32中的事件和中断。

事件是中断的触发源,开放了对应的中断屏蔽位,则事件可以触发相应的中断。在STM32中,中断与事件不是等价的,一个中断肯定对应一个事件,但一个事件不一定对应一个中断。

当外部有信号输入时,如果通过了事件屏蔽寄存器,那么事件信号就进入脉冲触发器,引发一个脉冲信号,直接传递给相应的外设,用于触发,这就是一个纯硬件的过程,理解DMA的应该知道,这个方式不需要CPU参与,但是这也有它的缺点,如功能比较单一,仅能提供信号,不能提供信息,也就是只能产生指定功能的事件。如果通过中断屏蔽寄存器,就被直接送到CPU中,产生中断,如进入上面的入口函数开始处理。从这就可看出,事件是单纯硬件触发执行的过程,与CPU本身设计支持有关,而中断中则可以软件实现各种功能,而低功耗模式的事件唤醒就是stm32支持的事件之一。

进入停止模式之后,任何外部中断都可以唤醒低功耗,但是需要重新配置时钟,不然系统将以默认时钟(没有经过倍频)运行。

选择事件唤醒低功耗之停止模式,可以更加快速,不需要中断服务函数,自然也不需要配置NVIC的相关寄存器。

进入低功耗库函数:

PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFE);

 

/**  * @brief  Enters STOP mode.  * @param  PWR_Regulator: specifies the regulator state in STOP mode.  *   This parameter can be one of the following values:  *     @arg PWR_Regulator_ON: STOP mode with regulator ON  *     @arg PWR_Regulator_LowPower: STOP mode with regulator in low power mode  * @param  PWR_STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction.  *   This parameter can be one of the following values:  *     @arg PWR_STOPEntry_WFI: enter STOP mode with WFI instruction  *     @arg PWR_STOPEntry_WFE: enter STOP mode with WFE instruction  * @retval None  */void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry){  uint32_t tmpreg = 0;  /* Check the parameters */  assert_param(IS_PWR_REGULATOR(PWR_Regulator));  assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));    /* Select the regulator state in STOP mode ---------------------------------*/  tmpreg = PWR->CR;  /* Clear PDDS and LPDS bits */  tmpreg &= CR_DS_MASK;  /* Set LPDS bit according to PWR_Regulator value */  tmpreg |= PWR_Regulator;  /* Store the new value */  PWR->CR = tmpreg;  /* Set SLEEPDEEP bit of Cortex System Control Register */  SCB->SCR |= SCB_SCR_SLEEPDEEP;    /* Select STOP mode entry --------------------------------------------------*/  if(PWR_STOPEntry == PWR_STOPEntry_WFI)  {       /* Request Wait For Interrupt */    __WFI();  }  else  {    /* Request Wait For Event */    __WFE();  }    /* Reset SLEEPDEEP bit of Cortex System Control Register */  SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);  }

 

可以选择事件和中断唤醒两种方式,选择哪种方式是根据库函数的第二个参数决定的,这是一个宏:

进入低功耗之后,需要事件或者中断去唤醒,这里用RTC闹钟事件选择唤醒mcu。

RTC_SetAlarm( RTC_GetCounter()+600*N);

RTC_ITConfig(RTC_IT_ALR, ENABLE);
RTC_WaitForLastTask();

上面三句话需要放在进入低功耗的函数前,这样当RTC闹钟时间到了之后,在没有其他事件或者中断唤醒的前提下,闹钟会唤醒进入停机模式的mcu。每次操作了RTC,需要等待RTC操作完成,这些在ST库函数中都给我们做好了。

另外需要注意的是,停机模式下,mcu唤醒之后,时钟和频率是没有经过倍频的,在F1上,低功耗唤醒之后,是8M频率运行,而正常运行是72M。所以,在唤醒停机模式之后,需要重新配置时钟。

ST很贴心,直接调用库函数:

SystemInit();

就可以了。那么整体流程就是:

RTC_SetAlarm( RTC_GetCounter()+600*N);            RTC_ITConfig(RTC_IT_ALR, ENABLE);            RTC_WaitForLastTask();            PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFE);            SystemInit();            RTC_WaitForSynchro();

上面的代码,裸机中推荐放在while(1)最后,带os应该在空闲任务中。

Advance:

有低功耗的项目中,看门狗监测目前没有找到好的方式,使用看门狗监测程序但它会破坏低功耗,查询很多资料论坛后,还是选择了放弃看门狗,看门狗被开启,就不能再软件关闭了。

转载地址:http://pjbvl.baihongyu.com/

你可能感兴趣的文章
php 比较运算符
查看>>
for循环效率问题求解答
查看>>
Android so lib库远程http下载和动态注册
查看>>
痞子衡嵌入式:并行接口NAND标准(ONFI)及SLC Raw NAND简介
查看>>
Q-criterion- definition and post-processing
查看>>
单例模式-Singleton
查看>>
OneZero第二周第二次站立会议(2016.3.29)
查看>>
(转)移动开发:Ant自动化打包APK(1)--ANT,Android 环境配置与打包
查看>>
eclipse怎么删除多余的tomcat server(2)
查看>>
python面试题
查看>>
Day10 - Ruby如何调用方法(invoke method)?
查看>>
java中的异常
查看>>
mysql查询重复数据
查看>>
Tesseract 引擎翻译
查看>>
Android之复选框对话框
查看>>
【RabbitMQ系列】队列、绑定、交换器
查看>>
Run as ant build每次都执行两次
查看>>
如何在微信公众号下载保存图片??
查看>>
Spring读书笔记——bean解析
查看>>
算法练习(5)数字列表中 连续最大的和
查看>>