如题
bao lan:
进入pm2定时休眠超过40秒什么办?
da qin zheng sheng:
使用蓝牙低功耗没有?蓝牙低功耗通常不会超过40秒就会自动唤醒的。
bao lan:
回复 da qin zheng sheng:
谢谢回复!我的意思是我需要40秒以上的休眠,比如5分,6个小时等等,这种情况应该什么做?
da qin zheng sheng:
回复 bao lan:
通过软件计数,和定时器类似的。
bao lan:
回复 da qin zheng sheng:
试过了,在定时器中断里计数后马上进入休眠,程序就跑飞了。若在osal_start_system循环里计数过了时间就搜不到蓝牙,请高手赐教什么解决。
da qin zheng sheng:
回复 bao lan:
这个需要在rtc中断编程
Susan Yang:
// max allowed sleep time in ms // Note: When OSAL timer was updated to 32 bits, the call to halSleep was // changed to take a 32-bit osal_timeout value. But since the CC2540 // previously used a 16 bit ll_McuPrecisionCount, halSleep was modified // to limit osal_timeout to 16 bits as well (please see SVN rev. 27618). // However, the max value of the 16 bit ll_McuPrecisionCount is about 41s, // which is shorter than the max sleep time of 65.535s! So it is possible // Timer2 rollover could occur during sleep, which could affect when an // OSAL timer event is generated. The OSAL timer software should // be updated to use the full 24bit value of Timer2, allowing timer // events of up to 2.9 hours, but until this can be done properly, the // max sleep duration will be limited to less than ll_McuPrecisionCount. // Note: Not an issue for BLE as the max sleep time would have to be less // than 32s. #define MAX_SLEEP_TIMEOUT 40000
Alvin Chen:
回复 Susan Yang:
void osal_pwrmgr_powerconserve( void ) {uint32next;halIntState_t intState;// Should we even look into power conservationif ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON ){// Are all tasks in agreement to conserveif ( pwrmgr_attribute.pwrmgr_task_state == 0 ){// Hold off interrupts.HAL_ENTER_CRITICAL_SECTION( intState );// Get next time-outnext = osal_next_timeout();// Re-enable interrupts.HAL_EXIT_CRITICAL_SECTION( intState );// Put the processor into sleep modeOSAL_SET_CPU_INTO_SLEEP( next );}} } #endif /* POWER_SAVING */#define OSAL_SET_CPU_INTO_SLEEP(timeout) halSleep(timeout); /* Called from OSAL_PwrMgr */void halSleep( uint32 osal_timeout ){ uint32 timeout; uint32 llTimeout; uint32 sleepTimer;
#ifdef DEBUG_GPIO // TEMP P1_0 = 1;#endif // DEBUG_GPIO
// max allowed sleep time in ms if (osal_timeout > MAX_SLEEP_TIMEOUT) { osal_timeout = MAX_SLEEP_TIMEOUT; }
// get LL timeout value already converted to 32kHz ticks LL_TimeToNextRfEvent( &sleepTimer, &llTimeout );
// check if no OSAL timeout // Note: If the next wake event is due to an OSAL timeout, then wakeForRF // will already be FALSE, and the call to LL_TimeToNExtRfEvent will // already have taken a snapshot of the Sleep Timer. if (osal_timeout == 0) { // use common variable timeout = llTimeout;
// check if there's time before the next radio event // Note: Since the OSAL timeout is zero, then if the radio timeout is // not zero, the next wake (if one) will be due to the radio event. wakeForRF = (timeout != 0) ? TRUE : FALSE; } else // OSAL timeout is non-zero { // convet OSAL timeout to sleep time // Note: Could be early by one 32kHz timer tick due to rounding. timeout = HAL_SLEEP_MS_TO_32KHZ( osal_timeout );
// so check time to radio event is non-zero, and if so, use shorter value if ((llTimeout != 0) && (llTimeout < timeout)) { // use common variable timeout = llTimeout;
// the next ST wake time is due to radio wakeForRF = TRUE; } else // OSAL timeout will be used to wake { // the next ST wake time is not due to radio wakeForRF = FALSE; } }
// HAL_SLEEP_PM3 is entered only if the timeout is zero halPwrMgtMode = (timeout == 0) ? HAL_SLEEP_DEEP : HAL_SLEEP_TIMER;
#ifdef DEBUG_GPIO // TEMP P1_0 = 0;#endif // DEBUG_GPIO
// check if sleep should be entered if ( (timeout > PM_MIN_SLEEP_TIME) || (timeout == 0) ) { halIntState_t ien0, ien1, ien2;
#ifdef DEBUG_GPIO // TEMP P1_0 = 1;#endif // DEBUG_GPIO
HAL_ASSERT( HAL_INTERRUPTS_ARE_ENABLED() ); HAL_DISABLE_INTERRUPTS();
// check if radio allows sleep, and if so, preps system for shutdown if ( halSleepPconValue && ( LL_PowerOffReq(halPwrMgtMode) == LL_SLEEP_REQUEST_ALLOWED ) ) {#if ((defined HAL_KEY) && (HAL_KEY == TRUE)) // get peripherals ready for sleep HalKeyEnterSleep();#endif // ((defined HAL_KEY) && (HAL_KEY == TRUE))
#ifdef HAL_SLEEP_DEBUG_LED HAL_TURN_OFF_LED3();#else // use this to turn LEDs off during sleep HalLedEnterSleep();#endif // HAL_SLEEP_DEBUG_LED
// enable sleep timer interrupt if (timeout != 0) { // check if the time to next wake event is greater than max sleep time if (timeout > MAX_SLEEP_TIME ) { // it is, so limit to max allowed sleep time (~510s) halSleepSetTimer( sleepTimer, MAX_SLEEP_TIME ); } else // not more than allowed sleep time { // so set sleep time to actual amount halSleepSetTimer( sleepTimer, timeout ); } }
// prep CC254x power mode HAL_SLEEP_PREP_POWER_MODE(halPwrMgtMode);
// save interrupt enable registers and disable all interrupts HAL_SLEEP_IE_BACKUP_AND_DISABLE(ien0, ien1, ien2); HAL_ENABLE_INTERRUPTS();
#ifdef DEBUG_GPIO // TEMP P1_0 = 0;#endif // DEBUG_GPIO
// set CC254x power mode; interrupts are disabled after this function // Note: Any ISR that could wake the device from sleep needs to use // CLEAR_SLEEP_MODE(), which will clear the halSleepPconValue flag // used to enter sleep mode, thereby preventing the device from // missing this interrupt. HAL_SLEEP_SET_POWER_MODE();
#ifdef DEBUG_GPIO // TEMP P1_0 = 1;#endif // DEBUG_GPIO
// check if ST interrupt pending, and if not, clear wakeForRF flag // Note: This is needed in case we are not woken by the sleep timer but // by for example a key press. In this case, the flag has to be // cleared as we are not just before a radio event. // Note: There is the possiblity that we may wake from an interrupt just // before the sleep timer would have woken us just before a radio // event, in which case power will be wasted as we will probably // enter this routine one or more times before the radio event. // However, this is presumably unusual, and isn't expected to have // much impact on average power consumption. if ( (wakeForRF == TRUE) && !(IRCON & 0x80) ) { wakeForRF = FALSE; }
// restore interrupt enable registers HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2);
// power on the LL; blocks until completion // Note: This is done here to ensure the 32MHz XOSC has stablized, in // case it is needed (e.g. the ADC is used by the joystick). LL_PowerOnReq( (halPwrMgtMode == CC2540_PM3), wakeForRF );
#ifdef HAL_SLEEP_DEBUG_LED HAL_TURN_ON_LED3();#else //!HAL_SLEEP_DEBUG_LED // use this to turn LEDs back on after sleep HalLedExitSleep();#endif // HAL_SLEEP_DEBUG_LED
#if ((defined HAL_KEY) && (HAL_KEY == TRUE)) // handle peripherals (void)HalKeyExitSleep();#endif // ((defined HAL_KEY) && (HAL_KEY == TRUE)) }
HAL_ENABLE_INTERRUPTS(); }
#ifdef DEBUG_GPIO // TEMP P1_0 = 0;#endif // DEBUG_GPIO
return;}