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 ZigbeeStack中功耗管理是如何实现的?

Other Parts Discussed in Thread: CC2530

1、CC2530 ZigbeeStack中功耗管理是如何实现的?

方法:动态调整睡眠定时器的溢出周期,MCU进入睡眠模式,由睡眠定时器中断或者外部中断唤醒MCU

2、程序实现:

(1)void osal_pwrmgr_powerconserve( void )

(2)uint32 osal_next_timeout( void )

(3)void halSleep( uint32 osal_timeout )

不理解void halSleep( uint32 osal_timeout )中的轮询,时间递减的原理。

(1)为什么每次减去的是HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME );

(2)设置电源模式: HAL_SLEEP_SET_POWER_MODE()中, HAL_DISABLE_INTERRUPTS();

唤醒源:睡眠定时器中断或者外部中断,但是这里关闭了中断,那系统是如何唤醒的??

      do
      {
        /* enable sleep timer interrupt */
        if(timeout != 0)
        { 
          if (timeout > HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ))
          {
            timeout -= HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME );
            halSleepSetTimer(HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ));
          }
          else
          {
            /* set sleep timer */
            halSleepSetTimer(timeout);
            timeout = 0;
          }
          
          /* set up sleep timer interrupt */
          HAL_SLEEP_TIMER_CLEAR_INT();
          HAL_SLEEP_TIMER_ENABLE_INT();
        }
				
        /* Prep CC2530 power mode */
        HAL_SLEEP_PREP_POWER_MODE(halPwrMgtMode);

        /* save interrupt enable registers and disable all interrupts */
        HAL_SLEEP_IE_BACKUP_AND_DISABLE(ien0, ien1, ien2);
        HAL_ENABLE_INTERRUPTS();

        /* set CC2530 power mode, interrupt is disabled after this function
         * Note that an ISR (that could wake up from power mode) which runs
         * between the previous instruction enabling interrupts and before
         * power mode is set would switch the halSleepPconValue so that
         * power mode shall not be entered in such a case. 
         */
        
        HAL_SLEEP_SET_POWER_MODE();
        
        /* the interrupt is disabled - see halSetSleepMode() */
        
        /* restore interrupt enable registers */
        HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2);

        /* disable sleep timer interrupt */
        HAL_SLEEP_TIMER_DISABLE_INT();

      } while(timeout != 0);

  • 1. 因为CC2530 使用的32M晶振
    2./* restore interrupt enable registers */

    /* set CC2530 power mode, interrupt is disabled after this function
    * Note that an ISR (that could wake up from power mode) which runs
    * between the previous instruction enabling interrupts and before
    * power mode is set would switch the halSleepPconValue so that
    * power mode shall not be entered in such a case.
    */

    HAL_SLEEP_SET_POWER_MODE();

    /* the interrupt is disabled - see halSetSleepMode() */

    /* restore interrupt enable registers */
    HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2);
  • Alivin,您好
    如下理解是否正确:
    (1)设置HAL_SLEEP_PREP_POWER_MODE(halPwrMgtMode);设置了电源模式
    (2)设置HAL_SLEEP_SET_POWER_MODE();
    PCON = halSleepPconValue ;实际就是PCON = 0x01;此时MCU就进入了(1)中设置的电源模式,此时MCU只能中断唤醒,而不是我理解的
    继续执行了HAL_DISABLE_INTERRUPTS();导致无法产生中断
    (3)睡眠定时器溢出,产生中断时,设置PCON = 0x00;恢复到正常模式
    所以此处的轮询周期就是设置的定时器溢出周期:HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME )
  • #define HAL_SLEEP_PREP_POWER_MODE(mode) st( SLEEPCMD &= ~PMODE; /* clear mode bits */ \
    SLEEPCMD |= mode; /* set mode bits */ \
    while (!(STLOAD & LDRDY)); \
    halSleepPconValue = PCON_IDLE; \

    休眠定时器到的时候有两种方式,一种是中断,一种检测标志位

    在协议栈里面HAL_SLEEP_PREP_POWER_MODE不仅设置了睡眠模式而且这个函数中在检测标志位。

    #define HAL_SLEEP_SET_POWER_MODE() halSetSleepMode()
    void halSetSleepMode(void)
    {
    PCON = halSleepPconValue;                                                                         //halSleepPconValue=1
    HAL_DISABLE_INTERRUPTS();
    }

  • Alvin 您好:
    (1)void halSleepSetTimer(uint32 timeout);设置定时器比较值
    (2)HAL_SLEEP_PREP_POWER_MODE(halPwrMgtMode);
    设置供电模式(SLEEPCMD |= halPwrMgtMode)
    等待睡眠定时器准备好加载新的比较值(STLOAD & LDRDY = 1)
    halSleepPconValue = PCON_IDLE = 0x01
    (3)HAL_SLEEP_SET_POWER_MODE()
    PCON = halSleepPconValue; 此处写入PCON寄存器,MCU就会进入SLEEPCMD 设置的电源模式,此时MCU进入睡眠模式
    (4)等待外部中断或者睡眠定时器中断

    不理解您说的:
    休眠定时器到的时候有两种方式,一种是中断,一种检测标志位

    while (!(STLOAD & LDRDY))
    Datasheet中 LDRDY 的说明:

    Load ready. This bit is 0 while the Sleep Timer loads the 24-bit compare value and 1 when the
    Sleep Timer is ready to start loading a new compare value.

    谢谢指导。
  • 你的理解是正确的,我的指的是ST:
    休眠定时器到的时候有两种方式,一种是中断,一种检测标志位

    在协议栈里面HAL_SLEEP_PREP_POWER_MODE这个函数中在检测标志位,