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.

关于PM3模式下,终端节点扔在发送Data Request

Other Parts Discussed in Thread: Z-STACK

如题,通过

SLEEPCMD |= 3; //设置系统睡眠模式
PCON = 0x01; //进入睡眠模式 ,通过中断唤醒

让芯片进入睡眠模式后,用抓包工具发现EndDevice扔在发送DataRequest,这与我的认知不服呀,用的Home1.2.2a协议栈,芯片为CC2530F256,预编译为

SECURE=0
ISR_KEYINTERRUPT
xPOWER_SAVING
ZIGBEE_FRAGMENTATION
xTC_LINKKEY_JOIN
xNV_INIT
xNV_RESTORE
NWK_AUTO_POLL
HOLD_AUTO_START
HAL_UART=TRUE
ZAPP_P1
MT_TASK
MT_APP_FUNC
MT_SYS_FUNC
MT_ZDO_FUNC

  • NWK_AUTO_POLL會讓EndDevice定時喚醒发送DataRequest
  • 你确定你进入了?
    你要设置POLLRATE=0 ,先把NWK_AUTO_POLL关了,Z-stack有自己的PM机制,不建议自己手动操作。
  • 都进入PM3模式了,振荡器都关了的,定时器啥的都不起作用了的嘛,NWK_AUTO_POLL是怎么发挥作用的啊?
  • 如果還會看到data request就代表你沒有成功进入PM3模式
  • 要通过关闭所有定时事件使芯片进入PM3模式太难了,我所理解的是只要执行
    SLEEPCMD |= 3; //设置系统睡眠模式
    PCON = 0x01; //进入睡眠模式 ,通过中断唤醒
    芯片肯定应该进入深度睡眠模式,凌驾于一切机制之上,什么都不干的啊
  • 我都执行了
    SLEEPCMD |= 3; //设置系统睡眠模式
    PCON = 0x01; //进入睡眠模式 ,通过中断唤醒
    为何芯片还没有进入PM3模式了,会存在哪些因素影响?
  • 怎么判断有没有成功进入PM3模式了?
  • 你的理解不太对,只有poll rate在就会存在一个定时器,

    而且也不是很难我们有过相关指导的分享。

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

    在协议栈宏定义中使能POWER_SAVING后,然后在f8wConfig.cfg文件里面把-DRFD_RCVC_ALWAYS_ON=FALSE,就可以让End Device进入休眠状态。
    关于休眠的时间是有OSAL操作系统的调度来决定,每次休眠时间都是按照最新会发生的一个Event Timeout作为休眠时间。具体在协议栈hal_sleep函数中有说明。
    这个timeout主要分为两类,一类是应用层事件的timeout,另外一类是MAC层事件的timeout,
    1)应用层的timeout的时间,是在osal_pwrmgr_powerconserve( void )函数中,通过osal_next_timeout();获得的。
    2)MAC层的timeout时间,是通过halSleep( uint16 osal_timeout )函数里面,通过MAC_PwrNextTimeout();来获得的。
  • 試試下面從cc254x抓出來pm3的測試程式

    /***********************************************************************************
    * CONSTANTS
    */
    // Wait time in Active mode.
    #define ACT_MODE_TIME 50000


    /***********************************************************************************
    * LOCAL VARIABLES
    */
    // Variable for active mode duration.
    static uint32 __xdata activeModeCnt = 0;


    /***********************************************************************************
    * LOCAL FUNCTIONS
    */

    /***********************************************************************************
    * @fn setup_port_interrupt
    *
    * @brief Function which sets up the Port 0 Interrupt for Power Mode 3 usage.
    *
    * @param void
    *
    * @return void
    */
    void setup_port_interrupt(void)
    {
    // Clear Port 0 Interrupt flags.
    P0IF = 0;
    P0IFG = 0x00;

    // Interrupt enable on all pins on port 0.
    P0IEN = 0xFF;

    // Enable CPU Interrupt for Port 0 (IEN1.P0IE = 1).
    P0IE = 1;

    // Enable Global Interrupt by setting the (IEN0.EA = 1).
    EA = 1;
    }


    /***********************************************************************************
    * @fn port0_isr
    *
    * @brief Port 0 Interrupt Service Routine, which executes when SRF05EB S1
    * (P0_1) is pressed.
    *
    * @param void
    *
    * @return void
    */
    #pragma vector = P0INT_VECTOR
    __interrupt void port0_isr(void)
    {
    // Note that the order in which the following flags are cleared is important.

    // Clear Port 0 Interrupt Flags.
    P0IFG = 0x00;

    // Clear CPU Interrupt Flag for P0 (IRCON.P0IF = 0).
    P0IF = 0;

    // Set LED1 to indicate Active Mode.
    P1_0 = 1;
    }


    /***********************************************************************************
    * @fn main
    *
    * @brief Enter Power Mode, exit Power Mode 3 using Port 0 Interrupt.
    *
    * @param none
    *
    * @return 0
    */

    void main(void)
    {
    /***************************************************************************
    * Setup I/O
    */
    // Initialize P1_0 for SRF05EB LED1.
    P1SEL &= ~BIT0; // Function as General Purpose I/O.
    P1_0 = 1; // LED1 on.
    P1DIR |= BIT0; // Output.

    // Initialize P0_1 for SRF05EB S1 button.
    P0SEL &= ~BIT1; // Function as General Purpose I/O.
    P0DIR &= ~BIT1; // Input.
    P0INP |= BIT1; // 3-state input.


    /***************************************************************************
    * Setup interrupt
    *
    * Setup and enable Port 0 Interrupt, which shall wake-up the SoC from
    * Power Mode 3.
    */
    setup_port_interrupt();


    /***********************************************************************
    * Setup powermode
    */
    // Set [SLEEPCMD.MODE] to PM3.
    SLEEPCMD = (SLEEPCMD & ~SLEEPCMD_MODE) | SLEEPCMD_MODE_PM3;


    /* Main Loop, enter/exit Power Mode 3. */
    while(1)
    {
    // Wait some time in Active Mode, and clear LED1 before
    // entering Power Mode 3.
    for(activeModeCnt = 0; activeModeCnt < ACT_MODE_TIME; activeModeCnt++);
    P1_0 = 0;

    // Enter powermode
    // Sets PCON.IDLE with a 2-byte boundary assembly instruction.
    // NOTE: Cache must be enabled (see CM in FCTL).
    // This method gives the least current consumption.
    EnterSleepModeProcessInterruptsOnWakeup();

    }
    }