- 睡眠模式(内核停止,外设运行)
- 停机模式(所有时钟都停止)
- 待机模式(1.8V内核电源也关闭)
- DBP[8]:取消后备区域的写保护 位 8 在复位后,RTC和后备寄存器处于被保护状态以防意外写入。0:禁止写入RTC和后备寄存器 1:允许写入RTC和后备寄存器
- PLS[ 7:5 ]:PVD电平选择。 这些位用于选择电源电压监测器的电压阀值。
- PVDE[4]:电源电压监测器(PVD)使能。 0:禁止PVD 1:开启PVD
- CSBF[3]:清除待机位,始终读出为0。 0:无功效 1:清除SBF待机位(写)
- CWUF[2]:清除唤醒位,始终读出为0。 0:无功效 1:2个系统时钟周期后清除WUF唤醒位(写)
- PDDS[1]:掉电深睡眠,与LPDS位协同操作。 0:当CPU进入深睡眠时进入停机模式,调压器的状态由LPDS位控制。 1:CPU进入深睡眠时进入待机模式。
- LPDS[0]:深睡眠下的低功耗。PDDS=0时,与PDDS位协同操作 0:在停机模式下电压调压器开启 1:在停机模式下电压调压器处于低功耗模式
- EWUP[8]:使能WKUP引脚 ,在系统复位时清除这一位。
- PVDO[2]:PVD输出 ,当PVD被PVDE位使能后该位才有效。
- SBF[1]:待机标志。
- WUF[0]:唤醒标志。
01 | //THUMB指令不支持汇编内联 |
02 | //采用如下方法实现执行汇编指令WFI |
03 | __asm void WFI_SET(void) |
04 | { |
05 | WFI; |
06 | } |
07 |
08 |
09 | //进入待机模式 |
10 | //参数说明: |
11 | // var = 0 ,设定为睡眠模式 |
12 | // var = 1 ,设定为停机模式,电流消耗在20uA左右 |
13 | // var = 2 ,设定为待机模式,电流消耗在2uA左右 |
14 |
15 | void Sys_Standby(u8 var) |
16 | { |
17 |
18 | RCC->APB1ENR |= 1<<28; //使能电源时钟 |
19 |
20 | switch(var) |
21 | { |
22 | case 0:{ break; } //WFI进入睡眠模式 |
23 |
24 | case 1:{ //PDDS+LPDS+SLEEPDEEP+WFI进入停机模式 |
25 |
26 | SCB->SCR |= 1<<2; //使能SLEEPDEEP位 (SYS->CTRL) |
27 | PWR->CR |= 1<<0; //LPDS置位 |
28 | PWR->CR |= 1<<1; //PDDS置位 |
29 | break; |
30 | } |
31 |
32 | case 2:{ //PDDS+SLEEPDEEP+WFI进入待机模式 |
33 |
34 | SCB->SCR |= 1<<2; //使能SLEEPDEEP位 (SYS->CTRL) |
35 | PWR->CR|=1<<1; //PDDS置位 |
36 | break; |
37 | } |
38 | } |
39 |
40 | PWR->CR |= 1<<2; //清除Wake-up 标志 |
41 | PWR->CSR |= 1<<8; //允许写入RTC和BKP寄存器 |
42 | WFI_SET(); //执行WFI指令 |
43 | } |
44 |
45 |
46 | //系统软复位 |
47 |
48 | void Sys_Soft_Reset(void) |
49 | { |
50 | SCB->AIRCR =0X05FA0000|(u32)0x04; |
51 | } |
01 | #include |
02 | #include "system.h" |
03 | #include "wdg.h" |
04 | #include "exti.h" |
05 |
06 | #define LED1 PAout(4) |
07 | #define LED2 PAout(5) |
08 |
09 | #define PWR_MODE_Sleep 0 //开启睡眠模式 |
10 |
11 | #define PWR_MODE_STOP 1 //开启停机模式 |
12 |
13 | #define PWR_MODE_STANDBY 0 //开启待机模式 |
14 |
15 |
16 | void Gpio_Init(void); |
17 |
18 | int main(void) |
19 | { |
20 | u32 i= 10,j=10; |
21 |
22 | Rcc_Init(9); //系统时钟设置 |
23 |
24 | Exti_Init(GPIO_A,0,FTIR); //设置PA1为下降沿触发,参数GPIO_x 和 FTIR 在system.h中有定义 |
25 |
26 | Nvic_Init(0,0,EXTI0_IRQChannel,0); //设置外部中断 |
27 |
28 | Gpio_Init(); |
29 |
30 | while(i--){ |
31 |
32 | LED1 = !LED1; |
33 |
34 | delay(30000); //延时30ms |
35 |
36 | } |
37 |
38 | #if PWR_MODE_Sleep //睡眠模式,外部中断唤醒后会复位 |
39 |
40 | Sys_Standby(0); |
41 |
42 | #elif PWR_MODE_STOP //停机模式,外部中断唤醒,唤醒后复位 |
43 |
44 | Sys_Standby(1); |
45 |
46 | #elif PWR_MODE_STANDBY //待机模式,由独立看门狗唤醒,唤醒后会初始化,LED闪烁5次后,暗一段时间 |
47 |
48 | Iwdg_Init(3,2000); //设置为1.6s内不喂狗复位,使用独立看门狗唤醒,唤醒后复位 |
49 |
50 | Sys_Standby(2); |
51 |
52 | #endif |
53 |
54 |
55 | while(j--){ //这段程序用于检验唤醒后是否会继续运行后面的程序,还是会导致复位 |
56 |
57 | LED2 = !LED2; |
58 |
59 | delay(10000); //延时10ms |
60 |
61 | } |
62 | } |
63 |
64 |
65 | void Gpio_Init(void) |
66 | { |
67 | RCC->APB2ENR|=1<<2; //使能PORTA时钟 |
68 |
69 | GPIOA->CRL&=0x0000FFFF; // PA0~3设置为浮空输入,PA4~7设置为推挽输出 |
70 | GPIOA->CRL|=0x33334444; |
71 |
72 | } |
01 | #include "stm32f10x_it.h" |
02 | #include "system.h" |
03 |
04 | #define LED1 PAout(4) |
05 | #define LED2 PAout(5) |
06 | #define LED3 PAout(6) |
07 | #define LED4 PAout(7) |
08 |
09 |
10 | void EXTI0_IRQHandler(void) |
11 | { |
12 | LED4 = !LED4; |
13 | EXTI->PR = 1<<0; //清除中断标志位 |
14 | } |
待机相关代码参见 system.c文件中
001 | #include "stm32f10x.h" |
002 | #include "stdio.h" |
003 |
004 | #define PRINTF_ON 1 |
005 |
006 | void RCC_Configuration(void); |
007 | void GPIO_Configuration(void); |
008 | void NVIC_Configuration(void); |
009 | void EXTI_Configuration(void); |
010 | void IWDG_Configuration(void); |
011 |
012 | #define PWR_MODE_Sleep 0 //开启睡眠模式 |
013 |
014 | #define PWR_MODE_DeepSleep 1 //开启停机模式 |
015 |
016 | #define PWR_MODE_STANDBY 0 //开启待机模式 |
017 |
018 |
019 | vu32 DelayTime = 10000000; |
020 |
021 | int main(void) |
022 | { |
023 | RCC_Configuration(); |
024 | GPIO_Configuration(); |
025 | NVIC_Configuration(); |
026 | EXTI_Configuration(); |
027 |
028 | SysTick_Config(10000000); |
029 |
030 | while(--DelayTime); |
031 |
032 | #if PWR_MODE_Sleep //睡眠模式 |
033 |
034 | PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI); //唤醒后时钟变为内置8MHz |
035 |
036 | #elif PWR_MODE_DeepSleep //停机模式 |
037 |
038 | PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI); //唤醒后时钟变为内置8MHz |
039 |
040 | #elif PWR_MODE_STANDBY //待机模式 |
041 |
042 | IWDG_Configuration(); //设置为2s内不喂狗复位,使用独立看门狗唤醒 |
043 |
044 | PWR_EnterSTANDBYMode(); //唤醒后会初始化程序 |
045 |
046 | #endif |
047 |
048 | while(1); |
049 |
050 | } |
051 |
052 | void IWDG_Configuration(void) |
053 | { |
054 | RCC_LSICmd(ENABLE); //打开LSI |
055 | while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET); |
056 |
057 | IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); |
058 | IWDG_SetPrescaler(IWDG_Prescaler_32); |
059 | IWDG_SetReload(2000); //max 0xFFF 0~4095 |
060 | IWDG_ReloadCounter(); |
061 | IWDG_Enable(); |
062 | } |
063 |
064 | void GPIO_Configuration(void) |
065 | { |
066 | GPIO_InitTypeDef GPIO_InitStructure; |
067 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
068 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_7; |
069 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; |
070 | GPIO_Init(GPIOA , &GPIO_InitStructure); |
071 |
072 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; |
073 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; |
074 | GPIO_Init(GPIOA , &GPIO_InitStructure); |
075 |
076 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; |
077 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
078 | GPIO_Init(GPIOA , &GPIO_InitStructure); |
079 |
080 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; |
081 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; |
082 | GPIO_Init(GPIOA , &GPIO_InitStructure); |
083 |
084 | GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); |
085 | } |
086 |
087 |
088 | void RCC_Configuration(void) |
089 | { |
090 | /* 定义枚举类型变量 HSEStartUpStatus */ |
091 | ErrorStatus HSEStartUpStatus; |
092 |
093 | /* 复位系统时钟设置*/ |
094 | RCC_DeInit(); |
095 | /* 开启HSE*/ |
096 | RCC_HSEConfig(RCC_HSE_ON); |
097 | /* 等待HSE起振并稳定*/ |
098 | HSEStartUpStatus = RCC_WaitForHSEStartUp(); |
099 | /* 判断HSE起是否振成功,是则进入if()内部 */ |
100 | if(HSEStartUpStatus == SUCCESS) |
101 | { |
102 | /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */ |
103 | RCC_HCLKConfig(RCC_SYSCLK_Div1); |
104 | /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */ |
105 | RCC_PCLK2Config(RCC_HCLK_Div1); |
106 | /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */ |
107 | RCC_PCLK1Config(RCC_HCLK_Div2); |
108 | /* 设置FLASH延时周期数为2 */ |
109 | FLASH_SetLatency(FLASH_Latency_2); |
110 | /* 使能FLASH预取缓存 */ |
111 | FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); |
112 | /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */ |
113 | RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); |
114 | /* 使能PLL */ |
115 | RCC_PLLCmd(ENABLE); |
116 | /* 等待PLL输出稳定 */ |
117 | while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); |
118 | /* 选择SYSCLK时钟源为PLL */ |
119 | RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); |
120 | /* 等待PLL成为SYSCLK时钟源 */ |
121 | while(RCC_GetSYSCLKSource() != 0x08); |
122 | } |
123 | /* 打开APB2总线上的GPIOA时钟*/ |
124 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE); |
125 |
126 | //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); |
127 |
128 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); |
129 | //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG, ENABLE); |
130 |
131 | } |
132 |
133 |
134 | void USART_Configuration(void) |
135 | { |
136 | USART_InitTypeDef USART_InitStructure; |
137 | USART_ClockInitTypeDef USART_ClockInitStructure; |
138 |
139 | USART_ClockInitStructure.USART_Clock = USART_Clock_Disable; |
140 | USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; |
141 | USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge; |
142 | USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; |
143 | USART_ClockInit(USART1 , &USART_ClockInitStructure); |
144 |
145 | USART_InitStructure.USART_BaudRate = 9600; |
146 | USART_InitStructure.USART_WordLength = USART_WordLength_8b; |
147 | USART_InitStructure.USART_StopBits = USART_StopBits_1; |
148 | USART_InitStructure.USART_Parity = USART_Parity_No; |
149 | USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; |
150 | USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; |
151 | USART_Init(USART1,&USART_InitStructure); |
152 |
153 | USART_Cmd(USART1,ENABLE); |
154 | } |
155 |
156 | void EXTI_Configuration(void) |
157 | { |
158 | EXTI_InitTypeDef EXTI_InitStructure; |
159 |
160 | EXTI_InitStructure.EXTI_Line = EXTI_Line0; |
161 | EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; |
162 | EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; |
163 | EXTI_InitStructure.EXTI_LineCmd = ENABLE; |
164 |
165 | EXTI_Init(&EXTI_InitStructure); |
166 |
167 | } |
168 |
169 | void NVIC_Configuration(void) |
170 | { |
171 | NVIC_InitTypeDef NVIC_InitStructure; |
172 |
173 | NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); |
174 |
175 | NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; |
176 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; |
177 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; |
178 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
179 | NVIC_Init(&NVIC_InitStructure); |
180 | } |
181 |
182 | #if PRINTF_ON |
183 |
184 | int fputc(int ch,FILE *f) |
185 | { |
186 | USART_SendData(USART1,(u8) ch); |
187 | while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); |
188 | return ch; |
189 | } |
190 |
191 | #endif |
01 | #include "stm32f10x_it.h" |
02 |
03 | #include "stdio.h" |
04 |
05 |
06 | void EXTI0_IRQHandler(void) |
07 | { |
08 | GPIO_WriteBit(GPIOA,GPIO_Pin_7,Bit_SET); |
09 |
10 | //EXTI_ClearFlag(EXTI_Line0); //清除此中断标志位,系统由于唤醒将直接复位 |
11 |
12 | } |
13 |
14 | void SysTick_Handler(void) |
15 | { |
16 | GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_4))); |
17 | } |
上一篇:GPIO的操作
下一篇:STM32低功耗实验总结
推荐阅读最新更新时间:2024-03-16 14:38
设计资源 培训 开发板 精华推荐
- 希润医疗孟铭强:手功能软体机器人,让脑卒中患者重获新生
- 柔灵科技陈涵:将小型、柔性的脑机接口睡眠设备,做到千家万户
- 微灵医疗李骁健:脑机接口技术正在开启意识与AI融合的新纪元
- USB Type-C® 和 USB Power Delivery:专为扩展功率范围和电池供电型系统而设计
- 景昱医疗耿东:脑机接口DBS治疗技术已实现国产替代
- 首都医科大学王长明:针对癫痫的数字疗法已进入使用阶段
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件