Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9152078
  • 博文数量: 1727
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 19860
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1727)

文章存档

2024年(3)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: Windows平台

2015-02-06 10:21:57



在学习Zigbee无线传输技术时,为了延长电池的使用寿命,常希望设备在不工作时处于睡眠模式。但是许多时候会遇到比如CC2530在PM2模式下,睡眠定时器唤醒后,可以发送数据,但是无法接受数据,想了很久也不知道问题出在哪里?下面,小编简要的说明一下原因与解决方法。

工具/原料

  • cc2530技术手册

方法/步骤

  1. 作为示例,小编以简单的cc2530睡眠定时器周期性唤醒CPU为例,讲述如何解决上述问题。首先,需要配置睡眠定时器周期,如下所示通过设置ST0/ST1/ST2寄存器设定周期:

    /*

     * Sleep timer period set

     */

    void wg_setSleepTimerPeriod(float sec)

    {

      //Note: there is no need to care about overflow of sleep timer

      //  current value,just about recycle of adder

      uint32 sleepTimer = 0;

      

      //once read ST0 value,the current value of 24-bit counter is latched

      sleepTimer |= ST0;

      sleepTimer |= (uint32)ST1<<8;

      sleepTimer |= (uint32)ST2<<16;

      sleepTimer += (sec*32768); //low crystal,PM2 mode 

      

      ST2 = (uint8)(sleepTimer>>16);

      ST1 = (uint8)(sleepTimer>>8);

      ST0 = (uint8)sleepTimer; //sleep timer period set


    }

  2. 在设定睡眠定时器周期之后,需要使能睡眠定时器中断并清除睡眠定时器中断标志,如下所示:

      //clear sleep timer flags

      STIF = 0;  //sleep timer flag

      IEN0 |= STIE_BV; //enable sleep timer interrupt

     

  3. 使能睡眠定时器中断标志之后,通过设定SLEEPCMD.MODE就可以使CPU进入特定睡眠模式:

    /*

     * End device sleep for save power

     */

    void wg_analyEdvSavePower(void)

    {

      /* Prep CC2530 power mode: PM2 */

      SLEEPCMD &= ~PMODE; /* clear mode bits */

      

      //Power mode pre-load 

      SLEEPCMD |= 0x02;   /* set mode bits : PM2 */

      

      while (!(STLOAD & LDRDY));  

    }

  4. 根据资料与实验猜想,之所以CPU从PM2模式唤醒之后能发送数据而不能接收数据,是因为当进入睡眠模式后,CPU关闭,16MHz RC与 32MHz 晶振也都关闭,32kHz时钟(RC或者32kHz XOSC)仍然,当CPU唤醒后默认系统主时钟为16MHz的RC时钟,由于32MHz时钟模块并没有开启,所以RF无法接受!当然也就没法接收数据啦,所以正确的解决办法就是:

      PCON = PCON_IDLE;

     //enter PM2 mode , wake-up and continue run below...

      

      //Wake-up and continue run ...

     /* MCU initial:

      *   system clock set: 32MHz, turn on cache prefetch mode.

      */

      clockSetMainSrc(CLOCK_SRC_XOSC);

      

      basicRfReceiveOn(); // turn on rf receiver

      wg_waitMs(2); //delay for rf receiver on

      

      HAL_DISABLE_INTERRUPTS();


      //re-store IENx(x.0/1/2) SFR

      IEN0 = ien0;

      IEN1 = ien1;

      IEN2 = ien2; //interrupt register

      

      IEN0 &= ~STIE_BV; //disables sleep-timer interrupt

      HAL_ENABLE_INTERRUPTS();

    如上代码所示,当睡眠唤醒之后,先设置系统主时钟为32MHz外部晶振时钟,并开启RF 接收器,恢复中断控制器IEN0/IEN1/IEN2,并清除睡眠定时中断,开启系统中断!

阅读(3229) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~