Уменьшение потребления и спящие режимы в МК Xmega

   Иногда возникает необходимость сокращения электропотребления, особенно в тех случаях, когда микропроцессор основное время находится в режиме ожидания, а источник питания – батарейка или аккумулятор с ограниченной возможностью зарядки. В таких случаях целесообразно использовать спящие режимы микропроцессора позволяющие сократить потребление, а которых и пойдет речь в данном уроке для микропроцессора Xmega A.
    Микропроцессор Xmega A имеет возможность существенно уменьшать электропотребление до величины необходимой для внутренней электроники и других приложений требующих батарейного питания. При минимизации потребления следует обратить внимание на то, что не только переход в спящий режим (sleep mode) определяет величину потребления энергии, но и состояние ножек входов-выходов, а также количество включенных периферийных модулей и так далее.
    Сокращение потребления энергии до минимума
    Хотя многие факторы влияют на потребление, есть те, которые влияют больше остальных, перечислим их с советами по применению:
   1) Рабочее (операционное) напряжение. Потребляемая мощность пропорциональна квадрату напряжения питания устройства, поэтому оно должно быть настолько низким насколько это возможно. Уменьшение напряжения питания может сократить максимально возможную частоту системного таймера, тем самым, увеличивая время на выполнение программного кода в активном режиме.
   Совет: Для минимизации потребляемой мощности используйте на столько низкое напряжение питания, на сколько это возможно.
   2) Активный режим работы. В активном режиме работы, т.е. когда не используются спящие режимы (режимы ожидания), потребляемая мощность пропорциональна частоте системного таймера (системных часов). Это означает что, если спящие режимы не используются, устройство должно быть запущено на минимальной системной частоте.
    Совет: Для минимизации потребляемой мощности не в спящих режимах используйте на столько низкую системную частоту, на сколько это возможно.
   3) Спящие режимы (режимы ожидания). Данный способ применяется в большинстве случаях, когда требуется минимизация потребления энергии, но нежелательно уменьшение системной частоты - главным образом, чтобы гарантировать быстроту обработки и быстрый ответ системы (устройства). Для таких применений можно использовать спящие режимы XMega A, для того чтобы перевести устройство в режим низкого потребления, на время пока не происходит процессов. Основной принцип такой – работать так быстро как это возможно и находиться в спящем режиме так долго, сколько это возможно. Работа с максимальным быстродействием уменьшает эффект статической (не зависящей от тактовой частоты) потребляемой мощности, например включение энергонезависимой памяти в активном режиме.
    Мощность потребления и работа периферийных устройств во «сне» зависит от выбранного спящего режима. Таблица 1 показывает характеристики различных режимов ожидания доступных в микропроцессоре XMega A. Приложение может переключиться между спящими режимами во время работы, в зависимости от того какой режим является самым подходящим в данный момент. Наиболее часто используются 3 режима: нерабочий, экономный и отключения.
    - В нерабочем режиме большинство периферийных устройств продолжает работать, только ядро центрального процессора (ЦП) и энергонезависимая память (Flash и EEPROM) отключены. DMA контроллер и Система событий продолжает работать, т.е., например, преобразования АЦП и передача по USART продолжаются даже при отключенном ЦП. Устройство просыпается от любого прерывания.
    - В экономном режиме низкочастотный таймер часов реального времени продолжает работать, в то время как ЦП и большинство других периферийных устройств отключены. Часы реального времени обычно используют для пробуждения устройства через определенные интервалы времени. Поскольку источник системных часов остановлен в данном спящем режиме, то процесс пробуждения занимает больше времени, чем для Нерабочего режима т.к. системные часы должны стабилизироваться перед работой.
    - Отключенный режим – самый глубокий спящий режим. В этом режиме большинство периферийных устройств остановлены. Устройство в данном режиме не может разбудить само себя, т.к. все часы отключены. Пробуждение возможно от внешнего входа – от асинхронного прерывания на входной ножке или двухпроводному интерфейсу. Однако Xmega с модулем резервного аккумулятора и 32-разрядными часами реального времени является в данном случае исключением, т.к. в таком устройстве часы реального времени будут работать в независимости от спящего режима.
   Семейство XMEGA также имеет два дополнительных спящих режима, которые полезны при необходимости быстрого пробуждения:
   - Режим ожидания, фактически являющейся отключенным режимом с работающим источником системных часов.
   - Длительный режим ожидания, фактически являющейся экономным режимом с работающим источником системных часов.
    Эти два спящих режима не дают такое низкое потребление мощности как режим отключения и экономный режим, но полезны в применениях с необходимостью быстрого пробуждения.
    Отметим, что асинхронное прерывания по порту или прерывание по двухпроводному интерфейсу могут пробудить устройство из любого спящего режима.
    Совет: Минимизируйте потребляемую мощность с помощью использования самых допустимо глубоких спящих режимов на такое время, на сколько это возможно и используйте максимальное быстродействие в активном режиме, что бы сократить время пребывания в нем.
   4) Предварительное масштабирование часов
   Хотя рекомендуется использовать ЦП с максимальным быстродействием для сокращения времени работы процессора в активном режиме, есть ситуации, где лучше использовать пониженную тактовую частоту. В таких случаях обычно процессор ожидает в активном или нерабочем режиме с работой в определенные интервалы времени, например, последовательная передача данных. В таких случаях желательно избегать генерирования более высоких частот ЦП и периферийных тактовых частот, чем это необходимо для активных периферийных устройств. Это легко достигается использованием предварительного масштабирования (prescale) часов, которое может быть изменено без сбоев синхросигнале.
    Если предварительно масштабирование выполняется в ЦП и в нескольких периферийных устройствах, то необходимо выполнять предварительное масштабирование с максимально большим общим делителем и как можно раньше в цепочке распределения тактирующих часов, это позволит сократить потребление энергии. Этот принцип показан на рис.1.
Рис.1. Предварительное масштабирование без общего делителя между ЦП и периферийными устройствами и с ним 
    Заметим, что предварительное масштабирование также влияет на тактовую частоту ЦП, поэтому предмасштабирование в активном режиме не всегда полезно, т.к. увеличивает время выполнения программы. 
    Совет: Минимизируйте потребляемую мощность, активно используя предварительное масштабирование, особенно в интервалах ожидания в активном или нерабочем режиме.
    5) Переключение между источниками тактирования
    Важно избегать генерации более высокой системной тактовой частоты, чем это фактически необходимо. В идеальном случае предмасштабирование не используется. Этого можно добиться переключением между источниками тактирования.
    Например, предпочтительнее генерировать системную тактовую частоту 16 МГц при помощи PLL из внутреннего RC-генератора на 2 МГц, чем с использованием RC-генератора на 32 МГц с предмасштабированием на 16 МГЦ. Также хорошим выбором являются внешние источники тактирования, тем более, если они уже имеются в устройстве и не требуют дополнительных финансовых затрат.
    Задержка на пробуждение устройства зависит от источника тактирования системных часов. Одним из способов уменьшить эту задержку заключается в том, чтобы переключатся между источниками тактирования так, чтобы устройство входило в спящий режим и просыпалось при синхронизации от быстроотвечающего источника.
    Совет: Минимизируйте потребляемую мощность, используя переключение между источниками тактирования вместо предмасштабирования при необходимости уменьшения тактовой частоты.
    6) Задержки пробуждения
    Когда устройство просыпается из спящего режима более глубокого, чем нерабочий режим (за исключением двух режимов ожидания), источник системного тактирования должен синхронизироваться до начала работы ЦП. Это вызывает небольшую задержку, связанную с выбором источника тактирования. Если используется внутренний RC-генератор или внешний источник тактирования, то задержка составляет 6 циклов, правда она добавляется к задержке на запуск генератора. Если требуется стабильная частота, то рекомендуемая задержка для запуска керамических резонаторов составляет 1000 циклов, а для кварцевых кристаллов 16000 циклов. Это в дополнении ко времени запуска генератора, которое зависит от резонатора и нагрузочных емкостей.
     Кроме того, существует задержка протяженностью минимум в 13 циклов перед запуском процедуры обработки прерываний (ISR) выполняемой после пробуждения.
    Во время задержки на запуск потребляемая мощность близка к мощности в нерабочем режиме и является неэффективно потраченной мощностью. Поэтому рекомендуется просыпаться как можно реже и выполнять как можно больше необходимых процедур во время каждого пробуждения.
    Совет: Чтобы минимизировать задержку пробуждения и сократить мощность потребления, используйте RC-генератор или внешний источник тактирования и просыпайтесь так редко, на сколько это возможно.
    7) Регистры, уменьшающие мощность потребления
    Большинство периферийных и встроенных модулей могут быть остановлены по отдельности для уменьшения потребления мощности в активном и нерабочем режимах. Также установка соответствующих битов в регистре уменьшения мощности Power Reduction Registers (PRR) отключает устройства от периферийного источника тактирования. Для эффективного уменьшения потребления требуется отключить модули и периферийные устройства (в регистрах управления) до установки соответствующих битов в регистре PRR. Некоторые модули должны быть заново инициализированы после обнуления соответствующего им бита в регистре PRR.
    В отключенном и экономном режимах, модули остановлены независимо от состояния регистра PRR, т.к. источник периферийных часов отключен.
    Совет: Минимизируйте потребляемую мощность, используя регистры PRR для отключения периферийных устройств и модулей, когда они не используются.
    8) Источник часов реального времени
    Одной из основных причин использования неактивного и экономного режимов, а также режима длительного ожидания является то, что в этих режимах часы реального времени (RTC) - активны. RTC обычно используют для пробуждения устройства через заданные интервалы времени.
    Для большинства процессоров семейства XMEGA существует три возможных источника для генерации часов реального времени: внешний кварцевый кристалл частотой 32 кГц, внутренний RC-генератор на 32 кГц и внутренний генератор на 32 кГц ультранизкой мощности Ultra Low Power (ULP). Для любого из вариантов, для уменьшения потребления рекомендуется использовать предварительно масштабируемый синхросигнал частотой 1 кГц. Для внешнего кварцевого генератора 32 кГц также доступен специальный режим пониженной мощности (X32KLPM).
    Использование внешнего кварцевого генератора 32 кГц с включенным режимом X32KLPM, позволяет уменьшить потребление мощности в сравнении с режимом ULP и большую точность, чем при использовании внутреннего RC-генератора. Этот генератор также может быть использован в качестве источника системных часов, если такая низкая частота приемлема для данного применения.
    Таблица 1. Точность и потребления тока при различных источниках генерации часов реального времени
    Для семейства микропроцессоров Xmega с модулем резервного аккумулятора и 32-разрядными часами реального времени в качестве источника тактирования RTC может быть использован только кварцевый генератор на 32 кГц.
    Совет: Минимизируйте потребляемую мощность, используя синхронизацию часов реального времени от частоты 1 кГц полуученую от внешнего кварцевого генератора в режиме пониженной мощности(X32KLPM).
    9) Состояние ножек портов ввода-вывода
    Все цифровые ножки ввода-вывода, для избежание аппаратных конфликтов, по умолчанию установлены в плавающие состояние. Но поскольку у ножек имеются входные буферы, важно гарантировано установить определенный уровень на ножке ввода-вывода для исключения случайного внутреннего переключения или утечки. Возможность утечки в плавающем состоянии ножки ввода-вывода относительно невелика, но существенно увеличивается в спящем режиме, однако ее появление можно минимизировать четкой установкой на ножке высокого или низкого уровня.
    Если ножка соединена с аналоговым источником, цифровой входной буфер для данной ножки должен быть отключен, даже если она не сконфигурирована как ввод. Отключение выполняется для каждого порта в отдельности в регистрах PINnCTRL.
    Совет: Минимизируйте потребляемую мощность, установив на всех неиспользуемых ножках высокий или низкий уровень и отключив входной цифровой буфер ножек соединенных с аналоговыми источниками.
    10) Регистры виртуальных портов
    Использование регистров виртуальных портов позволяет сократить время пребывание процессора в активном режиме. Они позволяют получить доступ к памяти ввода-вывода, в данном цикле выполнения программы, с помощью специальных инструкций, таких как IN, OUT и обработка битов в регистрах DIR, а также IN, OUT и INTFLAGS для четырех Протов ввода-вывода.
    Совет: Минимизируйте потребляемую мощность, используя регистры виртуальных портов для доступа к портам ввода-вывода.
    11) Регистры ввода-вывода общего назначения
    Другим способом сокращения времени пребывания процессора в активном режиме является способ использования регистров ввода-вывода общего назначения GPIO для хранения переменных. Регистры GPIO также имеют доступ с помощью специальных инструкций к памяти ввода-вывода в течение одного цикла.
    Регистры GPIO являются энергозависимыми, поэтому временные переменные периодически должны использоваться для хранения значений находящихся в этих регистрах, иначе быстродействие уменьшится.
    Совет: Используйте регистры ввода-вывода общего назначения для хранения переменных для минимизации потребляемой мощности.
    12) Сторожевой таймер
    Сторожевой таймер – это обычный таймер с отдельным источником тактирования. Если он включен, то потребляет энергию даже в спящем режиме процессора. Сторожевой таймер может быть синхронизирован только от внутреннего источника тактирования ультранизкой мощности (ULP) частотой 32 кГц, предварительно отмасштабированного на 1 кГц.
    Совет: Отключайте сторожевой таймер для минимизации потребляемой мощности.
    13) Детектор уровня напряжения питания
    Целью детектора уровня напряжения питания Brown-Out Detector (BOD) является контроль проседания напряжения питания устройства. Внутренний BOD настоятельно рекомендуют использовать для гарантии того, что устройство работает в установленных руководством пределах.
    Однако, в спящем режиме устройство не работает, или точнее сказать, не выполняет код программы, поэтому логично отдельно конфигурировать BOD для активного, нерабочего и спящих режимов. Включайте BOD только в активном и нерабочем режимах. Полная конфигурация BOD выполняется fuse-битами микропроцессора.
    Для уменьшения потребляемой мощности BOD может быть запущен в тестовом (пробном) режиме с частотой дискретизации 1 кГц с синхронизацией от предмасштабируемого источника тактирования ULP. В тестовом режиме BOD не может определить пропадания напряжения между выборками, поэтому данный режим может быть использован только в применениях с медленными изменениями напряжений питания, например питание от батарейки.
    Совет: Отключайте BOD в спящих режимах для минимизации потребляемой мощности. Желательно использовать тестовый режим только для устройств с медленно меняющимся напряжением питания.
    14) JTAG интерфейс и отладка на процессоре
    JTAG интерфейс используется для программирования и отладки процессора, но не функционирует во время работы завершенного устройства. Если отладка на процессоре On-chip Debugging (OCD) разрешена, то JTAG интерфейс подключен к источнику тактирования и активен в спящем режиме устройства, поэтому при возможности OCD и JTAG интерфейс должны быть отключены.
    Отладка на процессоре может быть отключена fuse-битами, а JTAG интерфейс как fuse-битами, так и программно. Отключение JTAG интерфейса программно гарантирует, что устройство может быть перепрограммировано, т.к. JTAG интерфейс перезапускается при сбросе процессора.
    Альтернативой JTAG интерфейсу может быть интерфейс программирования и отладки (PDI), при его использовании JTAG не нужен и может быть отключен fuse-битами. Интерфейс программирования и отладки также работает во всех спящих режимах.
    Совет: Минимизируйте потребляемую мощность, отключив отладку на процессоре (OCD) и JTAG интерфейс.
    15) Режимы уменьшения мощности Flash и EEPROM
    С контроллером энергонезависимой памяти Non-Volatile Memory (NVM) микропроцессора Xmega возможно использовать режимы уменьшения потребляемой мощности для EEPROM и Flash. В этих режимах EEPROM и неиспользуемые в данный момент разделы Flash (такие как приложения или сектор начальной загрузки) выключены, при активном режиме микропроцессора, так же как и при любом спящем режиме, поэтому эти режимы не влияют на экономию потребляемой мощности в спящих режимах.
    Если ЦП попытается получить доступ к энергонезависимой памяти находящейся в режиме уменьшения потребляемой мощности, то он будет остановлен на время необходимой для пробуждения из нерабочего режима, в течении которого память будет активизирована.
    Обратите внимание на то, что в документации есть опечатка относительно режима сокращения питания Flash и спящего режима. Про обходной путь заключающийся в отключение режима уменьшения потребления для Flash до входа процессора в спящий режим и во включение его при пробуждении. На потребляемую мощность в спящем режиме режим сокращения питания не влияет.
    Совет: Минимизируйте потребляемую мощность, включая режим уменьшения потребляемой мощности для EEPROM и Flash в активном режиме.
    16) Запись в EEPROM
    Если в EEPROM записывается более одного байта, то необходимо использовать страницу буфера EEPROM вместо битовой записи. Так как запись одного бита занимает столько же времени, что и запись всей страницы EEPROM. Если, например, нужно записать два бита, то побитовая запись займет вдвое больше времени, чем это необходимо. Так как потребление увеличивается во время записи в EEPROM, то использовать побитовую запись не целесообразно.
    Совет: Минимизируйте потребляемую мощность, используя постраничную запись в EEPROM, а не побитовую.
    Ну и напоследок, представлю парочку примеров по использованию спящих режимов.
    Пример 1. Достаточно часто встречается применение микропроцессоров, когда большую часть времени устройство находится в ожидании и лишь через заданные промежутки времени выполняет какие то действия, зачастую небольшой длительности. В таких применениях для экономии энергии целесообразно переводить микропроцессор во время периода ожидания в спящий режим. А для пробуждения удобнее всего использовать счетчик реального времени (RTC).
    Задача: Написать программу выдачи раз в 2 секунды на ЦАП (ножка PB3) односторонней спадающей пилы от 0,5 В до 0 В малой длительности (не более 0,2 с) и переходом в спящий Экономный режим (Power-save) после окончания выдачи пилы. Пробуждение осуществляется по прерыванию счетчика реального времени.
    Будем использовать внешний кварцевый генератор с частотой 16 МГц и основной системной частоты 48 МГц и нормальный режим таймера. БСчетчик реального времени настроим на частоту 0,5 Гц при синхронизации от внутреннего 1кГц RC-генератора. Пилу будем формировать простым вычитанием (декрементация) выполняемым в процедуре обработки прерывания по таймеру с частотой 15кГц. Выход из спящего режима происходит по прерыванию счетчика реального времени вызванного переполнением, однако обработка самого прерывания не требуется, поэтому она в программе и не представлена.
#define ENABLE_BIT_DEFINITIONS         // разрешение использования групповых битовых имен 
#include <ioxm128a1.h> // Объявление используемых библиотек
#include <ina90.h> // Объявление используемых библиотек
int Data = 2047; // Объявление переменной для формирования пилы ЦАП
char Flag = 0; // Объявление переменной флага окончания выдачи пилы
void InitDAC(void)
{
DACB.CTRLB = 0x40; // двухканальная работа каналов 0 и 1
DACB.TIMCTRL = 0x50; // минимум 48 CLK между преобразованиями
DACB.CTRLA = 0x0D; // Разрешение работы DACB и каналов 0 и 1
DACB.CH0DATA = 2047; // Выдача на канал 0 в нулевое значение
}
void InitTimers(void)
{
/* Инициализации таймера С0 */
TCC0.CTRLA = 0x05; // N=64;
TCC0.PER = 50-1; // частота таймера 15кГц при системной частоте 48МГц
TCC0.INTCTRLA = 1; // уровень прерываний таймера low
/* Инициализации счетчика реального времени */
CLK.RTCCTRL = CLK_RTCEN_bm+CLK_RTCSRC_RCOSC_gc; // включение и настройка на частоту 1 кГц от внутреннего генератора 32кГц
RTC.PER = 2000; // частота счетчика 0.5 Гц при 1 кГц
RTC.CNT = 0; // обнуление счетчика
RTC.INTCTRL = 1; // уровень прерываний счетчика low
RTC.CTRL = 0x01; // включение счетчика с делителем 1
}
int main(void)
{
__disable_interrupt(); // Отключение прерываний
/* Установка тактирования от 3-х кранной частоты внешнего генератора 3*16=48 */
OSC.XOSCCTRL = 0xCB; // выбор внешнего генератора с временем запуска 16 тыс. CLK и частотой 12-16 МГц
OSC.CTRL = 0x08; // разрешение работы внешнего генератора
while((OSC.STATUS & 0x08) == 0 ) ; // ожидание появления в регистре статуса бита включения синхронизации от внешнего генератора
OSC.PLLCTRL = 0xC3; // настройка блока PLL на синхронизацию от внешнего источника и 3-х кратоное умножение
OSC.CTRL = OSC.CTRL | 0x10; // разрешение работы блока PLL
while((OSC.STATUS & 0x10) == 0 ) ; // ожидание появления в регистре статуса бита включения блока PLL
CCP = 0xD8; // включение защиты от изменения регистров ввода-вывода на время изменения синхронизации
CLK.CTRL = 0x04; // настройка системной синхронизации от блока PLL
OSC.CTRL = OSC.CTRL & 0xFE; // отключение системной синхронизации от внутреннего RC-генератора частотой 2 МГц
InitTimers(); // Запуск процедуры инициализации таймеров
PMIC.CTRL = 1; // приоритет прерываний уровня low
InitDAC(); // Запуск процедуры инициализации ЦАП
__enable_interrupt(); // Разрешение прерываний
while(1) // Основной бесконечный цикл
{
if (Flag) // Если действия ЦАП завершены
{
SLEEP.CTRL = SLEEP_SEN_bm + SLEEP_SMODE_PSAVE_gc; // установка Экономного режима в качестве спящего режима
__sleep(); // переход в спящий режим
SLEEP.CTRL = 0; // выход из спящего режима (по прерыванию счетчика реального времени)
Flag = 0; // обнуление флага окончания работы ЦАП
}
}
}
ISR(TCC0_OVF_vect) // обработка прерываний по переполнению таймера С0
{
if (Data) // Если выдача пилы не окончена
Data--; // то формируется следующая точка пилы
else // иначе
{
Data=2047; // сброс пилы в начальное состояние
Flag = 1; // установка флага завершения работы ЦАП
}
if (DACB.STATUS & 2) // проверка пустоты регистра канала 1
DACB.CH1DATA = Data; // если пуст - запись в ЦАП данных пилы
}
    Пример 2.
    Задача: Написать программу пробуждения микропроцессора и выполнения какого то действия (например выдачи меандра) при подаче на определенную ножку логического ноля, а при отсутствие логического нуля на данной ножке, микропроцессор уходит в отключенные спящий режим (Power-down).
    В качестве основной системной частоты процессора будем использовать внутренний RC-генератор 2 МГц. В качестве входной подтянутой ножки будем использовать ножку PK1 и пробуждать процессор от прерывания по данной ножке. Таймер выполнения основной программы настроим на частоту 1кГц, в рабочем режиме на ножку PK0 выдается меандр частотой 500Гц.
#define ENABLE_BIT_DEFINITIONS         // разрешение использования групповых битовых имен 
#include <ioxm128a1.h> // Объявление используемых библиотек
#include <ina90.h> // Объявление используемых библиотек
void InitTimers(void)
{
TCC0.CTRLA = 0x04; // N=8;
TCC0.PER = 250-1; // частота таймера 1кГц при системной частоте 2МГц
TCC0.INTCTRLA = 1; // уровень прерываний таймера low
}
int main(void)
{
__disable_interrupt(); // Отключение прерываний
PORTK.DIRSET = 0x01; // Установка ножки 0 порта К как выход
PORTK.PIN1CTRL = PORT_OPC_PULLUP_gc;// Установка подятнутого входа ножки 1 порта К
InitTimers(); // Запуск процедуры инициализации таймеров
PMIC.CTRL = 1; // приоритет прерываний уровня low
PORTK.INTCTRL = 1; // установка уровня low прерываний по ножке 1 порта К
PORTK.INT0MASK = 2; // установка маски прерываний для порта К
__enable_interrupt(); // Разрешение прерываний
while(1) // Основной бесконечный цикл
{
if (!(PORTK.IN & 0x02)) // Если на ножке 1 порта К логический ноль, то
{
SLEEP.CTRL = SLEEP_SEN_bm + SLEEP_SMODE_PDOWN_gc; // установка отключенного режима в качестве спящего режима
__sleep(); // переход в спящий режим
SLEEP.CTRL = 0; // выход из спящего режима (по прерыванию ножки 1 порта К)
}
}
}
ISR(TCC0_OVF_vect) // обработка прерываний по переполнению таймера С0
{
PORTK.OUTTGL = 0x01; // переключение уровня сигнала на выходе ножки 0 порта К
}
    Blogger Comment
    Facebook Comment

0 коммент.:

Отправить комментарий