STM32待机模式学习笔记
2014-09-05 14:17
246 查看
STM32待机模式学习笔记
STM32内置低功耗模式,在系统或电源复位之后,微控制器处于运行状态,当CPU不需要继续运行时,可以利用多种低功耗模式来节省功耗。例如,等待某个外部事件,用户需要更具最低电源功耗,最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。
STM32F10xxx有三种低功耗模式:
●睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时 钟(SysTick)等仍在运行)
。
●停止模式(所有的时钟都已停止)
●待机模式(1.8V电源关闭)
此外,在运行模式下,可以通过以下方式中的一种降低功耗:
●降低系统时钟
●关闭APB和AHB总线上未被使用的外设时钟。
表 1:低功耗模式一览表
三种模式中,最低功耗的就是待机模式,在此模式下,最低只需要2uA左右的电流,其次是停机模式,大概需要20uA左右的电流,最后就是睡眠模式了,
STM32 的最低功耗模式-待机模式
待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个 1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。
进入待机模式:
关于如何进入待机模式,详见表2:
表2:待机模式
可以通过设置独立的控制位,选择以下待机模式的功能:
● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了
独立看门狗,除了系统复位,它不能再被停止。 (可参考看门狗章节笔记)
● 实时时钟(RTC):通过备用区域控制寄存器(RCC_BDCR)的RTCEN位来设置。
● 内部RC振荡器(LSI RC):通过控制/状态寄存器(RCC_CSR)的LSION位来设置。
● 外部32.768kHz振荡器(LSE):通过备用区域控制寄存器(RCC_BDCR)的LSEON位设置。
退出待机模式
从待机模式退出的方式共有4种:外部复位(NRST引脚)、IWDG复位、WKUP引脚上的上升沿或者RTC闹钟事件的上升沿发生。
从待机唤醒后,除了电源控制/状态寄存器(PWR_CSR),所有寄存器被复位。
从待机模式唤醒后的代码执行等同于复位后的执行(采样启动模式引脚、读取复位向量等)。电源控制/状态寄存器(PWR_CSR)将会指示内核由待机状态退出。
根据表2可以知道,配置过程中需要两个寄存器,即电源控制寄存器(PWR_CR)和电源控制/状态寄存器(PWR_CSR)。
下表是对这两个寄存器简介:
电源控制寄存器(PWR_CR) :
地址偏移:0x00
复位值:0x0000 0000 (从待机模式唤醒时清除)
通过设置PWR_CR的PDDS位,使CPU进入深睡眠时进入待机模式,CWUF位是清除唤醒位。
电源控制/状态寄存器(PWR_CSR) :
地址偏移:0x04
复位值:0x0000 0000 (从待机模式唤醒时不被清除)
与标准的APB读相比,读此寄存器需要额外的APB周期
通过设置PWR_CSR的EWUP位,设置为WKUP引脚用于唤醒,可用从WUF位来检测是否被唤醒。
/*******进入待机模式,以及wkup唤醒设置步骤**************
1.使能电源时钟
2.设置 WK_UP 引脚作为唤醒源
3.设置 SLEEPDEEP 位,设置 PDDS 位,执行 WFI 指令,进入待机模式
4.最后编写 WK_UP 中断函数
********************************************************/
STM32内置低功耗模式,在系统或电源复位之后,微控制器处于运行状态,当CPU不需要继续运行时,可以利用多种低功耗模式来节省功耗。例如,等待某个外部事件,用户需要更具最低电源功耗,最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。
STM32F10xxx有三种低功耗模式:
●睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时 钟(SysTick)等仍在运行)
。
●停止模式(所有的时钟都已停止)
●待机模式(1.8V电源关闭)
此外,在运行模式下,可以通过以下方式中的一种降低功耗:
●降低系统时钟
●关闭APB和AHB总线上未被使用的外设时钟。
表 1:低功耗模式一览表
三种模式中,最低功耗的就是待机模式,在此模式下,最低只需要2uA左右的电流,其次是停机模式,大概需要20uA左右的电流,最后就是睡眠模式了,
STM32 的最低功耗模式-待机模式
待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个 1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。
进入待机模式:
关于如何进入待机模式,详见表2:
表2:待机模式
可以通过设置独立的控制位,选择以下待机模式的功能:
● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了
独立看门狗,除了系统复位,它不能再被停止。 (可参考看门狗章节笔记)
● 实时时钟(RTC):通过备用区域控制寄存器(RCC_BDCR)的RTCEN位来设置。
● 内部RC振荡器(LSI RC):通过控制/状态寄存器(RCC_CSR)的LSION位来设置。
● 外部32.768kHz振荡器(LSE):通过备用区域控制寄存器(RCC_BDCR)的LSEON位设置。
退出待机模式
从待机模式退出的方式共有4种:外部复位(NRST引脚)、IWDG复位、WKUP引脚上的上升沿或者RTC闹钟事件的上升沿发生。
从待机唤醒后,除了电源控制/状态寄存器(PWR_CSR),所有寄存器被复位。
从待机模式唤醒后的代码执行等同于复位后的执行(采样启动模式引脚、读取复位向量等)。电源控制/状态寄存器(PWR_CSR)将会指示内核由待机状态退出。
根据表2可以知道,配置过程中需要两个寄存器,即电源控制寄存器(PWR_CR)和电源控制/状态寄存器(PWR_CSR)。
下表是对这两个寄存器简介:
电源控制寄存器(PWR_CR) :
地址偏移:0x00
复位值:0x0000 0000 (从待机模式唤醒时清除)
通过设置PWR_CR的PDDS位,使CPU进入深睡眠时进入待机模式,CWUF位是清除唤醒位。
电源控制/状态寄存器(PWR_CSR) :
地址偏移:0x04
复位值:0x0000 0000 (从待机模式唤醒时不被清除)
与标准的APB读相比,读此寄存器需要额外的APB周期
通过设置PWR_CSR的EWUP位,设置为WKUP引脚用于唤醒,可用从WUF位来检测是否被唤醒。
/*******进入待机模式,以及wkup唤醒设置步骤**************
1.使能电源时钟
2.设置 WK_UP 引脚作为唤醒源
3.设置 SLEEPDEEP 位,设置 PDDS 位,执行 WFI 指令,进入待机模式
4.最后编写 WK_UP 中断函数
********************************************************/
/** ****************************************************************************** * @file wkup.c * @author zhangkeyan * @version V1.0 * @date 2014-09-03 * @brief 待机唤醒 驱动代码 ****************************************************************************** * @attention * ****************************************************************************** */ #include "wkup.h" #include "led.h" #include "delay.h" /*******进入待机模式,以及wkup唤醒设置步骤************** 1.使能电源时钟 2.设置 WK_UP 引脚作为唤醒源 3.设置 SLEEPDEEP 位,设置 PDDS 位,执行 WFI 指令,进入待机模式 4.最后编写 WK_UP 中断函数 ********************************************************/ void SYS_StandBy(void) { NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); //使能PWR和BKP外设时钟 PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能 PWR_EnterSTANDBYMode(); //进入待命(STANDBY)模式 } //系统进入待机模式 void SYS_Enter_StandBy(void) { RCC_APB2PeriphResetCmd(0X01FC,DISABLE); SYS_StandBy(); } //检测WKUP脚的信号 //返回值1:连续按下3s以上 // 0:错误的触发 u8 Check_WKUP(void) { u8 counter = 0; u8 counter_num = 0; //记录松开的次数 LED0 = 0; //点亮 DS0 while(1) { if(WKUP_KD) { counter ++; counter_num = 0; } else { counter_num ++; //超过300ms内没有WKUP信号 if(counter_num > 3) { LED0 = 1; return 0; } } delay_ms(30); if(counter >100) //3s之后WKUP_KD信号一直存在 { LED0 = 0; return 1; } } } //中断,检测到PA0脚的一个上升沿. //中断线0线上的中断检测 void EXTI0_IRQHandler(void) { EXTI->PR=1<<0; //清除LINE10上的中断标志位 if(Check_WKUP())//关机? { SYS_Enter_StandBy(); } } /********PA0 WKUP唤醒初始化**********/ void WKUP_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;//上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //使用外部中断方式 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line0; //设置按键所有的外部线路 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设外外部中断模式:EXTI线路为中断请求 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 if(Check_WKUP()==0) SYS_StandBy(); //不是开机,进入待机模式 }
/** ****************************************************************************** * @file wkup.h * @author zhangkeyan * @version V1.0 * @date 2014-09-03 * @brief 待机唤醒 驱动代码 ****************************************************************************** * @attention * ****************************************************************************** */ #ifndef __WKUP_H #define __WKUP_H #include "sys.h" #define WKUP_KD PAin(0) //PA0 检测是否外部WK_UP按键按下 u8 Check_WKUP(void); //检测WKUP脚的信号 void WKUP_Init(void); //PA0 WKUP唤醒初始化 void SYS_Enter_StandBy(void); //系统进入待机模式 #endif
#include "delay.h" #include "sys.h" #include "usart.h" #include "led.h" #include "lcd.h" #include "rtc.h" #include "wkup.h" const u8 *COMPILED_DATE=__DATE__; const u8 *COMPILED_TIME=__TIME__; /*************主函数*************/ int main(void) { delay_init(72); NVIC_Configuration(); uart_init(9600); LED_Init(); //LED初始化 LCD_Init(); RTC_Init(); WKUP_Init(); POINT_COLOR = RED; //设置字体颜色为红色 LCD_ShowString(60,130," WKUP TEST"); LCD_ShowString(60,150,"zhangkeyan"); LCD_ShowString(60,170,"2014-9-5"); while(1) { LED0 = !LED0; delay_ms(250); } }
相关文章推荐
- STM32学习笔记之待机唤醒
- cortex_m3_stm32嵌入式学习笔记(十五):待机唤醒实验(WK_UP外部中断)
- STM32学习笔记之低功耗模式的机制
- C#面向对象设计模式纵横谈学习笔记(1)
- 设计模式学习笔记1:对设计模式学习的一点想法兼谈Facade模式
- 设计模式学习笔记(1)
- 设计模式学习笔记(5)
- 设计模式学习笔记(三)
- IOC模式的学习笔记
- 设计模式的学习笔记!(一)
- 学习笔记之ORM设计中用到的模式
- 设计模式学习笔记5:Singleton模式及其Delphi实现
- JAVA与模式 学习笔记(一) 统一的建模语言UML介绍(1)
- [设计模式学习笔记之一]面向对象是什么?
- [设计模式学习笔记之一]面向对象是什么?
- 设计模式学习笔记2:说说Mediator模式
- 设计模式学习笔记(一)
- JAVA与模式 学习笔记(一) 统一的建模语言UML介绍(2)
- 设计模式学习笔记(2)
- 设计模式学习笔记4:对接口进行包装的Adapter