【WB32库开发】第17章 (一)低功耗电源控制——睡眠模式

稳定的电源是保证系统稳定运行的基础,但是在实际的项目应用场合中,除了要保证系统稳定运行,对系统的功耗也有极高的要求;

例如在一些便携设备上,其自身电源极小,甚至可能仅有一块纽扣电池,却需要维持设备运行数月至数年之久,因此必须引入电源管理来控制功耗,提升设备续航时间;

WB32提供了几种电源管理模式,在保障设备系统正常运行外,亦能拥有极佳的功耗:
三种省电模式:睡眠模式,停止模式,待机模式
动态功耗:~160uA/MHz@3.3V
Stop 待机功耗:~18.5uA@3.3V
Standby 待机功耗:~4.5uA@3.3V
VBAT RTC 功耗:~1.1uA@3.3V
当主电源掉电时,VBAT 电源下提供 84 字节容量的备份寄存器;

本节课将通过固件库中PWR例程中的PWR_SLEEP工程讲解如何控制WB32进入低功耗睡眠模式并退出。在学习本节内容前务必仔细阅读WB32中文参考手册第六章电源控制(PWR)6.1节至6.3节部分。

17.1 睡眠模式实验

本例程演示如何进入低功耗SLEEP模式和通过外部中断退出低功耗SLEEP模式。初始点亮LED1,熄灭LED2;等待一段时间后配置PA0外部中断并进入SLEEP模式;

通过按下与PA0管脚连接的按键产生外部中断以退出SLEEP模式,在中断中切换LED2的状态(LED2点亮),程序继续运行,LED1闪烁。

17.1.1 预处理文件、宏定义与函数声明

#include "wb32f10x.h"

EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

void EXTI0_Config(void);

void delay(uint32_t n)
{
  while(n--);
}

本例程用到外部中断将WB32从睡眠模式下唤醒,故需要对EXTI和NVIC进行配置。

EXTI0_Config()与delay()两个用户自定义函数是两种不同的函数声明方式;若将delay()函数放在main函数后,为保证正确使用,也需向EXTI0_Config()函数一样,仅需将函数名进行声明即可。

17.1.2 main函数

int main(void)
{
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  /* 使能 GPIOB 时钟 */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |RCC_APB1Periph_GPIOB, ENABLE);
  GPIO_Init(GPIOB, GPIO_Pin_13 |GPIO_Pin_14, GPIO_MODE_OUT |GPIO_OTYPE_PP |GPIO_PUPD_NOPULL |GPIO_SPEED_HIGH);
  GPIO_ResetBits(GPIOB, GPIO_Pin_14);   // 开启LED1
  GPIO_SetBits(GPIOB, GPIO_Pin_13);     // 关闭LED2
  
  /* WB32上电后,经过此延时时间进入睡眠模式 */
  delay(50000000);
  
  /* 配置EXTI中断,用来将WB32从睡眠模式唤起 */
  EXTI0_Config();

  /* 使用WFI方式进入睡眠模式 */
  PWR_EnterSLEEPMode(PWR_FCLK_Div2, PWR_EntryMode_WFI);

  while (1)
  {
    /* LED1 闪烁 */
    GPIO_ToggleBits(GPIOB, GPIO_Pin_14);
    delay(8000000);
  }
}

有两种方式进入睡眠模式,分别是WFI(wait for interrupt)和WFE(wait for event),进入方式决定了从睡眠唤醒的方式;

LED1与LED2采用共阳极的连接方法,再将PB14连接LED1的阴极引脚,PB13连接LED2的阴极引脚,;在WB32上电后点亮LED1,关闭LED2;

17.1.3 中断配置函数

void EXTI0_Config(void)
{
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |RCC_APB1Periph_GPIOA | 
                         RCC_APB1Periph_EXTI |RCC_APB1Periph_AFIO, ENABLE);

  /* 配置PA0位下拉输入模式(PA0引脚默认电平为低电平) */
  GPIO_Init(GPIOA, GPIO_Pin_0, GPIO_MODE_IN |GPIO_PUPD_DOWN);

  /* 将PA0配置为EXTI0(PAx与EXTIx的x是对应的,PB、PC、PD也都一样) */
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

  /* 配置EXTI0 */
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  /* 配置EXTI中断 */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

EXTI基本配置,要注意的是将PA0引脚设置为下拉输入,即引脚默认电平为低;后面配置EXTI的检测信号沿为上升沿,若是将EXTI0设置为上拉输入,即引脚默认电平为高,则此中断永远无法达成。

17.1.4 EXTI0中断服务函数

void EXTI0_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line0) != RESET)
  {
    /* 清除EXTI line 0 中断位 */
    EXTI_ClearITPendingBit(EXTI_Line0);

    /* 翻转LED2电平状态 */
    GPIO_ToggleBits(GPIOB, GPIO_Pin_13);
  }
}

中断服务函数一般放着我们想要执行的函数,进入中断后必须清除对应的中断标志位。

17.2 实验结果

代码编译后烧录到WB32中,将外部电路连接好,PB14接在示波器通道1上(或LED2的阴极引脚处),PB13接在示波器通道2上(或LED2的阴极引脚处),上电后按下复位可以观察到:
请添加图片描述

CH1(PB14)为低电平,CH2(PB13)为高电平(观察小箭头与通道电平的位置);

按照正常程序执行情况,应继续向下执行程序,不停翻转PB14电平状态,使LED1闪烁;但此时却一直保持着PB14为低电平,PB13为高电平的状态;

***注意!***这是因为我们的WB32此时已经进入了睡眠状态,内在是关闭内核时钟,内核停止,而外设正常运行,在软件上表现为不再执行新的代码;这个状态会保留睡眠前的内核寄存器、内存的数据。唤醒后,若由中断唤醒,先进入中断,退出中断服务程序后,接着执行WFI指令后的程序;若由事件唤醒,直接接着执行WFE后的程序。

那么接下来,当我们使用杜邦线将PA0与板载3.3V连接在一起后,可以看到:
请添加图片描述

此时由于PA0检测到上升沿,将WB32从睡眠模式下唤醒,并进入EXTI0中断服务函数,清除中断标志位后将PB13的电平状态翻转(从高电平翻转为低电平),接着回到主函数里执行循环当中的LED1闪烁的程序;

我们在图中看到的就是这样一个情况,PB13的电平由高变低,PB14的电平不断反转。

若想再进入中断,翻转PB13的电平状态,可再将PA0与板载3.3V连接即可:
请添加图片描述

本次实验结果正确,其中最重要的“注意”部分,需要大家结合着后续的电源管理来对比学习,可以了解到几种不同的电源管理模式有哪些不同;

还需要注意的是,当WB32进入低功耗模式后,是无法正常使用DAP、SWD、JLINK(SWD模式)进行程序的烧录和下载的,可以先将WB32从低功耗模式中唤醒,然后再下载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值