4927 subscribers

Микроконтроллеры для начинающих. Часть 40. Использование режимов сна STM8

211 full reads
419 story viewsUnique page visitors
211 read the story to the endThat's 50% of the total page views
2,5 minutes — average reading time

Мы уже рассмотрели режимы сна в микроконтроллерах AVR и PIC

"Микроконтроллеры для начинающих. Часть 38. Использование режимов сна AVR"

"Микроконтроллеры для начинающих. Часть 39. Использование режимов сна PIC и PIC18"

Осталось рассмотреть последнее семейство - STM8. Режимы сна STM8 во многом похожи не уже рассмотренные за исключением специфичного для STM8L режима - Wait For Event. Как всегда, начнем с рассмотрения реализации в микроконтроллере и завершим примерами программ.

Режимы сна в STM8

STM8S и STM8L имеют несколько различающийся набор режимов сна. Это связано с тем, что STM8L в принципе ориентированны на использование в устройствах с очень малым потреблением.

Дополнительной особенностью STM8 является наличие внутренней схемы управления питанием, которую документация называет MVR - главный регулятор напряжения (Main Voltage Regulator). В STM8S он может быть включен и и выключен, а в STM8L может быть переведен в режим ультра низкой мощности (Ultra-low-power mode (ULP)). Причем это перевести MVR в режим ULP можно не только в режимах сна.

Режимы работы внутренней схемы питания оказывают влияние на все режимы работы микроконтроллера, но не относятся к режимам сна напрямую. Точно так же, не относится к режимам сна включение/выключение тактирования периферийных модулей.

Во всех режимах сна процессор микроконтроллера останавливается. То есть, в STM8 нет аналога режима дрёмы (Doze mode) PIC.

В режиме ожидания (Wait Mode) сохраняется работа тактового генератора и всех периферийных модулей (если их тактирование и питание не отключены дополнительно).

В режиме активного останова (Active Halt Mode) дополнительно останавливается тактовый генератор, за исключением LSI (низкочастотный внутренний RC генератор) и HSE (генератор с внешним кварцевым резонатором). Кроме того, останавливается работа периферийных модулей, за исключением AWU (STM8S), RTC (STM8L) и контроллера LCD (STM8L).

Режим останова (Halt Mode) микроконтроллер останавливается полностью. И вывести его из этого состояния можно только через вход внешнего прерывания или сброс.

Режим останова

В этот режим микроконтроллер переводится машинной командой HALT. А выйти из него можно только через внешнее прерывание или сброс.

Для STM8L не рекомендуется переходить в режим останова из рабочего режима низкого потребления (Low power run mode).

Поскольку микроконтроллер был остановлен полностью, время пробуждения из этого режима самое большое. Что бы его сократить рекомендуется перед переходом в режим останова переключиться на внутренний RC тактовый генератор (HSI или LSI).

Кроме того, предусматривается процедура быстрого пробуждения, которая разрешается установкой бита FHW (FHWU) регистра CLK_ICKR (Internal clock register) модуля тактового генератора микроконтроллера. Подробно этот модуль мы будем изучать отдельно. Для STM8L при установке этого бита после пробуждения устанавливается тактовая частота HSI/8 (высокочастотный внутренний RC генератор с делителем 1:8).

Поскольку эффект от сброса понятен, рассмотрю лишь пробуждение от внешнего прерывания. Когда микроконтроллер полностью проснется будет выполнена процедура обработки прерывания, а вот дальнейшие действия зависят от состояния бита AL регистра CFG_GCR. Если этот бит сброшен, то программа продолжит выполнение с команды следующей за командой вызвавшей переход в режим сна (HALT, WFI). Если же этот бит установлен, то микроконтроллер снова погрузится в тот же самый режим сна. В данном случае, в режим останова.

Давайте сначала рассмотрим и режим активного останова, а потом сразу рассмотрим общий пример программы и описания нужных регистров.

Режим активного останова

Для STM8L режим активного останова идентичен режиму останова, за исключением того, что работа некоторых тактовых генераторов и RTC не останавливается.

А вот для STM8S этот режим более интересен. Дело в том, что в этих микроконтроллерах есть модуль AWU (Auto WakeUp module), который может работать независимо от ядра. Более подробно этот модуль мы рассмотрим отдельно. Сейчас для нас важно, что этот модуль является специальным таймером, который при переполнении и пробуждает микроконтроллер. В данной статье я буду считать, что этот модуль уже настроен и просто нужно разрешить его работу. Разрешает работу AWU установка бита AWUEN регистра Control/status register (AWU_CSR).

В рабочем режиме AWU остановлен, а при выполнении команды HALT (если его работа разрешена) счетчик таймера сбрасывается и начинается счет. При переполнении счетчика таймера микроконтроллер просыпается и работа продолжается со следующей за HALT команды.

Разумеется, разбудить микроконтроллер можно и внешним прерыванием и сбросом. При этом продолжение работы, после обработки прерывания, будет зависеть от бита AL, как я уже описывал выше.

Дополнительно, можно автоматически отключать MVR при переходе в этот режим сна с помощью бита REGAH (STM8S) или SAHALT (STM8L). Но это увеличивает время пробуждения.

Описание регистров и пример программного использования режимов останова

Как обычно, для примеров будет использоваться компилятор SDCC версии 4.0

А теперь давайте посмотрим на описание в программе на С регистров, которые я упоминал

Описание фрагментов регистров STM8 используемых для иллюстрации работы с режимами останова. Код мой
Описание фрагментов регистров STM8 используемых для иллюстрации работы с режимами останова. Код мой
Описание фрагментов регистров STM8 используемых для иллюстрации работы с режимами останова. Код мой

Я описал не регистры полностью, а только нужные нам биты. Адреса регистров могут различаться в разных микроконтроллерах, поэтому я описал их отдельно и привел конкретные значения для STM8S105K6. Для вашего микроконтроллера нужно заменить их на адреса из документации. Обратите внимание, что описание регистра CLK_ICKR для STM8L помещено в комментарий, что бы не мешать компиляции.

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

А теперь пример программы использующей эти описания и переключающейся в режимы останова

Пример программы STM8 использующей режимы останова. Код мой
Пример программы STM8 использующей режимы останова. Код мой
Пример программы STM8 использующей режимы останова. Код мой

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

Режим ожидания прерывания STM8S и STM8L

В микроконтроллерах STM8S есть режим ожидания, в который можно перейти с помощью машинной команды WFI (Wait For Interrupt). Как я уже говорил ранее, в режиме ожидания останавливается процессор, но остальные модули продолжают работать.

При возникновении запроса прерывания микроконтроллер просыпается и управление передается по вектору соответствующего прерывания. А после завершения обработки прерывания действия микроконтроллера определяются битом AL регистра CFG_GCR, как я это уже описывал ранее. Только вместо режима останова происходит возврат в режим ожидания, если AL=1.

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

У таймера 4 (TIM4) есть возможность вызвать прерывание при обновлении счетчика (переполнении). Для разрешения генерации такого прерывания должен быть установлен бит UIE регистра TIM4_IER. На этом краткий экскурс в работу TIM4 я завершу на сегодня. На пока этого достаточно.

Если мы хотим подождать и пробудиться от прерывания от TIM4, то это можно сделать так (считаем таймер 4 уже настроенным)

TIM4_IER. UIE=1;

__asm__("wfi");

Если хотите, можете настроить и бит AL. Я не буду это иллюстрировать.

Режим ожидания события STM8L

Этот режим специфичен для STM8L и использует машинную команду WFE (Wait For Event).

Прежде, чем начать знакомство с этим режимом хочу ответить на довольно часто возникающий у новичков вопрос - почему это режим нельзя использовать с STM8S, ведь в описании команды WFE нет ограничения типа микроконтроллера? Все верно, эта команда есть в STM8S, но использовать ее вы не сможете. По той простой причине, что в STM8S нет регистров WFE_CRх, которые необходимы для работы в режиме ожидания события.

В режиме ожидания события разрешенные прерывания обрабатываются как обычно, на основании приоритетов. Однако, после выполнения обработчика прерывания микроконтроллер снова возвращается в режим ожидания.

При наступлении ожидаемых событий микроконтроллер просыпается и выполнение программы просто продолжается со следующей за WFE команды. То есть, для пробуждения из режима ожидания события прерывания для ожидаемых не обрабатываются.

Ожидаемые события задаются с помощью установки соответствующих событию бит в одном из регистров WFE_CRх. Всего таких регистров 4, от WFE_CR1 до WFE_CR4, но не во всех микроконтроллерах реализован полный набор.

События могут быть такими:

  • События связанные с выводами портов. Всего таких событий 8, от EXTI_EV0 до EXTI_EV7. Например, событие EXTI_EV3 происходит при возникновении условия прерывания связанного с битом 3 любого порта. При этом собственно прерывание не обрабатывается, но настройки вывода (уровень, или направление изменения состояния) предназначенные для управления прерываниями влияют и на фиксацию события.
  • События связанные с портами в целом. Такая возможность есть не для всех портов. И задается такое событие не для порта индивидуально, а для пары портов. В паре может произойти событие от любого из портов, то есть, тут используется логическая операция ИЛИ. Есть такие пары портов: B и G, D и H, E и F.
  • События таймеров. Эти события связанные таймерами. Для всех 5 таймеров, но набор событий для них разный. Я сейчас не буду детализировать, что это за события, так как иначе придется слишком глубоко погрузиться в тонкости их работы. Со временем вы все узнаете.
  • Событие связанное с АЦП и компаратором. Как именно формируется событие определяется настройками АЦП или компаратора.
  • События связанные с коммуникационными интерфейсами I2C, UART, SPI. Точно так же, что именно приводит к формированию события определяется настройками соответствующего интерфейса.
  • События связанные с часами реального времени, низкочастотного генератора с внешним резонатором, системы контроля тактовой частоты.
  • События связанные с каналами прямого доступа к памяти (DMA).
  • События связанные с модулем шифрования AES.

Подробный список событий и формат регистров WFE_CRх можно найти в документации.

Отдельно иллюстрировать режим ожидания события не буду. В последнем примере для режима ожидания прерывания просто нужно заменить команду WFI на WFE, а перед ее выполнением нужно настроить не разрешение прерываний, а требуемые события.

Заключение

Мы закончили знакомство с различными видами режимов сна. Их реализация в различных микроконтроллерах во много схожа. Не смотря на терминологические различия и детали.

Использование режимов сна позволяет не только снизить энергопотребление, но улучшить электромагнитную совместимость, что является очень важным. При этом использовать засыпание микроконтроллера в программах, даже написанных на С, довольно легко.

Некоторую сложность представляет временное отключение BOD в AVR. Но я ранее показал, что все не так страшно, как кажется. Действительно сложным является использование использование режимов Low power run и Low power wait в STM8L, причем большей частью из-за необходимости копировать код из ПЗУ в ОЗУ. И я эти режимы, как и предупреждал сразу, даже не рассматривал в статьях (все таки цикл для начинающих).

До новых встреч!