[资料分享] LM3S 系列单片机休眠与深度休眠应用笔记(二)

eeleader   2010-6-29 15:11 楼主

1.4 深度睡眠模式设置步骤

处理通过调用WFI 指令即可进入睡眠模式,但要进入深度睡眠实现最低的功耗需要正确配置,其步骤如下:

1. 使能ACG 自动时钟门控。这样睡眠模式和深度睡眠模式的外设时钟可以单独控制。

2. 配置寄存器DCGC0 DCGC1 DCGC2,设置深度睡眠模式下允许时钟的外设。我们一般只给唤醒CPU 的外设使能时钟,因为允许时钟的外设越少,功耗越低。例如:我们的示例程序在进入深度睡眠模式后是通过PORTB 的外部中断唤醒的,因此在深度睡眠模式下必须允许PORTB 的时钟(置位DCGC2 寄存器的第1 位)。睡眠或深度睡眠模式下,必须设置最少一个唤醒条件,否则无法唤醒。另外值得注意的是,如果程序中设置了定时器中断,并且在睡眠或深度睡眠模式下允许了时钟,则在睡眠或深度睡眠模式下定时器正常工作,当定时器产生中断时,处理器就会被唤醒。

3. 使能深度睡眠位SLEEPDEEP ,使处理器休眠时进入深度睡眠模式。

4. 使能深度睡眠时钟配置寄存器DSLPCLKCFG IOSC 位,使处理器在深度睡眠期间将内部振荡器强制为时钟源。

5. 在完成上述配置后,如果想让处理区进入深度睡眠模式,调用WFI 指令即可。睡眠后,发生异常中断即可唤醒处理器。

 

1.5 示例程序说明

深度睡眠应用示例程序如程序清单 1 所示,在正常运行时时翻转LED 灯,按KEY1 键,进入深度睡眠,按KEY2 键唤醒处理区。程序清单 11)定义了深度睡眠需要操作的几个寄存器的地址,2 个按键和一个LED 灯。

程序清单 12)定义了函数WFI( ) ,此函数为C 语言内嵌汇编指令的函数。处理器请求休眠是通过汇编指令WFI 来实现的,用户应用程序只需调用函数WFI( ) ,即可请求休眠,关键字__asm 申明该函数内为汇编指令。

程序清单 13)定义了配置相关寄存器,使休眠时进入深度休眠,最大程度地实现低功耗的函数DeepSleepConfig( ) 。程序清单 14)为中断服务程序,示例程序在此请求休眠挂起。程序清单 15)也为中断服务程序,示例程序在此唤醒休眠。

程序清单 1 深度睡眠应用示例程序

#include "hw_memmap.h" #include "hw_types.h" #include "hw_ints.h" #include "sysctl.h" #include "systick.h" #include "gpio.h"#include "interrupt.h"

#define HWREG(x)      (*((volatile unsigned long *)(x))) #define SYS_CTL_REG 0xe000ed10 1#define SYS_DSLPCLKCFG    0x400FE000 + 0X144 #define SYS_RCC      0x400FE000 + 0X060

#define KEY1 GPIO_PIN_4 // 定义KEY1 #define KEY2 GPIO_PIN_5 // 定义KEY1 #define LED1 GPIO_PIN_1 // 定义LED1

__asm void WFI(void) 2{ WFI }

void DeepSleepConfig() 3{ unsigned long temp;

 // ACG 自动时钟门控,睡眠或深度睡眠时使用SCGC DCGC 来控制分配给外设的时钟temp = HWREG(SYS_RCC);  HWREG(SYS_RCC) = temp|(1<<27);

// 设置深度睡眠下允许时钟外设 SysCtlPeripheralDeepSleepEnable(SYSCTL_PERIPH_GPIOB);

// 设置深度睡眠使能 HWREG(SYS_CTL_REG) = (1<<2);

// 深度睡眠期间将内部振荡器强制为时钟源HWREG(SYS_DSLPCLKCFG) = 1; }

void delay (unsigned int t) { unsigned int i;

do

{
  i = 6000;
do{}
  while(--i);


 }while(--t); }

void InitPB(void)

{ // 使能PB SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

// 设置连接KEY2 PB5 为输入GPIODirModeSet(GPIO_PORTB_BASE, KEY2, GPIO_DIR_MODE_IN);

// 设置KEY2 中断的触发方式为低电平触发 GPIOIntTypeSet(GPIO_PORTB_BASE, KEY2, GPIO_LOW_LEVEL);

// 设置PB 的优先级为1  IntPrioritySet(INT_GPIOB, (1<<5));

// 使能KEY2 中断 GPIOPinIntEnable(GPIO_PORTB_BASE, KEY2);

// 使能PB 口中断 IntEnable(INT_GPIOB); }

void InitPD(void)

{ // 使能PD SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

// 设置连接KEY1 PD4 为输入GPIODirModeSet(GPIO_PORTD_BASE, KEY1, GPIO_DIR_MODE_IN);

// 设置连接LED1 PD7 为输出 GPIODirModeSet(GPIO_PORTD_BASE, LED1, GPIO_DIR_MODE_OUT);

// 设置KEY1 中断的触发方式为低电平触发 GPIOIntTypeSet(GPIO_PORTD_BASE, KEY1, GPIO_LOW_LEVEL);

// 设置PB 的优先级为3  IntPrioritySet(INT_GPIOD, (3<<5));

// 使能KEY1 中断 GPIOPinIntEnable(GPIO_PORTD_BASE, KEY1);

// 使能PD 口中断 IntEnable(INT_GPIOD); }

void GPIO_Port_D_ISR(void) 4

{  GPIOPinIntClear(GPIO_PORTD_BASE, KEY1); // 清除中断标志 WFI();

}

void GPIO_Port_B_ISR(void) 5{  GPIOPinIntClear(GPIO_PORTB_BASE, KEY2); // 清除中断标志}

int main(void)

{  InitPB ();  InitPD ();  DeepSleepConfig();

 while (1)

{   GPIOPinWrite(GPIO_PORTD_BASE, LED1, ~LED1); // 点亮LED1   delay(100);   GPIOPinWrite(GPIO_PORTD_BASE, LED1, LED1); // 熄灭LED1   delay(100);

} }

 

一个为理想不懈前进的人,一个永不言败人! http://shop57496282.taobao.com/ 欢迎光临网上店铺!

回复评论 (1)

顶一下,你发帖怎么这么快啊!!!!!!!!
我的博客
点赞  2010-6-29 15:16
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复