问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

stm32f407待机功耗

发布网友 发布时间:2023-03-07 16:04

我来回答

1个回答

热心网友 时间:2023-10-08 19:57

疑问

在做待机唤醒实验时,会有这样的疑问:只有进入待机模式的代码,那么唤醒是如何唤醒的?

原理

(此节主要针对待机唤醒原理进行简单介绍,可以根据自己情况自动略过)

STM32F4待机模式

在系统或电源复位以后,微控制器处于运行状态。运行状态下的 HCLK 为 CPU 提供时钟,内核执行程序代码。当 CPU不需继续运行时,可以利用多个低功耗模式来节省功耗,例如等待某个外部事件时。
STM32F4 的 3 种低功耗模式
在这三种低功耗模式中,最低功耗的是待机模式,在此模式下,最低只需要 2.2uA 左右的 电流。停机模式是次低功耗的,其典型的电流消耗在350uA 左右。最后就是睡眠模式了。
进入/退出待机模式

拓展:

在进入模式的第三步:将WUF位清零,查看寄存器PWR_CSR。
清零需要通过PWR_CR进行配置:CWUF位置1。
退出模式
根据图1及下面stm32部分时钟树可知,在待机的状态下,PLL、HSI 和 HSE 振荡器被断电、1.2V供电区别断电,可以认为只有LSI、LSE振荡器在工作,因此RTC、独立看门狗可以工作,从而进行待机唤醒。(还有WKUP上升沿、NRST复位)
代码

#include "wkup.h"
#include "led.h"
#include "delay.h"
#include "usart.h"

//系统进入待机模式
void Sys_Enter_Standby(void)
{
while(WKUP_KD);//等待WK_UP按键松开(在有RTC中断时,必须等WK_UP松开再进入待机)

RCC_AHB1PeriphResetCmd(0X04FF,ENABLE);//复位所有IO口

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能PWR时钟

PWR_BackupAccessCmd(ENABLE);//后备区域访问使能

//这里我们就直接关闭相关RTC中断
RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA,DISABLE);//关闭RTC相关中断,可能在RTC实验打开了。
RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA);//清楚RTC相关中断标志位。

PWR_ClearFlag(PWR_FLAG_WU);//清除Wake-up 标志

PWR_WakeUpPinCmd(ENABLE);//设置WKUP用于唤醒

PWR_EnterSTANDBYMode();//进入待机模式

}
//检测WKUP脚的信号
//返回值1:连续按下3s以上
// 0:错误的触发
u8 Check_WKUP(void)
{
u8 t=0;
u8 tx=0;//记录松开的次数
LED0=0; //亮灯DS0
while(1)
{
if(WKUP_KD)//已经按下了
{
t++;
tx=0;
}else
{
tx++;
if(tx>3)//超过90ms内没有WKUP信号
{
LED0=1;
return 0;//错误的按键,按下次数不够
}
}
delay_ms(30);
if(t>=100)//按下超过3秒钟
{
LED0=0; //点亮DS0
return 1; //按下3s以上了
}
}
}
//中断,检测到PA0脚的一个上升沿.
//中断线0线上的中断检测
void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line0); // 清除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_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PA0 连接到中断线0

EXTI_InitStructure.EXTI_Line = EXTI_Line0;//LINE0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0
EXTI_Init(&EXTI_InitStructure);//配置

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中断0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置NVIC

//(检查是否是正常开)机
if(Check_WKUP()==0)
{
Sys_Enter_Standby();//不是开机,进入待机模式
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
此处为wkup.c代码,比较简单,这里不再进行阐述,下面主要针对上述疑问进行解释。(通过查阅资料,自行理解的逻辑)

理解

首先,开机后,从int main()函数进行初始化,进行到WKUP_Init();对PA0进行相关配置,检查是否长按开机键,没有,进入Sys_Enter_Standby()函数,在函数内最后进入待机模式:PWR_EnterSTANDBYMode()。

PWR_EnterSTANDBYMode()配置在原理中已经进行介绍,不再重复,主要针对函数内的WFI进行介绍:
WFI: wait for Interrupt 等待中断,即下一次中断发生前都在此hold住不干活
也就是说:当前大环境是正常运行状态,当运行于此处时,卡住不进行后续代码执行,相当于进行待机处理。
所以在初始化时,运行到WFI就卡在了一个地方

当按键wkup被按下时,其实已经进行了待机唤醒处理,(从按下时,灯光亮了一下就可以看出来,程序已经开始运行了,没有继续卡在原处),此时是从int main()函数第一行开始重新运行。进行到WKUP_Init();对PA0进行相关配置,检查是否长按开机键。

没有按够3s,重复上述1、2步骤;

当按键达到3s后,跳过WKUP_Init()函数中的ifCheck_WKUP()函数,程序正常运行,从而达到唤醒功能。并配置PA0中断方式。

当再次按键达到3s后,进入中断,判断有没有按够3s。时间不够,继续运行正常状态;时间达到3s,Sys_Enter_Standby()
再次进入待机模式。

void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE10上的中断标志位
if(Check_WKUP())//关机?
{
Sys_Enter_Standby(); //进入待机模式
}
}
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
金丝熊,一般吃什么啊?水果还是蔬菜? 怎样管理wp7上安装的软件?我手机是三星i917 》有文件管理软件吗?、我的... 二片式球阀(关于二片式球阀的基本详情介绍) 二片式球阀工作原理 二片式球阀优点 不锈钢二片式球阀安装与维护及注意事项 二片式球阀两片式球阀的结构特点 不锈钢二片式球阀结构特点 不锈钢二片式球阀简介 吃刚出炉的蛋糕致癌? 前程无量的意思 描写祝寿的词语 寿元无量的意思和造句 花中之魁是什么花 花中之魁指的是哪种花 儿子脾气暴躁怎么教育 脾气暴躁的孩如何教育脾气暴躁的孩子怎么教育 如果玉有裂痕还能继续戴吗 我是阳历1981年12月20日半夜0点多出生的。我属什么命,八字,五行都是什么。2009年生肖星座风水等运势如何 锦衣之下陆绎今夏什么时候在一起 西米做月饼怎么泡软 盎司意思是什么 不止有肉!蔬菜也有蛋白质! 浓硫酸和水谁先加 西红柿辣椒如何保鲜西红柿辣椒怎么保鲜 新鲜辣椒怎么保存到冬天吃 喜欢男女不卡性别是什么意思 2022年4月几号开业好 2022年4月有多少适合新店开张开业的好日子 2022年4月最佳开业好日子 2022年4月20日是开张的黄道吉日吗 2022年4月20日开张好吗 有内涵比较诱惑人的女生微信名字 尝遍全世界的甜 欧姆龙数字计数器面板显示SET什么意思? 空调控制面板set是什么意思 和圆有关的诗句 秋声诗句 胡椒产地 一只股票横盘多长时间才能到账 慊然是什么意思 伤感的句子说说心情文案合集(精选140句) 大规模杀伤武器包括 大规模杀伤性武器详细资料大全 人们应如何消除大规模杀伤性武器? 拆空调后要加氟吗 空调拆了需要再加氟吗 咸虾干怎么变淡 昂霄相关成语有哪些 昂耸成语有哪些 22款起亚智跑手自一体怎么用钥匙启动 什么网球拍比较好 网球拍品牌排行前十 在六榕寺为貔貅开光可以吗