官方提供的设置方法:
5,如何让End Device进入低功耗状态,休眠时间是如何设定的?
其实,闪一次就是睡眠了一次:亮的时候睡过来,灭的时候睡下去。具体代码在halSleep函数里。要做的,就是读懂这个机制是怎么运作的。
zstack的睡眠机制就是在操作系统没事干的时候才睡眠,频率高说明应用程序让操作系统不断做事。你想让它长时间睡眠,那要做的就是不要不断地给操作系统事情做,找到分配系统任务的地方。
CC2530 OSAL进入省电模式注意事项总结
在淘宝搞了几个CC2530模块回来玩,其中比较感兴趣的是低功耗这块功能,目前测试的结果是PM2模式下,纽扣电池2.8V电压,工作电流1.1uA(FLUKE F18B),符合规格书中描述的典型值1uA,总结如下:
前言:
1. OSAL是一个不错的操作系统,不要老是想着自己进入低功耗模式,应用任务没事干了,OSAL自己会进入低功耗模式。
2. 进入PM2不困难,真正困难的是真正低功耗并且通信正常。
3. 低功耗和代码有关,和硬件也有关,必要的时候,把板子除了最小系统所需之外的期间函调,一遍排查是代码问题还是硬件设计问题。
实际操作方法:(我基于淘宝卖家的例程进行操作,每个人的例程或协议栈版本不一样可能存在一定的差异)
1. 在编译器预编译那里定义:POWER_SAVING
2. f8wConfig.cfg文件中,DPOLL_RATE\DQUEUED_POLL_RATE\DRESPONSE_POLL_RATE\DREJOIN_POLL_RATE这几个全部赋值0。
3. 在你的任务初始化中增加这么一句osal_pwrmgr_device(PWRMGR_BATTERY);否则,OS不会进入省电模式。注意所有的用户任务都必须执行这么一句,否则无法进入省电模式。
做完以上3点,恭喜你,已经可以进入省电模式了。
但是,到底是PM1或PM2或PM3,要继续往下走
4. 找到void halSetSleepMode(void)函数,PCON = halSleepPconValue;这句决定你进入哪种省电模式,找到它定义的地方,我这边赋值是PCON_IDLE,将其改成HAL_SLEEP_TIMER或CC2530_PM2,即可进入PM2模式。想进入PM3同理。
作为第4点,即可进入PM2模式,但是并不以为则真的省电,可能几百个uA也可能若干个mA甚至几十个mA和没进入PM2一样。原因是,有其他任务在不停的唤醒CPU,导致电流下不来,需要注意哪几点?
1. 键盘,如果采用扫描模式则,则不停唤醒CPU,需设置成中断模式,或加大扫描周期。
2. LED,LED也有个任务,看看你的LED是不是频繁闪烁,如果是停掉。
3. ADC,我听别人说的,有个电池检测的任务不停进行电压采样,我这里没有。
4. 协议栈、协议栈、协议栈,重要的事情说三遍。
4.1 终端上电后或者断网后,会主动查找网络,导致无法进入省电模式。解决办法:http://blog.csdn.net/shjhuang/article/details/51171369,TI论坛也有,我忘记链接了。
4.2 VV大侠的http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/t/75525.aspx 当中的第4点。
以上做完了,我就实现了1.1uA的目标。
以上如有疑问,欢迎补充。
http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/t/105541.aspx
有完整的解说方法
接着继续喷吧。。我会每天来回复一条吧,喷喷。。。
ED LG:
IAR版本:8.20
zigbee协议:2.5.1a
例子地址:https://pan.baidu.com/s/1o8KBCD0
这个例子,还没有进行添加休眠。我试着,但是不成功。
ED LG:
回复 ED LG:
程序中还没有对LED进行处理。是不能进入休眠的。仿真看一看
ED LG:
回复 ED LG:
有进入这一步
然后点下一步:
不成立。。好了,在刚才IO中,我们再添加一代码:
#include "OSAL_PwrMgr.h"
osal_pwrmgr_device(PWRMGR_BATTERY);
再次仿真一下:
ED LG:
回复 ED LG:
刚才iar,挂了,重新来
进入了。我们一步步运行。
上图可以看出,等于0
然后,再执行下一步:
next=98????????????????????????????????
1MS都不到。。。
全速运行,看看能不能再一次进入void osal_pwrmgr_powerconserve( void )
还是进来的,
从这里说明在应用层添加osal_pwrmgr_device(PWRMGR_BATTERY); 是有用的。
不过新问题来的。
next得到的值很小很小,,说明系统是有任务在执行。。怎么解决呢。等会直接把网络关闭。
ED LG:
回复 ED LG:
在GenericApp.c;;;;;;;;添加 ZDApp_StopJoiningCycle();
仿真一下吧
我的IAR又挂了,我重启一下电脑吧
ED LG:
回复 ED LG:
重新仿真了,
next = osal_next_timeout(); 值 还是不变,
看来问题出现在那里?我感觉是有任务在执行,是不是接受部分呢??我们来看看
先把有可能的任务先关闭吧,比如串口,给XO。
VV:
@ED LG
非常感谢你的经历和经验分享!加油!