精读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就不行了。


于是看看休眠模式:


问题就是用在了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级的休眠则不休了,但是一些长时间的深度休眠依然可以!!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在划线处完成SampleApp工程应用层初始化函数代码的注释(用中文简述各段代码)。 void SampleApp_Init( uint8 task_id ) { SampleApp_TaskID = task_id; SampleApp_NwkState = DEV_INIT; SampleApp_TransID = 0; // #if defined ( BUILD_ALL_DEVICES ) // The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START // We are looking at a jumper (defined in SampleAppHw.c) to be jumpered // together - if they are - we will start up a coordinator. Otherwise, the device will start as a router. if ( readCoordinatorJumper() ) zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR; else zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER; #endif // BUILD_ALL_DEVICES // #if defined ( HOLD_AUTO_START ) // HOLD_AUTO_START is a compile option that will surpress ZDApp // from starting the device and wait for the application to start the device. ZDOInitDevice(0); #endif // SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; // SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; // SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_epDesc.task_id = &SampleApp_TaskID; SampleApp_epDesc.simpleDesc=(SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc; SampleApp_epDesc.latencyReq = noLatencyReqs; // Register the endpoint description with the AF afRegister( &SampleApp_epDesc ); // Register for all key events - This app will handle all key events RegisterForKeys( SampleApp_TaskID ); // By default, all devices start out in Group 1 SampleApp_Group.ID = 0x0001; osal_memcpy( SampleApp_Group.name, "Group 1", 7 ); aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); }
最新发布
06-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值