stm32 低功耗设计[操作寄存器+库函数]

发布者:雅致书香最新更新时间:2015-11-10 来源: eefocus关键字:stm32  低功耗设计  操作寄存器  库函数 手机看文章 扫描二维码
随时随地手机看文章
stm32的低功耗模式有三种:
 
  • 睡眠模式(内核停止,外设运行)
  • 停机模式(所有时钟都停止)
  • 待机模式(1.8V内核电源也关闭)
 
在这三种模式中,最低功耗的是待机模式,在此模式下,最低只需要2uA左右的电流。整个1.8V供电区被断电,PLL、HSI、HSE振荡器都被关闭。SRAM和寄存器内容丢失。停机模式是次低功耗的的,其典型的电流损耗在20uA左右。最后就是睡眠模式。
                        
stm32低功耗一览表
standby.png
 
这三种低功耗模式,唤醒后程序都会初始化运行。在例子中做了一番论证,结果如此。
 
直接操作寄存器
 
进入待机模式的通用步骤,其中涉及到2个寄存器,也就是电源控制寄存器(PWR_CR)和电源控制/状态寄存器(PWR_CSR)。
 
电源控制寄存器(PWR_CR),该寄存器的各位描述如下:
这是一个低9位有效的寄存器。
  • DBP[8]:取消后备区域的写保护 位 8 在复位后,RTC和后备寄存器处于被保护状态以防意外写入。0:禁止写入RTC和后备寄存器  1:允许写入RTC和后备寄存器 
  • PLS[ 7:5 ]:PVD电平选择。 这些位用于选择电源电压监测器的电压阀值。
                000:2.2V         100:2.6V             001:2.3V         101:2.7V
                010:2.4V         110:2.8V             011:2.5V         111:2.9V 
  • 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:在停机模式下电压调压器处于低功耗模式

 

电源控制寄存器(PWR_CR),该寄存器的各位描述如下:
低9位有效的寄存器,只用了4位,其他位保留
  • EWUP[8]:使能WKUP引脚 ,在系统复位时清除这一位。 
  • PVDO[2]:PVD输出 ,当PVD被PVDE位使能后该位才有效。 
  • SBF[1]:待机标志。
  • WUF[0]:唤醒标志。 
待机函数实现:(参见 system.c文件)

 

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 }
代码如下:(system.h 和 stm32f10x_it.h 等相关代码参照 stm32 直接操作寄存器开发环境配置
User/main.c
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 }
User/stm32f10x_it.c
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文件中

[page]
库函数操作
 
main.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
stm32f10x_it.c
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 }

关键字:stm32  低功耗设计  操作寄存器  库函数 引用地址:stm32 低功耗设计[操作寄存器+库函数]

上一篇:GPIO的操作
下一篇:STM32低功耗实验总结

推荐阅读最新更新时间:2024-03-16 14:38

毕业设计| 球上自平衡机器人
该机器人根据陀螺仪的位姿数据,通过三个全向轮驱动底部球体调整自己在球上的位置,保持动态平衡的同时实现全向移动。 保持动态平衡过程需要对机器人进行运动学分析 自平衡控制问题转化为三步:输入X、Y角度—控制器计算—输出A、B、C电机转速的控制模型。 # 控制器设计 # 首先考虑参考平衡车控制,球上自平衡机器人本质上依然是一个一阶倒立摆问题 这里参考了飞思卡尔直立车的控制方法,采用串级PID控制器,外环PD角度环,内环速度PI环。 由于我的驱动方案选择的是42步进电机,在速度闭环的时候有些问题。正常的直流电机+编码器的控制方案可以通过编码器将轮子的真实速度计算出来,从而和控制器的理想转速作差,实现速度控制。 而我这里的速度闭
[单片机]
毕业设计| 球上自平衡机器人
STM32和CAN总线在温度监控系统中的应用
  引言   现代工业控制领域通常要测量很多信号,将其转化为计算机可以识别的二进制信号,并利用计算机监视和记录各种测量的信号。这个过程就要涉及到信号的采集和处理。CAN总线是一种串行多主总线,它卓越的特性、极高的可靠性和独特的设计,特别适合工业过程监控设备的互连,因此,越来越受到工业界的重视,并已公认为最有前途的现场总线之一。本文介绍了基于STM32和CAN总线的温度监控系统的设计,通过上位机与下位机的通信,实现对温度数据的监控,并经初步实验达到了设计的要求。   1 系统总体方案概述   系统总体框图如图1所示,本系统采用主站+从站的结构,CAN主站主要实现温度数据的存储以及CAN总线协议和串口协议之间的桥接,CAN 从站主
[单片机]
<font color='red'>STM32</font>和CAN总线在温度监控系统中的应用
stm32的adc总结
在时间应用中对模拟信号的采集非常多,我们经常使用到的是ADC采集,模数转换。stm32自己带有adc采集接口,一些总结如下:
[单片机]
<font color='red'>stm32</font>的adc总结
STM32标准库编译成lib库文件
目录: 1、建立创建lib的工程 2、将库文件拷贝到工程目录 3、选择芯片:STM32F407VG 4、选择NO。因为这不是可运行的程序,这里不需要加入启动文件 5、创建完工程后,工程结构如图 6、MDK中点击工具栏上的 设置工程结构,并将库文件加入工程 7、完成后MDK下的目录结构 8、MDK下设置输出选项 9、设置C语言预编译宏和引用目录 10、设置完成后 11、将stm32f4xx_conf.h文件拷贝到工程 12、到此,工程设置完成。按F7编译,经过一支烟的时间即可生成库的lib 13、工程输出目录 14、将库文件加入该工程 15、新建工程,我命名成stm32f4use,处理器依旧选择STM32F407VG 16、这是选
[单片机]
<font color='red'>STM32</font>标准库编译成lib库文件
MSP430F5529 DriverLib 库函数学习笔记(六)定时器A产生PWM波
平台:Code Composer Studio 10.3.1 MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP) 1.通过Timer_A_outputPWM配置产生PWM波 所选输出引脚为P1.2 初始化函数 #define TIMER_PERIOD 12500 void Timer_A_PWM_Init(void) { Timer_A_outputPWMParam htim = {0}; //P1.2复用输出 GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_
[单片机]
MSP430F5529 DriverLib <font color='red'>库函数</font>学习笔记(六)定时器A产生PWM波
STM32学习笔记:USART串口的使用
1. 串口的基本概念 在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互联网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。还可以使用DMA方式,实现高速数据通信。 USART通过3个引脚与其他设备连接在一起,任何USART双向通信至少需要2个引脚:接受数据输入(RX)和发送数据输出(TX)。 RX: 接受数据串行输入。通过过采样技
[单片机]
STM32实例-LCD1602电路
1602 液晶,从它的名字我们就可以看出它的显示容量,就是可以显示 2 行,每行 16 个字符的液晶,电路图如下所示。 LCD1602它的任务电压是 4.5V~5.5V,关于这点我们设计电路的时分,直接依照 5V 零碎设计,然则包管我们的 5V 零碎最低不克不及低于 4.5V。在 5V 任务电压下丈量它的任务电流是 2mA,人人留意,这个 2mA 仅仅是指液晶,而它的黄绿背光多是用 LED 做的,所以功耗不会太小的,一二十毫安照样有的。1602 液晶一共 16 个引脚,每一个引脚的功用,我们都可以在它的数据手册上取得。而这些根本的信息,在我们设计电路和编写代码之前,必须先看明确,1602 液晶引脚功用如下表所示。 LCD
[单片机]
STM32 独立看门狗定时器IWDG复位
无论是什么微控制器,一般都会有看门狗模块。对于STM32来说,它具有两个看门狗:独立看门狗(IWDG)与窗口看门狗(WWDG)。这里就先讲讲独立看门狗。 看门狗能够检测和解决有软件错误引起的故障。当一个错误导致看门狗不能及时 喂狗 ,那么它就会产生一个系统复位。独立看门狗,之所以 独立 ,是因为它由专门的40kHz左右的低速时钟驱动的,及即时主时钟发生故障它也仍然有效。为它提供时钟的低速时钟LSI的频率虽然号称是40KHz,但实际上并不准确,它有MCU内部RC振荡产生,频率会会在30kHz~60kHz之间变化。所以,独立看门狗不能用来精确计时。如果想要实现准确计时,那还需要对LSI进行校准。独立看门狗最适合用于那些在一个主程序之外
[单片机]
<font color='red'>STM32</font> 独立看门狗定时器IWDG复位
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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