This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2530 OSAL进入省电模式注意事项总结

Other Parts Discussed in Thread: CC2530, TIDA-00374

在淘宝搞了几个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 终端上电后或者断网后,会主动查找网络,导致无法进入省电模式。解决办法:blog.csdn.net/.../51171369,TI论坛也有,我忘记链接了。
4.2 VV大侠的www.deyisupport.com/.../75525.aspx 当中的第4点。
以上做完了,我就实现了1.1uA的目标。
以上如有疑问,欢迎补充。

  • mark! 实战好文,谢谢分享。

  • @huang shangjian  我用的是2.51a的协议版本,按照这种方法,1. 在编译器预编译那里定义:POWER_SAVING 我只要做这个动作感觉这个模块就不能和其他的通信了。

  • Sir Lee1同学:

    1.  做一件事不一定是走出第一步就能马上看到效果哦。并且比之前的状况可能还要糟糕,只有做完了才能看到结果哦。

    2.  不能通信有两种,1是协议栈不能通信,2是应用层不能通信。你是哪种?后者不要犯低级错误哦,进入低功耗之后,如果应用层协议处理不好,确实就不能通信了哦。

  • @huang shangjian:

    下午好。你加我QQ吧:402732326.比较方便点。

    在这两个链接     http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/t/75525.aspx

                                   http://www.deyisupport.com/question_answer/wireless_connectivity/zigbee/f/104/t/45598.aspx?pi2132219853=1

    5,如何让End Device进入低功耗状态,休眠时间是如何设定的?

    在协议栈宏定义中使能POWER_SAVING后,然后在f8wConfig.cfg文件里面把-DRFD_RCVC_ALWAYS_ON=FALSE,就可以让End Device进入休眠状态。
    关于休眠的时间是有OSAL操作系统的调度来决定,每次休眠时间都是按照最新会发生的一个Event Timeout作为休眠时间。具体在协议栈hal_sleep函数中有说明。

    1.打开POWER_SAVING 预编译

    2.f8wConfig_cfg 中的RFD_RCVC_ALWAYS_ON=FALSE
    3.f8wConfig_cfg中四个DPoll_RATE设为0

    4.ZGlobals.c中三个PollRate设为0

    5.Onboard.c文件中,OnboardKeyIntEnable=HAL_KEY_INTERUPT_ENABLE

    6.hal_drivers.c中if(!Hal_KeyIntEnable)中的语句关掉

    7.osal_pwrmgr_init(void)中pwrmgr_attribute.pwrmgr_device=PWRMGR_BATTERY

    在网上搜了不少方法,也参考了TI官方的文档“Power Management For The CC2530.pdf”,以及“Measuring Power Consumption of CC2530 with Z-Stack(swra292AN079).PDF”。


    我是已经按照文档设置了多次,就是没有成功。你加我QQ吧:402732326,QQ聊比较方便一点。
  • @Huang Shangjian,

    感谢分享,有两点,

    1) f8wConfig.cfg文件中,DPOLL_RATE\DQUEUED_POLL_RATE\DRESPONSE_POLL_RATE\DREJOIN_POLL_RATE这几个全部赋值0。

    这几个变量不设为0也是没可以的,如果为了验证低功耗的电流,那么设备0用来做测试是可以的,否则用万用表测试电流波动快,看不到休眠电流。

    但是实际应用中还是根据需求来,比方说门锁的poll rate肯定不能是0,DREJOIN_POLL_RATE肯定不能是0,否则rejoin都没法成功。

    2)不需要手动添加,现在的协议栈只要使能POWER_SAVING就可以了

    #if defined( POWER_SAVING ) && !defined(USE_ICALL)
      else  // Complete pass through all task events with no activity?
      {
        osal_pwrmgr_powerconserve();  // Put the processor/system into sleep
      }
    #endif


  • VV很能发现问题。

    之前的总结是在旧版协议下得出的结论,前几天从TI官网下载了最新的协议栈,与旧版协议略有差异,发现确实如VV所述的情况,情大家也注意以上的问题。

    题外话:我正在做的低功耗设备,经过测试得出相关数据并计算后,得出的结论是:电池工作寿命为5.2年;而在同样的电池容量的条件下,TI原厂设计(TIDA-00374)则可以达到10.58年,这就是差距!汗ing


  • @huang shangjian,大虾,你好,我设置了协议栈进入了PM2模式,可是还是有10~20uA的功耗,能否留个邮箱,让我请教你呢?邮箱1791322858@qq.com

  • 看看有没有把没用到的IO  串口外设给关掉。关掉和不关,电流相差很大的。。即使一个灯在闪,电流也相差很大。我这边把所有外设全关掉,休眠,电流可达到小于1UA,

  • 关键是GPIO口怎么关?我这边GPIO口和外围电路全部断开,电流很小0.4uA。但是接上外围电路后电流旧变为150uA左右了。之间对连接的GPIO口设置了输入,高阻。输出为0。都没有很明显的改善。请教一下,大侠们的GPIO口都是怎么设置的?

  • 按照介绍实现了低功耗的模式,在PM2模式下可以通过定时唤醒发送指定的数据,在PM3模式下外部中断唤醒发送指定的数据。但是在enddevice工作一段时间后定时唤醒和中断唤醒都不成功,没有数据发送,请问这是什么原因呢。

  • @VV 

    1.   一个PM3 的设备 , 发送消息没有ACK 超出重发次数之后, 是否会开启寻网???

    2.  如果寻网 是否就证明  设备根本没有进入 PM3 ???

    3.  如果应用层中 调用了osal_start_timerEx() 设定了一些 一次性的事件,  事件执行后不再执行, 设备向后是进入PM2 还是PM3  ?

  • 我的也是,请问您解决了吗?

  • 我也是 ,应用 ZLL 协议 , 遥控器 在进入 PM3 后,待机 一个小时后 ,再 发送 数据 ,感觉好像 是发不出来。 不知道 为什么 ? 灯具或遥控器   从新上电  就好了,不知道为什么 ? 还望 TI工程师 给予 答复? 

  • 请问 osal_pwrmgr_device(PWRMGR_BATTERY);是加在什么地方?

  • void BlinaApp_Init( byte task_id )

      BlinaApp_TaskID = task_id;

      BlinaApp_NwkState = DEV_INIT;

      BlinaApp_TransID = 0;

      osal_pwrmgr_device(PWRMGR_BATTERY);

      osal_pwrmgr_task_state(BlinaApp_TaskID,0);

      // Device hardware initialization can be added here or in main() (Zmain.c).

      // If the hardware is application specific - add it here.

      // If the hardware is other parts of the device add it in main().

      BlinaApp_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;

  • VV你好

              在低功耗情况下 -DRFD_RCVC_ALWAYS_ON=FALSE  ,zstack的接收(RX)在空闲状态下关闭,哪有没有什么API函数可以直接控制RX的开关??



  • 我实现了,低功耗模式,但是 我想在上电的1分钟之后再进入的话,需要怎么操作的?能提供下思路吗?

  • 剛啟動先調用 osal_pwrmgr_device( PWRMGR_ALWAYS_ON); 讓CPU先維持在非低功耗模式,然後啟動一個一分鐘的timer event,時間到的時候在調用osal_pwrmgr_device( PWRMGR_BATTERY );進入低功耗模式
  • 哈哈,非常感谢,回答的这么迅速,赞!