2016-10-27 4 views
3

Разработка для STM32L053R8 на плате NUCLEO-L053R8.HAL_RCC_OscConfig занимает слишком много времени (appx 170 μS), мне нужно, чтобы оно составляло <50 μS при пробуждении от STOP

У нас есть система, которая «просыпается» от сна каждые 200 мкС или около того, выполняет ли небольшая работа, а затем возвращается в режим сна (режим остановки). В идеале я хотел бы проснуться от STOP менее 50 мкС. Функция HAL_RCC_OscConfig() занимает около 170 мкс, что делает это усилие бессмысленным.

Из того, что я вижу, большая часть времени тратится на конфигурацию PLL, в частности цикл while («Подождите, пока PLL готов»), который следует за повторным включением PLL (около 98 μS).

/* Configure the main PLL clock source, multiplication and division factors. */ 
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, 
        RCC_OscInitStruct->PLL.PLLMUL, 
        RCC_OscInitStruct->PLL.PLLDIV); 
/* Enable the main PLL. */ 
__HAL_RCC_PLL_ENABLE(); 

/* Get timeout */ 
tickstart = HAL_GetTick(); 

/* Wait till PLL is ready */ 
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) 
{ 
    if((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) 
    { 
    return HAL_TIMEOUT; 
    }  
} 

Есть ли способы пробудиться из режима STOP и вернуться к полной скорости HSI менее 50 μS? Каков наиболее эффективный способ установки часов при пробуждении из STOP?

В настоящее время я использую метод, предписанный в примере PWR_STOP, который выглядит следующим образом:

/* Enter Stop Mode */ 
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); 

/* Stop interrupt that woke us up */ 
int ret = HAL_LPTIM_TimeOut_Stop_IT(&LptimHandle); 
SystemDisableWakeupCounter(); 

/* Configures system clock after wake-up from STOP: enable HSI, PLL and select 
PLL as system clock source (HSI and PLL are disabled automatically in STOP mode) */ 
SystemClockConfig_STOP(); 

Вызов SystemClockConfig_STOP() в свою очередь, вызывает SystemClock_Config(), который настраивает часы и включает эту длительную задержку в HAL_RCC_OscConfig(&RCC_OscInitStruct).

Большое спасибо за любую помощь.

+0

Какой у вас источник PLL? –

+0

PLLSource является RCC_PLLSOURCE_HSI – PsyUk

ответ

1

Я не знаю, каков ваш источник PLL прямо сейчас, но рекомендуется HSI16. Все от reference manual.

Сигнал синхронизации HSI16 генерируется с помощью внутреннего генератора 16 МГц RC . Его можно использовать непосредственно как системные часы или как PLL-вход.

Часы HSI16 могут использоваться после пробуждения от режима Stop Low-power , что обеспечивает меньшее время пробуждения, чем пробуждение, используя часы MSI .


Если вы можете позволить немного более высокий уровень потребления, не отключать внутренний регулятор. Это компромисс: более быстрое пробуждение с более высоким потреблением или медленнее, экономя больше энергии, решайте, что является более важным.

При выходе из режима останова путем выдачи прерывания или события пробуждения, то MSI или HSI16 RC-генератор выбран в качестве системного тактового сигнала в зависимости в битовом STOPWUCK в регистре RCC_CFGR.

Когда регулятор напряжения работает в маломощном режиме, при пробуждении из режима останова возникает дополнительная задержка запуска . Сохраняя внутренний регулятор ВКЛ в режиме остановки, потребление увеличивается, хотя время запуска уменьшается.


Теперь я полагаю, с помощью PLL является обязательным, но я боюсь, что отдельно от выше, вы не можете сделать очень много о времени запуска. ФАПЧ требуется определенное время, чтобы зафиксировать на частоте входного опорного тактового сигнала. Но сначала входная частота должна стать стабильной (поэтому рекомендуется использовать HSI16).

Вместо ожидания блокировки (while) вы можете использовать прерывание.

Прерывание может быть сгенерирован, когда PLL готова, если включен в реестр RCC_CIER (см раздел 7.3.5).

И хотя PLL блокируется, вы можете выполнять некоторые задачи на частоте 16 МГц, а задачи, требующие полной скорости, могут быть запущены при получении прерывания (настройка синхронизации часов в ISR).

+1

Благодарим вас за подробную информацию. Я уже устанавливал RCC_CFGR_STOPWUCK, но я модифицировал функцию слежения, чтобы не устанавливать PLL с помощью: RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSEState = RCC_HSE_OFF; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.HSICalibrationValue = 0x10; Это разбудилось в ~ 6uS. Тогда я смог установить необходимый GPIO, а затем полностью разбудить (~ 160uS) и выполнять основные обязанности. – PsyUk

+0

re: «прерывание может быть сгенерировано, когда PLL готов, если он включен в регистре RCC_CIER» Есть ли у вас удобный пример? Я включил прерывание, а затем вступил в спящий режим при выключенном компьютере. __HAL_RCC_ENABLE_IT (RCC_IT_PLLRDY); SysTick-> CTRL = 0; HAL_PWR_EnterSLEEPMode (PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI); , но я не вижу событие, вызванное. Должно ли быть связано с EXTI каким-то образом? Если я добавлю цикл, проверяющий PLLRDY вместо ожидания во сне, я вижу, что флаг установлен. \t \t Что мне не хватает? – PsyUk

+0

@PsyUk Я еще не использовал эту функцию, просто знал об этом из справочного руководства, которое я процитировал. Сейчас я не могу это проверить, но проверю позже. –

2

Ну, datasheet говорит, что блокировка PLL может занимать до 160 мкс, поэтому задержка будет там до тех пор, пока вы пытаетесь использовать PLL.

enter image description here

вам нужно PLL вообще делать?

Вы можете настроить RCC для пробуждения с уже запущенным HSI на частоте 16 МГц (см. Бит RCC_CFGR_STOPWUCK). Вы получаете только половину скорости, но он работает и работает на 6 человек.

+0

Спасибо за ссылку. Мне действительно нужна PLL, и RCC_CFGR_STOPWUCK уже установлен. Установка PLLState на None дает более быстрое пробуждение и, после выполнения необходимых задач, я затем устанавливаю состояние PLL в On. – PsyUk

Смежные вопросы