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); //正常工作模式
  }

 

 

 

posted @ 2018-10-29 21:30  飞起的小田  阅读(1200)  评论(0编辑  收藏  举报