Энергосберегающий режим

Большинство интегральных микросхем, особенно микроконтроллеры, строятся на КМОП-технологии. Их отличительной чертой является то, что для удержания логического уровня на транзисторе энергия не расходуется, в отличие от биполярного исполнения. Энергия тратится только на переключение транзисторов из одного состояние в другое, т.е. при заряде и разряде паразитной емкости затвора. Таким образом, частота переключения напрямую влияет на энергопотребление устройства. Чем выше частота, тем выше потребляемый ток. При питании устройства от сети потребляемые лишние миллиамперы не столь важны — проблемы начинаются, когда используется батарейное питание. Если вся остальная схема устройства спроектирована правильно (используются большие номиналы резисторов для уменьшения протекания тока через цепи, эффективные преобразователи, элементы с низким током утечки), то единственным, с чем возможно экспериментировать, остается сам микроконтроллер.

Присутствует ток утечки, но им можно пренебречь.

Такую информацию обычно приводят в документации на микроконтроллер.

Вспомнив закон Ома, можно предложить понизить напряжение питания до минимально возможного для данного микроконтроллера. Согласно документации на микроконтроллер stm32f103c8, минимальное напряжение, при котором сам контроллер будет работать нормально, это 2,0 вольта. Здесь, однако, стоит помнить, что некоторые цепочки вне МК могут перестать функционировать как следует. Если на плате имеется, скажем, зеленый светодиод, то при питании ниже его прямого напряжения (обычно 2,2 В) он просто не будет светиться при выставлении высокого логического уровня на ножке МК. Если что-то подключено через обычный диод, то стоит помнить, что падение на нем составляет порядка 0,7 В, что в итоге может оказаться ниже порога срабатывания внешней микросхемы.

Напряжение питания (обычно 3,3 В) понижается внутренним преобразователем до 1,8 В и используется ядром Cortex-M3. Микроконтроллеры STM8L можно запустить от напряжения 1,8 В, а MSP430 будет работать и от 0,9 В.

Понижение напряжения — вполне оправданый подход, например, рабочее напряжение питания компьютерной плашки оперативной памяти DDR SDRAM составляет 2,6 В. Рынок носимых устройств расширяется с каждым днем, и потому для увеличения срока автономной работы устройства снижают рабочие напряжения. Так, стандарт памяти LPDDR4 работает от 1,1 В, что существенно улучшает характеристики энергопотребления.

Другой подход — аппаратно-программный. Допустим, у нас имеется велокомпьютер. Его основная задача — измерить скорость и вывести актуальные данные на дисплей. Скорость определить довольно легко: если мы поместим магнит на обод колеса и датчик Холла на вилку, то, измерив время между срабатываниями датчика, можно рассчитать расстояние, которое проехал велосипедист, ведь периметр обода нам известен. Таким образом, энергия батарейки между срабатываниями датчика холла будет тратиться впустую: нет данных, которые можно подсчитать, нечего выводить на дисплей. Или тот же пример с часами: очевидно, что обновлять показание на дисплее не имеет смысла чаще, чем раз в секунду. Следовательно, работать микроконтроллеру в эти промежутки на максимальной частоте нет никакого смысла. Более того, кроме ядра, энергию потребляют и периферийные блоки — их также имеет смысл отключить, если они не используются. Ниже приведен график, иллюстрирующий потребление тока (условно) от времени для велокомпьютера.

Таким образом, проинтегрировав по времени, легко заметить, что количество потребленной энергии уменьшилось. Контроллер stm32f103c8 поддерживает разные энергосберегающие режимы: нормальный, спящий (англ. sleep) режим; режим остановки (англ. stop); и режим ожидания (англ. standby). Переход в любой из них осуществляется при помощи вызова ассемблерных инструкций (intrinsic-функций) WFI (сокр. Wait For Interrupt) и WFE (англ. Wait For Event).

Данный МК не относится к семейству низкого энергопотребления (L-серия), функциональность ограничена.

__WFI();
__WFE();

Из названия должно быть понятно, что выход из режима пониженного энергопотребления происходит либо по прерыванию, либо по событию. Прерывание или событие может быть как внутреннее (не для всех режимов), так и внешнее. В нашем случае с велокомпьютером при появлении магнита над датчиком Холла напряжение на ножке МК изменяется, а значит, логичнее всего использовать прерывание от модуля EXTI для возобновления работы. Но какой же режим выбрать?

В самом «мягком», режиме сна, тактирование ядра останавливается, периферия продолжает работу, а выходы сохраняют свое состояние. После того как сработает прерывание (или событие), тактирование возобновляется, а программа начинает выполняться с того места, где была прервана.

Следующий режим, остановки, позволяет уменьшить потребление энергии еще больше: все генераторы, в том числе умножитель частоты PLL, отключаются, однако выводы МК по-прежнему сохраняют свое состояние. Ниже приведена функция из стандартной библиотеки stm32, позволяющая войти в данный режим работы.

void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) {
    uint32_t tmpreg = 0;
    /* Check the parameters */
    assert_param(IS_PWR_REGULATOR(PWR_Regulator));
    assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
    
    /* Select the regulator state in STOP mode ---------------------------------*/
    tmpreg = PWR->CR;
    /* Clear PDDS and LPDS bits */
    tmpreg &= CR_DS_MASK;
    /* Set LPDS bit according to PWR_Regulator value */
    tmpreg |= PWR_Regulator;
    /* Store the new value */
    PWR->CR = tmpreg;
    /* Set SLEEPDEEP bit of Cortex System Control Register */
    SCB->SCR |= SCB_SCR_SLEEPDEEP;
    
    /* Select STOP mode entry --------------------------------------------------*/
    if(PWR_STOPEntry == PWR_STOPEntry_WFI) {
        /* Request Wait For Interrupt */
        __WFI();
    } else {
        /* Request Wait For Event */
        __WFE();
    }
    
    /* Reset SLEEPDEEP bit of Cortex System Control Register */
    SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);  
}

Стоит понимать, что выйти из такого состояния можно только при помощи внешнего воздействия (события или прерывания от EXTI), так как, например, таймер уже работать не сможет ввиду отсутствия источника тактирования. Если в микроконтроллере присутствует блок RTC со своим источником тактирования (внутренней низкочастотной цепочкой или внешним кварцевым резонатором), то выйти из состояния можно по прерыванию от него.

Последний режим, ожидания, самый жесткий и энергоэффективный, но имеет и свои ограничения. Отключается практически всё: вся система тактирования, внутренний регулятор напряжения, что приводит к потере данных в регистрах и оперативной памяти. Единственное, что может работать в таком режиме, это блок часов реального времени и сторожевой таймер. При выходе из этого режима микроконтроллер будет находиться в таком же состоянии, как и при первом старте, т.е. в сброшенном. Всю периферию придется настраивать заново. Ниже приведена функция из стандартной библиотеки, позволяющая войти в данный режим.

void PWR_EnterSTANDBYMode(void) {
  /* Clear Wake-up flag */
  PWR->CR |= PWR_CR_CWUF;
  /* Select STANDBY mode */
  PWR->CR |= PWR_CR_PDDS;
  /* Set SLEEPDEEP bit of Cortex System Control Register */
  SCB->SCR |= SCB_SCR_SLEEPDEEP;
    /* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM   )
  __force_stores();
#endif
  /* Request Wait For Interrupt */
  __WFI();
}

Выйти из него можно несколькими способами: по нарастающему фронту на специальной ножке WKUP (англ. WaKe UP, проснуться), сигналу от блока RTC или сторожевого таймера, либо сбросив питание (напрямую или через ножку NRST).

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

0

Изменено: