STM32实例-待机唤醒实验

发布者:Jinyu521最新更新时间:2022-12-08 来源: zhihu关键字:STM32  待机唤醒  低功耗模式 手机看文章 扫描二维码
随时随地手机看文章

本文我们来学习下STM32的待机唤醒功能。要实现的功能是:系统运行时 D1 指示灯闪烁,5 秒后进入待机模式,D1 指示灯熄灭,同时串口 printf输出相关提示信息,可通过 K_UP 按键实现唤醒。学习本内容可以参考《STM32F10x中文参考手册》-4 电源控制器(PWR)章节。


STM32 低功耗模式介绍

很多单片机具有低功耗模式,比如 MSP430、STM8L等。我们的STM32也不例外。默认情况下,系统复位或上电复位后,微控制器进入运行模式。在运行模式下,HCLK 为 CPU 提供时钟,并执行程序代码。当 CPU 不需继续运行(例如等待外部事件)时,可以利用多种低功耗模式来节省功耗。用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。


当然在运行模式下,也可以通过如下方式降低功耗:

(1)降低系统时钟速度

(2)不使用 APBx 和 AHB 外设时,将对应的外设时钟关闭

STM32 提供了 3 种低功耗模式,以达到不同层次的降低功耗的目的,这三

种模式如下:

(1)睡眠模式( CM3 内核停止工作,外设仍在运行)

(2)停止模式(所有时钟都停止)

(3)待机模式( 1.8 V 内核电源关闭)


这三种模式所需的功耗是逐级递减,也就是说待机模式功耗是最低的。三种低功耗模式汇总表如下图所示:

我们仅对 STM32 的待机模式进行介绍,其他 2 种模式可以参考《STM32F10x 中文参考手册》-4电源控制器(PWR)章节,里面有详细的介绍。

(1)待机模式

在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设, CM3 核心的外设全都照常运行。在停止模式中,进一步关闭了其它所有的时钟,于是所有的外设都停止了工作,但由于其 1.8V 区域的部分电源没有关闭,还保留了内核的寄存器、内存的信息,所以从停止模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码。在待机模式中, 它除了关闭所有的时钟, 还把 1.8V 区域的电源也完全关闭了,也就是说,从待机模式唤醒后,由于没有之前代码的运行记录,只能对芯片复位,重新检测 BOOT 条件,从头开始执行程序。

那么我们如何进入待机模式呢?其实很简单,只要按下图所示待机模式进入与退出步骤的步骤执行就可以了。

上图还列出了退出待机模式的操作,当检测到外部复位(NRST 引脚)、

IWDG 复位、 WKUP 引脚上升沿、 RTC 闹钟事件的上升沿时,微控制器退出待机模式。本文我们是通过 WKUP 引脚(PA0)上升沿来退出待机模式,当然也可以直接通过芯片复位管脚 NRST退出。

从待机模式唤醒后,除了电源控制/状态寄存器(PWR_CSR),所有的寄存器豆被复位,程序将按照复位(启动引脚采样、复位向量已获取等)后的方式重新执行。电源控制/状态寄存器(PWR_CSR)将会指示内核由待机状态退出。

在进入待机模式后,除了复位引脚以及被设置为防侵入或校准输出时的

TAMPER (PC13)引脚和被使能的唤醒引脚( WK_UP 脚(PA0)),其他的 IO 引脚都将处于高阻态。

由于篇幅限制,本文并没有对待机模式相关寄存器进行介绍,大家可以参考《STM32F10x 中文参考手册》-4 电源控制器(PWR)章节,里面有详细的讲解。如果看不懂的可以暂时放下,因为我们使用的是库函数开发。

待机模式配置步骤

接下来我们介绍下如何使用库函数进入和退出待机模式。这个也是在编写程序中必须要了解的。

具体步骤如下:(电源管理相关库函数在 stm32f10x_pwr.c和 stm32f10x_pwr.h 文件中)

(1)使能电源时钟

因为低功耗模式是通过 STM32 电源(PWR)系统进行管理的,所以需要使能电源时钟,调用的库函数为:

(2)设置 WK_UP 引脚为唤醒源

待机唤醒方式有很多种,我们选择 WK_UP 引脚(PA0)上升沿来退出待机模式。在库函数中,设置使能 WK_UP 用于唤醒 CPU 待机模式的函数是:

因为按键 K_UP 连接在PA0 管脚上,并且是高电平有效,这样一来就可以使用 K_UP按键来退出待机模式。

(3)进入待机模式

进入待机模式, 首先要设置 SLEEPDEEP 位 ( 详见 《 Cortex M3 权威指南(中文)》 , chpt13 Cortex-M3 的其它特性--电源管理章节) ,接着我们通过 PWR_CR设置 PDDS 位,使得 CPU 进入深度睡眠时进入待机模式,最后执行 WFI 指令开始进入待机模式,并等待 WK_UP 中断的到来。整个操作可以通过一个库函数完成,如下:

通常在进入待机模式前,我们会清除唤醒标志,以等待下次进入。清除唤醒标志库函数为:

以上几步全部配置好后,我们就可以正常进入待机模式了,并且可以通过按键 K_UP或者复位按键唤醒。

特别提醒下,如果学到 RTC 实时时钟实验的时候,需要进入待机模式,如果使能了 RTC 闹钟中断的时候,进入待机模式前,必须按如下操作处理:

1.禁止 RTC 中断( ALRAIE、 ALRBIE、 WUTIE、 TAMPIE 和 TSIE 等)。

2.清零对应中断标志位。

3.清除 PWR 唤醒(WUF)标志(通过设置 PWR_CR 的 CWUF 位实现)。

4.重新使能 RTC 对应中断。

5.进入低功耗模式。

本实验使用到硬件资源如下:

(1)D1 指示灯

(2)串口 1

(3)K_UP 按键

D1指示灯、K_UP 按键、串口 1 电路在前面章节都介绍过,这里不多说。D1指示灯用来提示系统正常运行,K_UP 按键用来唤醒待机模式,串口 1 用来输出提示信息。

所要实现的功能是:系统运行时 D1 指示灯闪烁,5 秒后进入待机模式,D1 指示灯熄灭,同时串口 printf 输出相关提示信息,通过 K_UP 按键实现唤醒。

程序框架如下:

(1)配置进入与退出待机模式

(2)编写主函数

前面介绍待机模式配置步骤时,就已经讲解如何配置。下面我们打开“待机唤醒实验”工程,在 APP 工程组中可以看到添加了wkup.c文件(里面包含了待机模式驱动程序),在 StdPeriph_Driver 工程组中添加了 stm32f10x_pwr.c 库文件。电源系统管理相关操作的库函数都放在stm32f10x_pwr.c 和 stm32f10x_pwr.h 文件中,所以使用到电源系统管理就必须加入 stm32f10x_pwr.c 文件,同时还要包含对应的头文件路径。

这里我们分析几个重要函数,其他部分程序大家可以打开工程查看。

待机模式配置函数

要让系统进入待机模式,我们必须对它进行配置。进入待机模式代码如下:

该函数首先使能电源PWR时钟,然后清除唤醒标志位,并使能 WK_UP管脚为唤醒方式,最后进入待机模式。这一过程在前面步骤介绍中已经提了。

主函数

配置待机模式后,我们就可以编写主函数,代码如下:

主函数实现的功能很简单,首先调用之前编写好的硬件初始化函数,包括

SysTick 系统时钟,中断分组,LED 初始化等。然后进入 while 循环,每间隔一秒让 printf 输出一个信息,同时指示灯状态发生变化。倒计 5 秒钟后,调用函数 Enter_Standby_Mode进入待机模式,此时指示灯熄灭。

将工程程序编译后下载到开发板内,可以看到系统运行时 D1 指示灯不断闪烁,5 秒钟后进入待机模式,此时 D1 指示灯熄灭。当按下 K_UP 按键或复位按键时,待机模式被唤醒,系统重新运行,同时串口打印提示信息。如果想在串口调试助手上看到输出信息,可以打开“串口调试助手”,首先勾选下标号 1 DTR 框,然后再取消勾选。这是因为此串口助手启动时会把系统复位住, 通过 DTR 状态切换下即可。然后设置好波特率等参数后,串口助手上即会收到 printf发送过来的信息。(串口助手上先勾选下标号1 DTR框,然后再取消勾选)如下图所示。

实验说明:下载待机唤醒实验程序后,若使用普中 ARM 仿真器下载其他的程序会出现报警,这是因为处于低功耗模式时,所有外设时钟都已关闭,所以需要在下载程序前先复位下系统。


关键字:STM32  待机唤醒  低功耗模式 引用地址:STM32实例-待机唤醒实验

上一篇:STM32L0 系列 EEPROM 读写,程序卡死?
下一篇:基于 STM32 设计的指针式电子钟与日历

推荐阅读最新更新时间:2024-11-13 11:42

STM32定时器的预装寄存器以及影子寄存器话题
经常有人问起预装寄存器和影子寄存器的话题,其实STM32相关系列的手册里有介绍,有文档做介绍,这里借花献佛地一起分享下。 在谈预装寄存器及影子寄存器的差别前,不妨先对STM32定时器的时基单元做个基本了解。STM32各系列的定时器结构和框架基本是一样的,时基单元也一样。 下面时基单元是以STM32F3系列为参考。 时基单元中的TIMx_PSC、 TIM_ARR两个寄存器加上捕捉比较模块中TIMX_CCR寄存器,它们都可以动态修改。不过他们的修改和生效可能不在同一个时刻,这里便引入了预装寄存器及影子寄存器的概念。要记住一点,真正在TIMER模块中起作用的是影子寄存器。 1、用户程序对TIMx_PSC寄存器值的修
[单片机]
<font color='red'>STM32</font>定时器的预装寄存器以及影子寄存器话题
STM32实战1:按键点亮LED小灯 hh
#include sys.h #include key.h void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//初始化时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPI
[单片机]
STM32自带GB2312字库显示汉字
  本文介绍如何把字库文件写入单片机的flash中,然后无需再提取字模,即可实现单片机显示中文字符的功能。 下载字库到单片机flash中的指定位置   在上一篇博客中,最后留了一个想法,让单片机自带字库。现在就来实现这个想法。 我把用到的编译过的字符放在这里   我们借助J-Flash软件把bin文件放在单片机flash中的指定位置。   首先要新建工程,然后根据自己的板子选择型号   然后打开数据文件,找到刚刚下载的bin文件   根据自己单片机的flash大小输入地址,注意这个地址要与代码中的“基地址”一致   设置好以后按下快捷键F7   成功烧录以后,代码不可以在使用此区域。——一般情况下,你的
[单片机]
<font color='red'>STM32</font>自带GB2312字库显示汉字
stm32库函数下,输出可调频率pwm
//////////////////////////////////////////////////////////// //基于库函数的不完全代码 //////////////////////////////////////////////////////////// TIM3_PWM_Init(899,0); //不分频。PWM频率=72000000/900=80Khz while(1) { TIM3- ARR=led0pwmval+50; //改变此句话的值,调节pwm频率 TIM_SetCompare2(TIM3,49); delay_ms(500); led0pwmval++; if(led0
[单片机]
使用CubeMX创建BLE应用
1、CubeMX介绍 应用优势 帮助MCU选型 在设计阶段尽可能模拟实际应用场景 自动代码生成,增加开发速度 设置选项 STM32CubeMX需要Java RE环境 安装之后,按Alt+S来配置更新器——不仅用于GUI,还用于Cube FW库 选择软件库存放位置 更新管理器 可以从“帮助”菜单中访问更新 工具更新器可以检测工具和CubeMX库的新版本 使用库管理器下载新的库包 MCU选择器 通过名字查找MCU 方便查找文档 输出Excel表格 MCU交叉选择器 引脚分配 2、功耗测量插件 使用PCC 通用PCC参数 MCU选择:可以直接从网站获取datasheet 参数选
[单片机]
STM32硬件IIC
1 /** 2 * @brief 写一个字节到I2C设备中 3 * @param 4 * @arg pBuffer:缓冲区指针 5 * @arg WriteAddr:写地址 6 * @retval 正常返回1,异常返回0 7 */ 8 uint8_t I2C_ByteWrite(u8 pBuffer, u8 WriteAddr) 9 { 10 /* Send STRAT condition */ 11 I2C_GenerateSTART(macI2Cx, ENABLE); 12 13 I2CTimeout = I2CT_FLAG_TIMEOUT; 14 15 16 /*
[单片机]
stm32 基本定时器最简单定时配置
最近用到了定时器的定时功能,了解了下,stm32的定时器功能很强大,东西也挺多的,datasheet里也说了一大段,这个我就不详说了,这儿只说明下如何配置最简单的定时功能配置。 环境说明:MCU:stm32F4系列,用的是通用定时器TIM3 首先要知道的是TIM3 是挂载到APB1总线上的,这点详见STM32F417xx_datasheet-P.19,有个框图叫Device overview,算了,还是截个图 而APB1 的时钟是多少呢?这个得看你自己配置的多少了,一般是在SetSysClock()函数里,我这儿是系统时钟的4分频,系统时钟这儿为168MHz,所以APB1上的时钟为42MHz,这儿不要以为TIM3
[单片机]
<font color='red'>stm32</font> 基本定时器最简单定时配置
一例使用STM32外设库设置串口速度与实际不一样的解决
最近手上有了块金牛的stm32实验板,兴致勃勃的测试各种功能,但是碰到一个问题,用stm32 的外设库写串口程序,发现串口速度与实际不一样。一度怀疑是外设库的问题,但是用mdk的外设监控查看后,发现实际的串口速度为自定义的3倍,如图 很疑惑,本人有一种钻牛角尖的精神,因此一度debug下去,发现这个设置是在如下关键语句 (位于 外设库 中的 USART_Init定义语句,在stm32f10x_usart.c中) USART_Init初始化函数 RCC_GetClocksFreq(&RCC_ClocksStatus); if (usartxbase == USART1_BASE) { apbclock = RCC_ClocksSt
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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