Other Parts Discussed in Thread: CC2538, Z-STACK
最近在量产产品中发现了一个严重问题,
我们的产品使用CC2538,工作在PM2模式,使用的32K内部时钟。当供电电压低于3V时,基于内部32K时钟的Sleep Timer会频繁的停止工作。
在电压高于3V或者使用外部32K时钟时不会有此问题。
我们的产品使用电池供电,会出现电压低于3V的情况。而为了节省IO引脚没有使用32K外部时钟。
请问这个问题是怎么回事?
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.
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), 对吗?
这个问题,彻底解决了,时钟也没有偏差了。 多谢!
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。