最近在研究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
配置好之后,再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的电流,换成大阻值之后就可以得到更低的电流了。