最近在研究CC250的低功耗模式,从官方的文档Measuring Power Consumption of CC2530 With Z-Stack.PDF文档中大概了解下需要配置的内容,结合自己测试的经验,大概介绍下。使用Zstack的版本如下:

ZigBee 2007 Release
 Version 2.5.1a
 April 25, 2012

CC530的功耗模式情况如下:

(1)LITE Sleep,我们所说的PM2模式,功耗在ma级别,会被任务定时器或者外部中断唤醒(按键中断)

(2)Deep Sleep,PM3模式,功耗最低,在uA级别,当没有任务需要执行的时候,会进入;只能被外部中断或者Reset唤醒。


进入低功耗模式需要注意五点:

1,我们使用的环境是IAR,首先需要在编译选项中加入POWER_SAVING,使能低功耗模式;其他没有用到的可以去掉,比如串口,LCD等功能。我的配置如下,前面带x的表示该功能被屏蔽了;

NWK_AUTO_POLL
 xZTOOL_P1
 xMT_TASK
 xMT_SYS_FUNC
 xMT_ZDO_FUNC
 xLCD_SUPPORTED=DEBUG
POWER_SAVING
 xNV_RESTORE
 xNV_INIT
 xHOLD_AUTO_START

Android11 代码实现进入低功耗模式 无法进入低功耗模式_ZStack  低功耗

配置好之后,再osal_run_system()函数中才能调用进入低功耗的模式:

#if defined( POWER_SAVING )
   else  // Complete pass through all task events with no activity?
   {
     //进入低功耗模式
     osal_pwrmgr_powerconserve();  // Put the processor/system into sleep
   }
 #endif
 
2,f8wConfig.cfg文件
 
-DRFD_RCVC_ALWAYS_ON=FALSE
 
-DPOLL_RATE=0//default 1000
 
-DQUEUED_POLL_RATE=0//default 100
 
-DRESPONSE_POLL_RATE=0//default 100


    下面对着几个参数的介绍是从网上摘抄的,Z-stack工程End Point Device默认情况下为电源管理关闭,自动轮询消息这一功能是开启的。这里有四个轮询选项,每一个都由一个不同的时间延迟参数控制。当电源管理功能开启后(添加POWER_SAVING),任一个轮询选项的设置都会影响到睡眠模式。时间延迟的设置不能用于Deep Sleep中的轮询,因此限制了降低功耗。这三个轮询选项分别如下:
(1)Data Request Polling—周期性向父节点发送数据请求来轮询消息队列。轮询的时间间隔由NLME_SetPollRate()或gNWK_POLL_RATE设定,如果事先没有使能它,那么在调用时就立即进行轮询。
(2)Queued Data Polling—在收到数据指示后,就会向父节点请求消息。这个时间间隔可由NLME_SetQueuedPollRate()或gQUEUED_POLL_RATE设定。
(3)Response Data Polling—在收到数据确认指示后,就会向父节点请求响应消息,这个时间间隔可由NLME_SetResponsePollRate()或gRESPONSE_POLL_RATE设定。
函数说明:
NLME_SetPollRate()——设置/改变网络检测速率,仅终端设备可用。
NLME_SetQueuedPollRate()——设置/改变队列检测速率,仅终端设备可用。
NLME_SetPollRate()——设置/改变响应检测速率,仅终端设备可用。
如果只是使用默认的轮询频率进入睡眠态,则只能进入LITE sleep。为了进入DEEP sleep则必须将gNWK_POLL_RATE设为0,不让它反复轮询。设置这个三个选项可以实现多种轮询方式,例如,对于一个不需要接收消息的设备,在它加入网络后,就将这三个选项都设为0。如果APS层使用了ACK,则必需确保在消息发送后到收到ACK这一段时间内,轮询是使能的。在有的系统中,可能需要使用可变的轮询频率,根据具体应用而进行设置。


f8wConfig.cfg文件的最后还有一个轮询,-DREJOIN_POLL_RATE=440,从字面上理解,应该是当加入不成功的时候,会在440ms之后,重新寻找协调器,期待入网的操作。昨天我就是忽视了这个参数,正好昨天也只是给End Device上电做实验,没有给协调器上电,导致终端一直在rejoin,所以昨天看到的现象是进PM2,然后立刻又出来,之后又进入,反反复复。所以我们也可以把这个设置为0,这个也就是试用在没有协调器,只是用终端做实验的时候,通常如果可以入网,就不会440ms之后唤醒CC2530。

-DREJOIN_POLL_RATE=0//default 440



3,配置存在轮询的程序,或者说会产生定时器中断的程序


显然,类似我们定义的周期性发送数据的APS层任务,都属于这个范围,一般情况下会调用osal_start_timerEx函数启动下一次超时的时间,这样会导致系统只能进入PM2,超时之后会从PM2唤醒。这样的程序主要包括如下两部分:


(1)按键轮询程序
 
void InitBoard( uint8 level )
 {
   if ( level == OB_COLD )
   {
     // IAR does not zero-out this byte below the XSTACK.
     *(uint8 *)0x0 = 0;
     // Interrupts off
     osal_int_disable( INTS_ALL );
     // Check for Brown-Out reset
     ChkReset();
   }
   else  // !OB_COLD
   {
     /* Initialize Key stuff */
    //HalKeyConfig(HAL_KEY_INTERRUPT_DISABLE, OnBoard_KeyCallback);//轮询方式
     HalKeyConfig(HAL_KEY_INTERRUPT_ENABLE, OnBoard_KeyCallback);//中断方式
   }
 }


按键程序,默认的方式是轮询方式,上面已经改为中断方式。




(2)SampleApp的任务当中,如果存在周期发送数据,可能存在如下类似结构的程序,我们要坚决屏蔽掉,


osal_start_timerEx( SampleApp_TaskID,
                               SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
                              SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );


4,最后要注意的地方是电源管理的属性

void osal_pwrmgr_init( void )
 {
  //pwrmgr_attribute.pwrmgr_device = PWRMGR_ALWAYS_ON; // Default to no power conservation.
   pwrmgr_attribute.pwrmgr_device = PWRMGR_BATTERY;//电池供电
   pwrmgr_attribute.pwrmgr_task_state = 0;            // Cleared.  All set to conserve。所有的任务支持省电
 }

默认情况下是电源总是保持打开的,我们需要切换为电池供电的方式。同时pwrmgr_task_state = 0表示所有的任务支持省电。




5,如果想做到更省电,需要将没有用到的外设关闭,普通IO内部上拉。




做到以上五点,CC2530 Zstack就可以实现真正的低功耗模式,目前只是用0.1ma的万用表测试了下,只能测试到最低0.1ma,之后会用精度更高的设备测试功耗。




修改电路之后遇到进入低功耗模式之后电流一直是3ma,很奇怪,一直以为是程序哪里的问题,最后仔细检查电路后,发现上拉了一个1K的电阻,上拉的电阻两边电压不一致,3V和GND,所以导致有大概3ma的电流,换成大阻值之后就可以得到更低的电流了。