天天看点

精读OSAL --时钟及休眠(hal_sleep.c)

CC25XX系列的SOC上面有两个高频时钟(32MHz外部晶振,16MHz的内部RC时钟),和两个低频时钟(32Khz的外部晶振,12KHz的内部RC时钟)。

文档仔细看过就明白,16Mhz的内部高频时钟是不能作RF时钟,只能在某些时候(中断)作快速启动的时钟源,涉及RF的操作都要等待32MHz的外部晶振

起振及稳定。所以32Mhz的晶振是必需的。而32Khz的低频时钟则可以二选一,内部32KHz的RC时钟是不精确的,要靠32Mhz稳定后,校正。外部32KHz则

没有这个问题。这里有个坑。。

是这样的,我要用到好多IO,于是外部32Khz晶振的IO就用上了,就配置用内部32KHzRC时钟,具体配置在hal_board_cfg.h如下:

// For non-USB, assume external, unless an internal crystal is explicitly indicated.
#if !defined (XOSC32K_INSTALLED) || (defined (XOSC32K_INSTALLED) && (XOSC32K_INSTALLED == TRUE))
#define OSC_32KHZ                     EXTERNAL_CRYSTAL_OSC
#else
#define OSC_32KHZ                     INTERNAL_RC_OSC
#endif
           

主要就是XOSC32K_INSTALLED这个宏,不同板有不同的默认值,dongle就默认不装,mindk则默认装。可以在IAR的预定义里直接定义。

好,定义好了,没定义POWER_SAVING时是好的,定义了POWER_SAVING就不行了。

于是看看休眠模式:

精读OSAL --时钟及休眠(hal_sleep.c)

问题就是用在了PM2里,因为OSAL一些1ms的定时是用32Khz的,而且是协议相关的,好死不死内部RC在没有了32Mhz时变得不准,通信就不行了。

方法就是要么装32K晶振,要么就关POWER_SAVING。。。

但是我还是找到一个折中的方案在hal_sleep.c中:

// POWER CONSERVATION DEFINITIONS
// Sleep mode H/W definitions (enabled with POWER_SAVING compile option).
#define CC2540_PM0                          0                     // PM0, Clock oscillators on, voltage regulator on
#define CC2540_PM1                          1                     // PM1, 32.768 kHz oscillators on, voltage regulator on
#define CC2540_PM2                          2                     // PM2, 32.768 kHz oscillators on, voltage regulator off
#define CC2540_PM3                          3                     // PM3, All clock oscillators off, voltage regulator off

// HAL power management mode is set according to the power management state.
// The default setting is HAL_SLEEP_OFF. The actual value is tailored to
// different HW platform. Both HAL_SLEEP_TIMER and HAL_SLEEP_DEEP selections
// will turn off the system clock, and halt the MCU. HAL_SLEEP_TIMER can be
// woken up by sleep timer interrupt, I/O interrupt and reset. HAL_SLEEP_DEEP
// can be woken up by I/O interrupt and reset.
#define HAL_SLEEP_OFF                       CC2540_PM0
#define HAL_SLEEP_TIMER                     CC2540_PM0
#define HAL_SLEEP_DEEP                      CC2540_PM3
           

HAL_SLEEP_TIMER强行定义成PM0,即一些ms级的休眠则不休了,但是一些长时间的深度休眠依然可以!!