lpc1114 睡眠模式sleep mode

  • 学习4275次

低功耗模式,专为电池供电而生!

LPC1114内部有很多的模块,几乎每个模块都可以通过相关寄存器来控制掉电与上电以及时钟是否开启。总的来说,上电的模块越少,就越省电。在实际的产品应用中,我们首先可以根据需要,把不用的模块统统关闭来达到节省功耗的目的,然后,还可以通过以下的3种低功耗模式来实现:睡眠模式、深度睡眠模式、深度掉电模式。

1. 睡眠模式(Sleep mode)

进入睡眠模式,LPC1114内核Cortex-M0的时钟停止工作,指令也无法执行。复位或者有一个中断发生将退出睡眠模式。

进入睡眠模式,正在运行的外设模块将继续运行,正在运行的外设模块可以产生一个中断来使得单片机推出睡眠模式。睡眠模式会消除单片机自身、存储系统和他们相关的控制器以及内部总线的动态功耗。处理器的状态和寄存器、外设的寄存器、SRAM中的数据以及单片机引脚的电平都会保持不变。

2. 怎样进入睡眠模式

执行以下步骤进入睡眠模式:

1. 设置PCON寄存器的DPDEN位为0;

2. 设置SCR寄存器中的SLEEPDEEP位为0;

3. 执行WFI指令。

3. 进入睡眠模式后,如何唤醒单片机

1. 复位

2. 发生一个NVIC中断

4. 示例程序

为了很容易的看到效果,这里用流水灯的运行和停止运行来观察是否进入睡眠模式。开始流水灯执行,过一会儿,进入睡眠模式后,流水灯停止流水。

新建一个工程,结构如下图所示:

pmu

在main.c中,输入以下代码:

#include "lpc11xx.h"
#include "pmu.h"
#define LED1_ON? LPC_GPIO1->DATA &= ~(1<<0)
#define LED1_OFF LPC_GPIO1->DATA |= (1<<0)
#define LED2_ON? LPC_GPIO1->DATA &= ~(1<<1)
#define LED2_OFF LPC_GPIO1->DATA |= (1<<1)
/***********************************/
/* 函数名称:延时函数?????????? */
/***********************************/
void delay()
{
???uint16_t i,j;
???for(i=0;i<5000;i++)
???for(j=0;j<200;j++);
}
/***********************************/
/* 函数名称:LED灯初始化?????? */
/***********************************/
void led_init()
{
???LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16); // 使能IOCON时钟
???LPC_IOCON->R_PIO1_0 &= ~0x07;???
???LPC_IOCON->R_PIO1_0 |= 0x01; //把P1.0脚设置为GPIO
???LPC_IOCON->R_PIO1_1 &= ~0x07;
???LPC_IOCON->R_PIO1_1 |= 0x01; //把P1.1脚设置为GPIO
???LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<16); // 禁能IOCON时钟
???LPC_GPIO1->DIR |= (1<<0); // 把P1.0设置为输出引脚
???LPC_GPIO1->DATA |= (1<<0); // 把P1.0设置为高电平
???LPC_GPIO1->DIR |= (1<<1); // 把P1.1设置为输出引脚
???LPC_GPIO1->DATA |= (1<<1); // 把P1.1设置为高电平
}
/***********************************/
/* 函数名称:GPIO1中断函数???????? */
/***********************************/
void PIOINT1_IRQHandler()
{
???LPC_PMU->PCON &= ~(1<<8); // SLEEPFLAG标志位清零????
???LPC_GPIO1->IC = 0XFFF;? // 清RIS状态位
}
/***********************************/
/* 函数名称:主函数??????????????? */
/***********************************/
int main()
{
???uint8_t cnt=0;
???led_init();
???LPC_GPIO1->IE |= (1<<9); // 允许P1.9引脚上的中断
???LPC_GPIO1->IE |= (1<<10); // 允许P1.10引脚上的中断
???NVIC_EnableIRQ(EINT1_IRQn); // 打开GPIO1中断
???while(1)
???{
??????delay();
??????LED1_ON;
??????LED2_OFF;
??????delay();
??????LED1_OFF;
??????LED2_ON;
??????cnt++;
??????if(cnt>20)
??????{
?????????cnt = 0;????????????????
?????????Entry_Sleep();
??????}
???}
}

 

从主函数main开始看起。

第45行,定义了一个变量cnt,计数用。

第46行,初始化了led灯。

第47,48行,分别允许了P1.9和P1.10的下降沿中断。

第49行,打开了GPIO1上的NVIC中断。

第50行,进入while循环,之后程序将一直在while里面循环运行,达到流水灯的效果。(关于led和P1.9 P1.10的外部中断设置部分,在第三章有详细说明。)

第59行,当cnt大于20,把cnt清0后,执行第62行的进入睡眠模式的函数。

进入睡眠模式后,流水灯停止流水。这时,可以给P1.9或P1.10一个下降沿来唤醒单片机。在RATION V3.0开发板上,P1.9和P1.10连接KEY1和KEY2,只要按下KEY1或KEY2,就会唤醒单片机,使得流水灯继续执行。当cnt到达20后,又会进入睡眠模式。

在pmu.h中,输入以下代码:

#ifndef? __LPC11XX_PMU_H
#define? __LPC11XX_PMU_H
extern void Entry_Sleep(void);
#endif

在pmu.c中,输入以下代码:

#include "lpc11xx.h"
#include "pmu.h"
void Entry_Sleep(void)
{
???LPC_PMU->PCON &= ~(1<<1);????? // DPDEN=0; 选择sleep/deep-sleep模式
???SCB->SCR &= ~(1<<2);????? ?????// SLEEPDEEP=0; 选择sleep模式
???__wfi();??????????????????????????? ?????? ??// 写wfi指令进入低功耗模式
}

Entry_Sleep()函数用到了两个寄存器和一个指令。

PCON:功耗控制寄存器

SCR:系统控制寄存器

__wfi:等待中断指令

PCON是PMU模块的寄存器,SCR是Crotex-M0内核系统控制模块SCB的寄存器。

PCON:功耗控制寄存器

符号 描述 复位值
0 保留位,不能给此位写1 0x0
1 DPDEN 深度掉电模式允许位 0
0 执行WFI进入睡眠或深度睡眠模式
1 执行WFI进入深度掉电模式
7:2 保留位,不能给这些位写1 0x0
8 SLEEPFLAG 睡眠模式标志 0
0 读:没有进入低功耗模式写:不起作用
1 读:进入了低功耗模式写:清此位
10:9 保留位,不能给这些位写1 0x0
11 DPDFLAG 深度掉电标志 0x0
0 读:没有进入深度掉电模式写:不起作用
1 读:进入深度掉电模式写:清除深度掉电模式
31:12 保留位,禁止给这些位写1 0x0

 

LPC_PMU->PCON &= ~(1<<1);??? // DPDEN=0; 选择sleep/deep-sleep模式

第5行,给PCON寄存器的bit1写0,选择进入睡眠或深度睡眠模式。

SCR:系统控制寄存器

符号 描述 复位值
0 保留位 0
1 SLEEPONEXIT 从处理模式到线程模式是否进入退出睡眠模式:0= 在线程模式中不睡眠

1 = 当从ISR返回到线程模式进入睡眠模式或深度睡眠模式

此位置1使能中断避免应用程序返回空的mian函数

0
2 SLEEPDEEP 在低功耗模式下选择处理器使用睡眠模式还是深度睡眠模式:0 = 睡眠模式??????? 1 = 深度睡眠模式 0
3 保留 0
4 SEVONPEND 发送中断信号。当有中断进入等待中断模式,中断信号可将CPU从WFE中唤醒。如果CPU没有等待中断,但是中断信号已经有效,将会在下一个WFE指令后生效。当然执行SEV指令也可将CPU唤醒0 = 只有使能的中断才可以将CPU唤醒,没有使能的中断将被忽略

1 = 所有的中断,包括使能和没有使能的中断都可以将CPU唤醒

0
31:5 保留位 0x00

 

SCB->SCR &= ~(1<<2);????? ?????// SLEEPDEEP=0; 选择sleep模式

第六行,给SCR寄存器的bit2写0,即选择睡眠模式。

???__wfi();??????????????????????????? ???????? // 写wfi指令进入低功耗模式

WFI是专门为了节省功耗设计的指令,执行该指令后,单片机将挂起等待一个中断到来,挂起后,相当于一直执行NOP指令。

发表评论