stm32低功耗实验之待机模式

发布者:喜悦的38号最新更新时间:2017-09-12 来源: eefocus关键字:stm32  低功耗实验  待机模式 手机看文章 扫描二维码
随时随地手机看文章

一 待机模式简介

  在stm32的低功耗模式中,待机模式可以实现系统的最低功耗,在这种模式下,只需要2uA左右的电流。





三 待机唤醒程序分析

实验现象:

  将程序下载到开发板上后,LED灯会不断地亮灭,当按下KEY2键超过3s时,LED灯灭,标志着单片机进入待机模式,再按下KEY1键,这时唤醒单片机,LED又开始不断地亮灭亮灭。


程序中用到的一些宏定义


  1. #define             macEXTI_GPIO_CLK                        (RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO)       

  2. #define             macEXTI_GPIO_PORT                       GPIOC     

  3. #define             macEXTI_GPIO_PIN                        GPIO_Pin_13  

  4. #define             macEXTI_SOURCE_PORT                     GPIO_PortSourceGPIOC  

  5. #define             macEXTI_SOURCE_PIN                      GPIO_PinSource13  

  6. #define             macEXTI_LINE                            EXTI_Line13  

  7. #define             macEXTI_IRQ                             EXTI15_10_IRQn  

  8. #define             macEXTI_INT_FUNCTION                    EXTI15_10_IRQHandler  




主函数:


  1. int main(void)  

  2. {     

  3.     /* config the led */  

  4.     LED_GPIO_Config();  

  5.       

  6.     /* exti line config */  

  7.     EXTI_Pxy_Config();  //初始化中断函数  

  8.       

  9.     USARTx_Config();      

  10.       

  11.     if(PWR_GetFlagStatus(PWR_FLAG_WU) == SET)  

  12.     {  

  13.         printf("\r\n使能电源管理时钟单元前的检测,待机唤醒复位 \r\n");  

  14.   

  15.     }  

  16.     else  

  17.         printf("\r\n 使能电源管理时钟单元前的检测,上电复位 \r\n");  

  18.       

  19.       

  20.       

  21.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);  

  22.       

  23.       

  24.     if(PWR_GetFlagStatus(PWR_FLAG_WU) == SET)  

  25.     {  

  26.         printf("\r\n 使能后检测,待机唤醒复位\r\n");  

  27.   

  28.     }  

  29.     else  

  30.         printf("\r\n 使能后检测,上电复位 \r\n");  

  31.       

  32.       

  33.     while(1)                              

  34.     {     

  35.           

  36.         LED1( ON );            

  37.         Delay(0xFFFFF);  

  38.         LED1( OFF );            

  39.   

  40.         LED2( ON );             

  41.         Delay(0xFFFFF);  

  42.         LED2( OFF );            

  43.   

  44.         LED3( ON );             

  45.         Delay(0xFFFFF);  

  46.         LED3( OFF );            

  47.       

  48.     }  

  49. }  

分析:在主函数中,除了用到一些必要的初始化之外,就是while循环,在while循环中点亮LED灯,唯一不太熟悉的是几个printf语句,这里暂时不管,先看EXTI_Pxy_Config()函数。



EXTI_Pxy_Config()函数



  1. void EXTI_Pxy_Config(void)  

  2. {  

  3.     GPIO_InitTypeDef GPIO_InitStructure;   

  4.     EXTI_InitTypeDef EXTI_InitStructure;  

  5.   

  6.     /* config the extiline clock and AFIO clock */  

  7.     RCC_APB2PeriphClockCmd(macEXTI_GPIO_CLK,ENABLE);  //开启GPIO时钟和AFIO时钟  

  8.                                                   

  9.     /* config the NVIC */  

  10.     NVIC_Configuration();  

  11.   

  12.     /* EXTI line gpio config*/    

  13.   GPIO_InitStructure.GPIO_Pin = macEXTI_GPIO_PIN;         

  14.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //配置为上拉输入  

  15.   GPIO_Init(macEXTI_GPIO_PORT, &GPIO_InitStructure);  

  16.   

  17.     /* EXTI line mode config */  

  18.   GPIO_EXTILineConfig(macEXTI_SOURCE_PORT, macEXTI_SOURCE_PIN);   

  19.   EXTI_InitStructure.EXTI_Line = macEXTI_LINE;  

  20.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  

  21.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  //设置为上升沿触发中断!!!,也就是当单片机检测到按键的上升沿时进入中断程序  

  22.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;  

  23.   EXTI_Init(&EXTI_InitStructure);   

  24. }  

分析:在EXTI_Pxy_Config()函数中,先进行了KEY2按键的初始化,注意KEY2按键并不是WKUP按键,一定要注意。然后将KEY2按键的IO口配置为EXTI中断模式,上升沿触发,也就是说当KEY2按键被按下时就会触发中断。然后我们再分析当按键KEY2被按下时,执行的相应中断函数。



macEXTI_INT_FUNCTION()函数


  1. /// IO口线中断,中断口为PC13  

  2. void macEXTI_INT_FUNCTION(void)  

  3. {  

  4.     if(EXTI_GetITStatus(macEXTI_LINE) != RESET) //确保是否产生了EXTI Line中断  

  5.     {  

  6.           

  7.         printf("\r\n 进入EXTI Line中断\r\n");         

  8.           

  9.         // K2 键长按进入待机模式  

  10.         if(PWR_Check_Standby())  //PWR_Check_Standby()函数是用来判断按键时长的,如果按键时间长超过3S就返回1,否则返回0  

  11.         {  

  12.             //使能WKUP引脚的唤醒功能  

  13.             PWR_WakeUpPinCmd (ENABLE);  

  14.               

  15.             //进入待机模式  

  16.             PWR_EnterSTANDBYMode();  

  17.         }  

  18.         EXTI_ClearITPendingBit(macEXTI_LINE);     //清除中断标志位  

  19.     }    

  20. }  

分析:当KEY2按键被按下时,触发了中断,单片机去执行中断函数,首先检测按下的时长是否超过了3s,现在我们假设超过了3s,那么单片机就会执行这两条语句


  1. PWR_WakeUpPinCmd (ENABLE); //设置了WKUP引脚的唤醒功能,不用过多分析  

  2. PWR_EnterSTANDBYMode();  

很明显,这两个函数是stm32库提供给我们的,同时这两个函数才是单片机进入待机模式的关键!!!



PWR_EnterSTANDBYMode();

要分析这个函数,就必须翻看stm32的参考手册了。


上面这张表表明单片机如何进入stm32的待机模式,需要设置三个位,然后再执行一个WFI或者WFE指令即可。PWR_EnterSTANDBYMode()函数就是做了这四件事。


  1. void PWR_EnterSTANDBYMode(void)  

  2. {  

  3.   /* Clear Wake-up flag */  

  4.   PWR->CR |= PWR_CR_CWUF;  //将PWR_CR的CWUF位置为1,置为1的效果是经过2个系统时钟周期后清除WUF唤醒位  

  5.   /* Select STANDBY mode */  

  6.   PWR->CR |= PWR_CR_PDDS;  //将PWR_CR的PDDS位置为1,置为1的效果是CPU进入深睡眠时进入待机模式  

  7.   /* Set SLEEPDEEP bit of Cortex System Control Register */  

  8.   SCB->SCR |= SCB_SCR_SLEEPDEEP;  //将SCB_SCR_SLEEPDEEP的位置为1,置为1的效果是当进入深睡眠模式时,以运行停止系统时钟  

  9. /* This option is used to ensure that store operations are completed */  

  10. #if defined ( __CC_ARM   )  

  11.   __force_stores();  

  12. #endif  

  13.   /* Request Wait For Interrupt */  

  14.   __WFI();  //调用__WFI()函数进入待机模式  

  15. }  

注意:1 程序中没有直接设置WUF位,因为WUF位是PWR_CSR寄存器控制的,同时WUF上写着是该位由硬件置位(这里是我猜测的,具体我也不是很清除,但是并不妨碍我们写程序)


2 SLEEPDEEP这个位可以在CM3权威指南上找到


这样单片机就进入了待机模式。


待机模式唤醒:

通过上表11我们可以看到退出待机模式有四种方法:

(1)WKUP引脚的上升沿(也就是我们程序中使用的方法)

(2)RTC闹钟

(3)NRST引脚上外部复位

(4)IWDG复位


当单片机进入待机模式时,按键KEY1按下,给一个高电平,就会看到单片机从待机模式下苏醒过来。

注意:单片机从待机模式下苏醒过来,效果和按下复位键差不多,程序又开始从头执行,保存的一些变量也会丢失




程序思路的整理:

程序上电执行时并不会立即进入低功耗模式,因为我们设置的是上升沿中断,在中断函数中进入低功耗模式的这样一个思路,而程序刚开始运行时,K2上并没有电平上升或下降沿的变化,K2按键被按下,触发一个上升沿中断,在中断程序里面判断按键按下的时间,当时间超过3s时,先使能WUP引脚的唤醒功能,并进入待机模式,在待机模式的状态下,单片机低功耗运行。当需要唤醒时,注意,单片机是不会执行任何程序的,中断程序也不会,因为单片机在待机模式下就像人睡着了一样,什么事都不会做。另外需要注意,WKUP引脚是不需要配置的,只要给一个上升沿,单片机就会从低功耗模式下唤醒,这个上升沿可以是任何种形式,在野火的程序中只不过是通过一个按键的形式给出罢了。



建议:1 建议大家在学习STM32一段时间后,就应该学会看stm32的数据手册,其实我们看到很多讲stm32的书,帖子,博客,基本都是把stm32手册上的内容翻译出来了,但是无论别人讲的多么好,始终不如自己去翻看手册得到的内容多。


参考资料: 正点原子《stm32开发指南v1.0》

                     野火MINI开发板待机模式程序

                    stm32参考手册

程序的下载地址:http://download.csdn.net/detail/qq_27312943/9631374


关键字:stm32  低功耗实验  待机模式 引用地址:stm32低功耗实验之待机模式

上一篇:STM32F407定时器11之PWM
下一篇:STM32启动文件分析

推荐阅读最新更新时间:2024-03-16 15:36

STM32开发笔记83: SX1268驱动程序设计(芯片复位)
单片机型号:STM32L053R8T6 本系列开发日志,将详述SX1268驱动程序的整个设计过程,本篇介绍芯片复位驱动程序。 一、数据手册 1、NRESET是芯片第15引脚,低有效。 2、通过15引脚NREST,可以达到完整的芯片复位。复位后,会执行标准的校准程序,先前的内容将丢失。复位最短时间为50us,给100us较为合适。 3、这张图是芯片各个模式的引脚的状态表,可以看到除复位模式外,其余模式NREST引脚的状态都为IN PU,其意思是输入上拉,其上拉值为50K。 二、程序 1、由于其内部上来,我们可以给出低功耗的程序,不将单片机控制NREST的引脚设置为输出,而设置为analog引脚,程序如下: c
[单片机]
<font color='red'>STM32</font>开发笔记83: SX1268驱动程序设计(芯片复位)
STM32入门之LED控制
为什么要学STM32? STM32是32位的单片机却只要八位单片机的价格,速度也是八位的好几倍。 更重要的是它作为ARM入门级的芯片比较容易掌握,网上资料也很多,很多人都在用。 STM32的IO端口有7个寄存器来控制,但是我们常用的就4个CRL CRH IDR ODR . 端口配置低寄存器(GPIOx_CRL) 端口配置高寄存器(GPIOx_CRH) 端口输入数据寄存器(GPIOx_IDR) 端口输出数据寄存器(GPIOx_ODR) 其中CRL 控制高8位的 IO CRH 低8 这两个实质是一样的。 对照我们AVR来看GPIOx_CRL就相当于DDRx ,GPIOx_ODR就相当于PORTx,G
[单片机]
STM32的串口采用DMA方式接收数据测试
环境: 主机:WINXP 开发环境:MDK4.23 MCU:STM32F103CBT6 说明: 串口可以配置成用DMA的方式接收数据,不过DMA需要定长才能产生接收中断,如何接收可变长度的数据呢? 方法有以下3种: 1.将RX脚与一路时钟外部引脚相连,当串口一帧发完,即可利用此定时器产生超时中断.这个实时性较高,可以做到1个字节实时监测. 2.不改变硬件,开启一个定时器监控DMA接收,如果超时则产生中断.这个实时性不高,因为超时时间必须要大于需要接收帧的时间,精度不好控制. 3.STM32单片机有的串口可以监测总线是否处于空闲,如果空闲则产生中断.可以用它来监测DMA接收是否完毕.这种方式
[单片机]
<font color='red'>STM32</font>的串口采用DMA方式接收数据测试
STM32 IAP(对flash进行读写)
/************************************************************ **实验名称: **功能: **注意事项: **作者: *************************************************************/ #include STM32Lib\\\\\\\\\\\\\\\\stm32f10x.h #include hal.h #define FLASH_ADR 0x08008000 //要写入数据的地址 #define FLASH_DATA 0x5a5a5a5a //要写入的数据 int main(void) { u32 tmp;
[单片机]
STM32的IO口输入输出模式的理解
最近在看数据手册的时候,发现在Cortex-M3里,对于GPIO的配置种类有8种之多: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_IPU 上拉输入 (5)GPIO_Mode_Out_OD 开漏输出 (6)GPIO_Mode_Out_PP 推挽输出 (7)GPIO_Mode_AF_OD 复用开漏输出 (8)GPIO_Mode_AF_PP 复用推挽输出 一、推挽输出:可以输出高、低电平,连接数字器件;推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。高
[单片机]
<font color='red'>STM32</font>的IO口输入输出<font color='red'>模式</font>的理解
STM32外设DMA使用总结
STM32外设DMA使用总结: 1、根据需要选择DAM模式: (1)循环模式—DMA_Mode = DMA_Mode_Circular (2)正常模式—DMA_Mode = DMA_Mode_Normal 2、对于DMA1的Chanel3,对应外设为USART3的RX 试想:如果串口接收中断和DAM中断同时打开,CPU如何相应? (1)中断优先级不同:这好说,支持嵌套中断(NVIC)的Cortex-M3自然优先服务中断优先级高的 (2)中断优先级相同:处理原则,先来先处理;若同时到来,中断号低的优先处理 查询手册可知,DMA(IRQn number 13)会先于USART3(39)被CPU处理 3、设置DMA模式为循环模式,则:
[单片机]
STM32开发笔记90: SX1268驱动程序设计(数据缓存)
单片机型号:STM32L053R8T6 本系列开发日志,将详述SX1268驱动程序的整个设计过程,本篇介绍数据缓存的相关驱动程序。 一、工作原理 二、接收模式的数据缓存 In receive mode RxBaseAddr specifies the buffer offset in memory at which the received packet payload data will be written. The buffer offset of the last byte written in receive mode is then stored in RxDataPointer which is init
[单片机]
<font color='red'>STM32</font>开发笔记90: SX1268驱动程序设计(数据缓存)
怎么使用C语言控制硬件
C语言的应用编程在单片机的领域占了很大一部分,使用的比较多的51单片机和STM32单片机都可以使用MDK软件编写固件。 单片机烧写了固件后可以点亮LED灯,可以驱动ADC检测电压,也可以驱动蜂鸣器发声,这就是简单地控制硬件。稍微复杂一点的,可以驱动NRF2401进行无线的连接,也可以使用ESP8266这类wifi芯片连接网络。 接下来,简单地讲讲如何使用C语言控制硬件。 1、电路连接 简单的模块可以直接使用高低电平来控制,比如红外线发射模块,当你在驱动引脚上的电压达到3.3v,就能发出红外线;然后将电平设置为0v,红外线发射就停止了。 一般而言,单片机的引脚输出电压能够达到3.3v,也是可以点亮红外线LED,但是可能会导致
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved