ZigBee开发(8)--基础实验睡眠唤醒
Zigbee 的特点就是远距离低功耗的无线传输设备,节点模块闲时可以进入睡眠模式,
在需要传输数据时候进行唤醒,能进一步节省电量。本章将讲述CC2530 在睡眠模式下的 2 种唤醒方法:外部中断唤醒和定时器唤醒。
实验功能:
将睡眠模式下的 CC2530 通过按键中断和定时器方式唤醒。通过 LED 状态展示。
实验讲解:
睡眠定时器用于设置系统进入和退出低功耗睡眠模式之间的周期。
还用于当系统进入低功耗模式后,维持 MAC 定时器(T2)的定时。
其特性如下:长达 24 位定时计数器,运行在 32.768KHZ 的工作频率。 24 位的比较器具有中断和 DMA 触发功能在 PM2 低功耗模式下运行
系统电源管理(工作方式如下):
1. 全 功 能 模 式 , 高 频 晶 振 (16M 或 者 32M ) 和 低 频 晶 振 (32.768KRCOSC/XOSC )全部工作, 数字处理模块正常工作。
2. PM1 : 高频晶振(16M 或者 32M )关闭,低频晶振(32.768K RCOSC/XOSC )工作,数字核心模块正常工作。
3. PM2 :低频晶振(32.768K RCOSC/XOSC )工作, 数字核心模块关闭,系统通过 RESET,外部中断或者睡眠计数器溢出唤醒。
4. PM3 : 晶振全部关闭,数字处理核心模块关闭,系统只能通过 RESET 或外部中断唤醒。此模式下功耗最低。
(1)中断唤醒
CC2530 需要配置的主要寄存器如下: PCON , SLEEPCMD。 功能如下表所示: (详细参考 CC2530 datasheet.pdf)
该寄存器有以下配置方法:
SLEEPCMD |= i; // 设置系统睡眠模式, i=0,1,2,3 PCON = 0x01; // 进入睡眠模式 ,通过中断打断 PCON = 0x00; // 系统唤醒 ,通过中断打断
完整源码:
#include<ioCC2530.h> /********************************************** 程序描述: LED2 闪烁 5 次后进入睡眠状态,通 过按下按键 S1 产生外部中断进行唤 醒,重新进入工作模式。 ***********************************************/ #include <ioCC2530.h> #define uint unsigned int #define uchar unsigned char //定义控制 LED 灯和按键的端口 #define LED2 P1_0 //定义 LED2 为 P11 口控制 #define KEY1 P0_1 //函数声明 void Delayms(uint); //延时函数 void InitLed(void); //初始化 P1 口 void SysPowerMode(uchar sel); //系统工作模式 /**************************** 延时函数 *****************************/ void Delayms(uint xms) //i=xms 即延时 i 毫秒 { uint i,j; for(i=xms;i>0;i--) for(j=587;j>0;j--); } /**************************** //初始化程序 *****************************/ void InitLed(void) { P1DIR |= 0x01; //P1_1 定义为输出 PICTL |= 0x02; //下降沿触发 LED2 = 0; //LED2 灯熄灭 P0INP &= ~0X01; //设置 P0 口输入电路模式为上拉/ 下拉 P0IEN |= 0X02; //P00 设置为中断方式 PICTL |= 0X01; // 下降沿触发 } /*************************************************************** 系统工作模式选择函数 * para1 0 1 2 3 * mode PM0 PM1 PM2 PM3 ***************************************************************/ void SysPowerMode(uchar mode) { uchar I,j; I = mode; if(mode<4) { SLEEPCMD |= I; // 设置系统睡眠模式 for(j=0;j<4;j++); PCON = 0x01; // 进入睡眠模式 ,通过中断打断90 } else { PCON = 0x00; // 系统唤醒 ,通过中断打断 } } /*************************** 主函数 ***************************/ void main(void) { uchar count = 0; InitLed(); //调用初始化函数 IEN1 |= 0X20; //开 P0 口总中断 P0IFG |= 0x00; //清中断标志 EA = 1; while(1) { LED2=~LED2; if(++count>=10) { count=0; SysPowerMode(3); //5 次闪烁后进入睡眠状态 PM3, //等待按键 S1 中断唤醒 } Delayms(500); } } /*****************************************91 中断处理函数-系统唤醒 *****************************************/ #pragma vector = P0INT_VECTOR __interrupt void P0_ISR(void) { if(P0IFG>0) { P0IFG = 0; //清标志位 } P0IF = 0; SysPowerMode(4); //正常工作模式 }
(2)定时器唤醒
CC2530 睡眠定时器除了实验 1 之外还需要配置的寄存器如下: ST0 , ST1 ,ST2。 也就是文初提及到的 24bit 定时器。
如下表所示: (详细参考 CC2530datasheet.pdf)
配置唤醒时间寄存器有以下配置方法:
UINT32 sleepTimer = 0; sleepTimer |= ST0; sleepTimer |= (UINT32)ST1 << 8; sleepTimer |= (UINT32)ST2 << 16; sleepTimer += ((UINT32)sec * (UINT32)32768) //低速晶振; ST2 = (UINT8)(sleepTimer >> 16); ST1 = (UINT8)(sleepTimer >> 8); ST0 = (UINT8) sleepTimer;
配置完毕后 sleepTimer 与 ST2<<16|ST1<<8|ST0 相差 sec 秒时间(低速晶振)
源代码:
#include<ioCC2530.h> /************************************** 程序描述:通过设置定时器在特定时间内进行 唤醒,重新进入工作模式,每次唤 醒 LED2 闪烁 3 下。 **************************************/ #define uint unsigned int #define uchar unsigned char #define uint32 unsigned long //定义控制 LED 灯和按键的端口 #define LED2 P1_0 //定义 LED2 为 P11 口控制 #define KEY1 P0_1 //函数声明 void Delayms(uint); //延时函数 void InitLed(void); //初始化 P1 口 void SysPowerMode(uchar sel); //系统工作模式 /**************************** 延时函数 *****************************/ void Delayms(uint xms) //i=xms 即延时 i 毫秒 { uint i,j; for(i=xms;i>0;i--) for(j=587;j>0;j--); } /**************************** //初始化程序 *****************************/ void InitLed(void) { P1DIR |= 0x01; //P1_1 定义为输出 PICTL |= 0x02; //下降沿触发 LED2 = 0; //LED2 灯熄灭 P0INP &= ~0X01; //设置 P0 口输入电路模式为上拉/ 下拉 P0IEN |= 0X02; //P00 设置为中断方式 PICTL |= 0X01; // 下降沿触发 } /*************************************************************** 系统工作模式选择函数 * para1 0 1 2 3 * mode PM0 PM1 PM2 PM3 ***************************************************************/ void SysPowerMode(uchar mode) { uchar I,j; I = mode; if(mode<4) { SLEEPCMD |= I; // 设置系统睡眠模式 for(j=0;j<4;j++); PCON = 0x01; // 进入睡眠模式 ,通过中断打断90 } else { PCON = 0x00; // 系统唤醒 ,通过中断打断 } } /***************************************** //初始化 Sleep Timer (设定后经过指定时间自行唤醒) *****************************************/ void Init_SLEEP_TIMER(void) { ST2 = 0X00; ST1 = 0X0F; ST0 = 0X0F; EA = 1; //开中断 STIE = 1; //SleepTimerinterrupt enable STIF = 0; //SleepTimerinterrupt flag 还没处理的 } /*************************************************************** 设置睡眠时间 ***************************************************************/ void Set_ST_Period(uint sec) { uint32 sleepTimer = 0; sleepTimer |= ST0; sleepTimer |= (uint32)ST1 << 8; sleepTimer |= (uint32)ST2 << 16; sleepTimer += ((uint32)sec * (uint32)32768);//低频晶振 PM2 模式 ST2 = (uchar)(sleepTimer >> 16); ST1 = (uchar)(sleepTimer >> 8); ST0 = (uchar) sleepTimer; } /*************************** 主函数 ***************************/ void main(void) { uchar i; InitLed(); //调用初始化函数 Init_SLEEP_TIMER(); //初始化 SLEEPTIMER LED2 = 1; while(1) { for(i=0;i<6;i++) //闪烁 3 下 { LED2=~LED2; Delayms(200); } Set_ST_Period(3); //重新进入睡眠模式 SysPowerMode(2); //进入 PM2 低频晶振模式 } } /*****************************************91 中断处理函数-系统唤醒 *****************************************/ #pragma vector = P0INT_VECTOR __interrupt void P0_ISR(void) { STIF = 0; //清标志位 SysPowerMode(4); //正常工作模式 }