Главная » Микроконтроллеры » Энергосбережение в микроконтроллерах AVR

Энергосбережение в микроконтроллерах AVR

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

В этой статье постараемся рассмотреть вопрос экономии энергосбережения в микроконтроллерах AVR.

Проведём небольшое исследование. Для начала загрузим в наш микроконтроллер ATmega8 простенькую программу, не выполняющую никакую работу и измерим потребляемый ток. В первом тесте микроконтроллер будет работать на частоте 16 МГц.

int main(void) {
while (1) {
}
return (0);
}
тест энергосбережения atmega8 частота 16МГц
Ток потребления на частоте 16МГц

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

Уменьшение тактовой частоты

Первый и, в принципе, самый простой способ снизить потребление тока нашей системы — это снизить тактовую частоту микроконтроллера. Запустим точно такую же программу, но тактовую частоту снизим до 1МГц.

тест энергосбережения atmega8 частота 1МГц
Ток потребления на частоте 1МГц

После включения питания мультиметр показал значение около 8 мА. Так что можно сказать, что энергопотребление снизилось почти в 2 раза. Все это по довольно простой причине. За счет уменьшения тактовой частоты уменьшается и количество операций, выполняемых за 1 секунду, и чем меньше выполняется операций, тем меньше потребляемый ток.

Программные способы экономии энергии

Микроконтроллеры AVR имеют соответствующие системы, с помощью которых мы можем программно управлять энергопотреблением. Благодаря этому у нас есть возможность отключить часть подсистем или перейти в специальные режимы энергосбережения. Все определения, относящиеся к управлению питанием, содержатся в заголовочных файлах <avr\sleep.h> и <avr\power.h>.

Энергопотребление контролируется с помощью регистра SMCR (Sleep Mode Control Register — регистр управления спящим режимом), а точнее с помощью битов SM0 — SM2. Кроме того, после выбора соответствующего режима его следует запустить установкой бита SE.

Микроконтроллер можно вывести из спящего режима только с помощью прерывания. Если прерывания заблокированы, единственным вариантом пробуждения является подача сигнала RESET.

Список режимов энергосбережения AVR:

  • SLEEP_MODE_IDLE — Самый простой режим. Вся периферия работает нормально, отключается только ядро ЦП (нет сигналов тактирования ЦП и FLASH).
  • SLEEP_MODE_PWR_DOWN — В этом режиме отключается внешний генератор и большинство подсистем процессора. Работают только BOD, Watchdog, TWI, возможны и внешние прерывания (INT). В случае прерывания по фронту сигнал должен быть достаточно длинным.
  • SLEEP_MODE_PWR_SAVE — В этом режиме работают только таймеры. Источник синхронизации, который не используется таймером, также отключается.
  • SLEEP_MODE_ADC — Все подсистемы функционируют нормально, отключены только ядро ЦП, FLASH-память и порты ввода-вывода, что снижает помехи, облегчая измерение АЦП. После входа в этот режим автоматически устанавливается флаг ADSC регистра ADCSRA (запускается измерение АЦП).
  • SLEEP_MODE_STANDBY — При использовании внешнего генератора этот режим отличается от режима SLEEP_MODE_POWER_DOWN только тем, что генератор остается включенным, что ускоряет пробуждение процессора (всего 6 тактов).
  • SLEEP_MODE_EXT_STANDBY — Режим аналогичен SLEEP_MODE_PWR_SAVE, за исключением того, что внешний осциллятор остается включенным, что ускоряет пробуждение процессора.

Первым шагом в настройке является выбор желаемого спящего режима. Для этого используется инструкция set_sleep_mode (режим), где режим определяет выбранный режим сна, показанный в таблице выше.

После выбора подходящего режима процессор можно перевести в спящий режим с помощью инструкции sleep_mode(). Это вызывает разблокировку бита SE, что позволяет войти в спящий режим, а после пробуждения происходит блокировка бита SE.

Блок питания 0...30В/3A
Набор для сборки регулируемого блока питания...
Подробнее

Вместо функции sleep_mode() можно напрямую управлять процессом сна микроконтроллера с помощью инструкций sleep_enable() и sleep_disable(), разрешающих соответственно разблокировку или блокировку возможности перехода в спящий режим, и команды sleep_cpu(), управляющая процессом сна микроконтроллера.

Также следует отметить, что доступные режимы зависят от конкретной модели микроконтроллера.  ATmega8 не поддерживает режим SLEEP_MODE_EXT_STANDBY.

Теперь пришло время протестировать каждый из доступных режимов. Для этого загрузим такой код:

int main(void) {
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_mode();
while (1) {
}
return (0);
}

Протестировав каждый из доступных режимов, мы получили следующие результаты (приблизительные значения):

  • SLEEP_MODE_IDLE — 7 мА
  • SLEEP_MODE_PWR_DOWN — 270 мкА
  • SLEEP_MODE_PWR_SAVE — 250 мкА
  • SLEEP_MODE_ADC — 6 мА
  • SLEEP_MODE_STANDBY — 270 мкА

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

Отключение системы BOD

Некоторые микроконтроллеры имеют возможность отключить систему BOD (Brown-out Detection) которая отслеживает снижение напряжения питания. Отключение BOD выполняется инструкцией sleep_bod_disable(). Однако такое отключение требует определенной последовательности инструкций.

set_sleep_mode(режим);
cli();
sleep_enable();
sleep_bod_disable();
sei();
sleep_cpu();
sleep_disable();

Поскольку чип ATmega8 не поддерживает отключение BOD, мы не проверяли эту функцию.

Исключение процессорных подсистем

Более новые процессоры AVR оснащены регистром PRR (регистр снижения мощности), благодаря которому мы можем отключать / включать определенные подсистемы через инструкции:

  • macrodefinition_enable() — включение
  • macrodefinition_disable() — отключение

В следующем списке приведены макроопределения, соответствующие конкретным подсистемам микроконтроллера:

  • power_all — включает/отключает все подсистемы
  • power_adc — включает/отключает АЦП
  • power_spi — включает/отключает интерфейс SPI
  • power_timerX — включает/выключает таймер номер X
  • power_twi — включает/отключает интерфейс TWI
  • power_usartX — включает/отключает интерфейс USART с номером X

К сожалению, чип ATmega8 не поддерживает этот тип инструкций.

Порты ввода/вывода

Также следует упомянуть, что порты ввода-вывода играют не маловажную роль в вопросе энергосбережения. Лучше установить неиспользуемые порты как входы и через резистор подтянуть их либо к питанию, либо к земле. Иначе у весящих в воздухе  портов «плавает» потенциал, что в свою очередь порождает постоянное переключение их состояния и увеличенное энергопотребление.

Дополнение (19/10/22)

Все тесты выше проводились с микроконтроллером Atmega8, и некоторые из функций данный микроконтроллер не поддерживает. Поэтому на этот раз проведем тесты с микроконтроллером ATmega328, у которого гораздо более широкие возможности.

Базовый тест

Как и в случае с тестированием ATmega8, в этот раз проведем два теста. В память микроконтроллера загрузим такую же программу. Объектом тестирования буде тактовая частота микроконтроллера ATmega328.

int main(void) {
while (1) {
}
return (0);
}
тест энергосбережения atmega328 частота 16МГц
Ток потребления на частоте 16МГц
тест энергосбережения atmega328 частота 1МГц
Ток потребления на частоте 1МГц

В первом случае была установлена тактовая частота 16МГц, величина потребляемого тока составила около 12,56мА. Во втором тесте тактовая частота составила 8МГц, но дополнительно был установлен бит CKDIV8, благодаря чему тактовое значение делится на 8. В итоге тактовая частота составила 1МГц, а потребление тока около 5,9мА.

Программирование энергосбережения

Далее проведем тест для каждого из вариантов из списка режимов энергосбережения AVR приведенного ранее. Все тесты проведем на тактовой частоте 1 МГц.

int main(void) {
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_mode();
while (1) {
}
return (0);
}

Результаты теста:

  • SLEEP_MODE_IDLE — 5,4 мА
  • SLEEP_MODE_PWR_DOWN — 22 мкА
  • SLEEP_MODE_PWR_SAVE — 21 мкА
  • SLEEP_MODE_ADC — 5,5 мА
  • SLEEP_MODE_STANDBY — 119 мкА
  • SLEEP_MODE_EXT_STANDBY — 119 мкА

Отключение системы BOD

Поскольку микроконтроллер ATmega328 поддерживает программное отключение BOD, проверим его и в этом режиме. Как видите, для теста был выбран режим SLEEP_MODE_IDLE. При этом величина потребляемого тока составила примерно 1,6мА.

int main(void) {
set_sleep_mode(SLEEP_MODE_IDLE);
cli();
sleep_enable();
sleep_bod_disable();
sei();
sleep_cpu();
sleep_disable();
while (1) {
}
return (0);
}

Отключение процессорных подсистем

И последнее что протестируем — это функция, отключающая определенные подсистемы процессора. Результаты тестов можно увидеть ниже:

  • power_all — 5,8 мА
  • power_adc — 5,3 мА
  • power_spi — 5,3 мА
  • power_timerX — 5,3 мА (таймер 0)
  • power_twi — 5,4 мА
  • power_usartX — 5,1 мА (usart0)

Код программы для этого теста:

int main(void) {
power_all_disable();
while (1) {
}
return (0);
}

Резюме

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



Инвертор 12 В/ 220 В
Инвертор с чистой синусоидой, может обеспечивать питание переменно...
Подробнее



Добавить комментарий