CC2541进入pm休眠最多40秒,超过40秒什么办?
如题
进入pm2定时休眠超过40秒什么办?
使用蓝牙低功耗没有?蓝牙低功耗通常不会超过40秒就会自动唤醒的。
谢谢回复!我的意思是我需要40秒以上的休眠,比如5分,6个小时等等,这种情况应该什么做?
通过软件计数,和定时器类似的。
试过了,在定时器中断里计数后马上进入休眠,程序就跑飞了。若在osal_start_system循环里计数过了时间就搜不到蓝牙,请高手赐教什么解决。
这个需要在rtc中断编程
// 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
void osal_pwrmgr_powerconserve( void ) { uint32 next; halIntState_t intState; // Should we even look into power conservation if ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON ) { // Are all tasks in agreement to conserve if ( pwrmgr_attribute.pwrmgr_task_state == 0 ) { // Hold off interrupts. HAL_ENTER_CRITICAL_SECTION( intState ); // Get next time-out next = osal_next_timeout(); // Re-enable interrupts. HAL_EXIT_CRITICAL_SECTION( intState ); // Put the processor into sleep mode OSAL_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;
}