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.

CC2538在PM2模式下的内部时钟问题。

Other Parts Discussed in Thread: CC2538, Z-STACK

最近在量产产品中发现了一个严重问题,

我们的产品使用CC2538,工作在PM2模式,使用的32K内部时钟。当供电电压低于3V时,基于内部32K时钟的Sleep Timer会频繁的停止工作。

在电压高于3V或者使用外部32K时钟时不会有此问题。

我们的产品使用电池供电,会出现电压低于3V的情况。而为了节省IO引脚没有使用32K外部时钟。

请问这个问题是怎么回事?

  • Luffy, 

    在协议栈里面有没有32K的源改成RC。

    #if !defined (OSC32K_CRYSTAL_INSTALLED)
    //defeualt to fitted
    #define OSC32K_CRYSTAL_INSTALLED FALSE

    #endif

    正对休眠这块,你们自己有没有改动过,还是直接使能了POWER_SAVING就可以了。

    电压在2V以下会有问题的。

    你说的频繁的停止工作,是指没办法唤醒了吗?

  • 已经改了,32 k源确定是内部的RC.

    对休眠这块没有改过,直接用POWER_SAVING

    停止工作是指, sleep timer停止计时。 在<3v时, 2.9也可以,睡前和醒后count值没有变化。>3v时,正常。

  • 你们手上水否有TI官方的开发板,做过测试吗?

    另外你们供电这块跟TI的官方参考设计对比过,包括供电的外围电路。

    板子上除了CC2538以外,还没有其他的外设器件么?

  • 我们手里没有开放板子。 我们做了TI 的zigbee平台已经快8年了, 从cc2430->cc2530->cc2630->cc2538,项目太多了。您能否帮忙试试?

  • 了解,谢谢对TI一贯的支持。

    能不能把你们具体复现这个问题的流程,看到什么现象,告诉我下。我可以在我们的开发板上面测试下。

    包括你们使用的软件协议栈版本?

  • 在Z-Stack Home 1.2.2.42930里,找个end device工程,  使用osal_start_timerEx启动30s的timer,timer到后闪灯。 在<3V 下,去查看是不是30s.

  •  好的,今天我测试下。

  • 我这边测试在电压低于3V,在2.4v的时候都没有问题的。

    示波器节点LED的I/O上面,电压每格是600mv,总共4格,2,4v。

    我做了两次测试,1次10s,另外1次30s

    你们使用的高频晶振,供电这块再检查下。

  • 你们有void SysCtrlDeepSleep(void) 函数源码吗?  我发现在调用完这个函数后,再调用HAL_CLOCK_STABLE 就可以了。 但跑了5分钟后,差近5s。这个差值,我正在调整。

  • void
    SysCtrlDeepSleep(void)
    {
    #ifndef NO_CLOCK_DIVIDER_RESTORE
    bool bRestoreSys;
    bool bRestoreIO;
    uint32_t ui32Reg;

    ui32Reg = HWREG(SYS_CTRL_CLOCK_STA);
    bRestoreSys = (ui32Reg & SYS_CTRL_CLOCK_STA_SYS_DIV_M)==0;
    bRestoreIO = (ui32Reg & SYS_CTRL_CLOCK_STA_IO_DIV_M)==0;
    if(bRestoreSys || bRestoreIO)
    {
    ui32Reg = HWREG(SYS_CTRL_CLOCK_CTRL);
    ui32Reg |= bRestoreSys? 0x1:0x0;
    ui32Reg |= bRestoreIO? 0x100:0x0;
    HWREG(SYS_CTRL_CLOCK_CTRL) = ui32Reg;
    }
    #endif

    //
    // Enable deep-sleep.
    //
    HWREG(NVIC_SYS_CTRL) |= NVIC_SYS_CTRL_SLEEPDEEP;

    //
    // Wait for an interrupt.
    //
    CPUwfi();

    //
    // Disable deep-sleep so that a future sleep will work correctly.
    //
    HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP);

    #ifndef NO_CLOCK_DIVIDER_RESTORE
    if(bRestoreSys || bRestoreIO)
    {
    ui32Reg = HWREG(SYS_CTRL_CLOCK_CTRL);
    ui32Reg &= bRestoreSys ? ~SYS_CTRL_CLOCK_CTRL_SYS_DIV_M : 0xffffffff;
    ui32Reg &= bRestoreIO ? ~SYS_CTRL_CLOCK_CTRL_IO_DIV_M : 0xffffffff;
    HWREG(SYS_CTRL_CLOCK_CTRL) = ui32Reg;
    }
    #endif
    }

    从16M 切到32M,没有时钟stable(HAL_CLOCK_STABLE), 对吗?

  • 为什么要改动这个代码,我这边测试没想你说的5分钟有5s的偏差,所以我觉得是不是在硬件找找问题,如果代码上没有改动的话

  • 这个问题,彻底解决了,时钟也没有偏差了。 多谢!

    SysCtrlDeepSleep之后的HAL_CLOCK_STABLE必须要有。 datasheet 写到:“When the 32-kHz RC oscillator is enabled, it is calibrated when a switch from the 16-MHz RC oscillator to the 32-MHz crystal oscillator is performed while SLEEPCMD.OSC32K_CALDIS is 0.”  而SysCtrlDeepSleep这个函数睡前把32M切换到16M, 醒后又切回32M,这个过程可能发生了calibarte。

  • 解决就好,

    你们选择32M晶振 ppm是多少的?那天我测试也没有出现你说的5分钟,差5秒,那么厉害。