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

     

  • 相关阅读:
    寒假的Java学习笔记总结1
    寒假的Java学习笔记总结0
    归档七
    数组归档
    课后作业感悟2
    作业感悟1
    《大道至简》第二章(是懒人创造了方法)读后感
    postman接口测试-文件上传
    postman接口测试:获取所有信息
    怎么测接口?
  • 原文地址:https://www.cnblogs.com/tianxxl/p/9873418.html
Copyright © 2020-2023  润新知