AVR Урок 54. Режимы пониженного энергопотребления. Часть 3



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

 

В функции main() отключим АЦП

 

 

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

 

 

Произведём также предварительную настройку ножек портов, включив неиспользуемые ножки на вход и подтянув к ним резисторы, ножки светодиодов — на выход и установив на них низкий уровень, а ножку INT0 включим на вход и подтянем к ней также резистор

 

 

Настроим внешние прерывания по нисходящему фронту и включим глобальные прерывания

 

 

В бесконечном цикле мы будем мигать светодиодами по очереди, причём после того, как промигают 5 светодиодов, мы подождём 4 секунды, затем, после того как промигают остальные 5 светодиодов, мы также подождём 4 секунды

 

 

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

Чтобы настроить, какой мы именно будем режим использовать, мы будем пользоваться функцией set_sleep_mode. Во входном параметре мы ей передаём режим.

Начнём с режима IDLE.

После того, как потухнет пятый светодиод в бесконечном цикле и пройдёт задержка в 4 секунды, мы перейдём в данный режим

 

 

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

 

 

 

Соберём код в среде MPLAB X и перейдём к программе AVRdude. Попробуем определить контроллер с помощью кнопки чтение сверху и перейдём во вторую вкладку с фьюзами. Считаем фьюзы. Если мы их не трогали после прошлого урока, то нам останется лишь отключить полностью BOD, убрав галку с фьюза BODLEVEL1. После этого все фьюзы BODLEVEL должны быть без галок

 

 

Прошьём фьюзы с помощью кнопки «Программирование«. Тем самым мы полностью выключили BOD

 

 

Вернёмся на первую закладку программы AVRdude «Program«, выберем там файл с нашей новой прошивкой и прошьём контроллер.

Посмотрим результат работы на амперметре.

Пока светодиоды бегут, энергопотребление будет приблизительно 23 милиампера

 

 

Как только светодиоды отмигают, ток потребления составит около 10,5 милиампера, значит светодиод потребляет примерно 12,5 милиампер. Это время задержки в 4 милисекунды. Светодиоды уже не горят, но в режим IDLE контроллер ещё не вошел

 

 

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

 

 

Помимо режимов пониженного энергопотребления контроллер может сэкономить потребление энергии и за счет уменьшения питающего напряжения

 

 

Если убавить напряжение до 1,8 вольт (правда я этого не делал, это проделал тот же подписчик и посетитель ресурса), то можно получить неплохую экономию.

 

 

Тот же самый активный режим без включенных светодиодов (при 5 вольтах, как мы помним, было 10,78 милиампер), только теперь напряжение 1,8 вольт, а тактирование с помощью кварцевого резонатора на 1,684 МГц

 

 

А если поставить кварцевый резонатор на 1 МГц, то получим вот это

 

 

По истечении 4 секунд контроллер уйдёт в режим IDLE и ток потребления составит примерно 4 милиампера, что, в принципе, укладывается в заявленный диапазон

 

 

А вот показания при измерении более точным прибором

 

 

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

Кратковременно нажмём кнопку, управляющую внешними прерываниями. Процесс продолжится с шестого светодиода

 

 

Затем светодиоды домигают до конца и через 4 секунды начнут мигать сначала, затем после потухания 5 светодиода и по истечении ещё 4 секунд контроллер опять войдёт в режим IDLE.

Давайте испытаем ещё какой-нибудь режим, например ADC Noise Reduction

 

set_sleep_mode(SLEEP_MODE_ADC);

 

Процесс пройдёт аналогичным образом, и когда контроллер войдёт в режим, ток составит примерно 1,6 милиампера

 

 

Показания на более точном приборе

 

 

Если мы нажмём кнопку, управляющую внешними прерываниями, то процесс также продолжится с шестого светодиода, то есть с точки входа в режим.

Следующий режим — Standby Mode или режим ожидания

 

set_sleep_mode(SLEEP_MODE_STANDBY);

 

В данном режиме, если собрать код и прошить контроллер, процесс пойдёт аналогичным образом, как и в случае двух предыдущих режимах, а потребление тока составило около 0,5 милиампер, что не совсем вяжется с заявленными (0,2), так как они действуют при напряжении питания 1,8 вольт и частоте тактирования 1 мегагерц, но всё же гораздо меньше чем в предыдущих

 

 

Показания, полученные при помощи более точного прибора

 

 

А вот показания полученные при питании от 1,8 вольт и частоте тактирования 1,684 МГц

 

 

А теперь при 1,8 вольт и частоте тактирования 1 МГц

 

 

Аналогичным образом испытаем и режим Extended Standby Mode или расширенный режим ожидания

 

set_sleep_mode(SLEEP_MODE_EXT_STANDBY);

 

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

Следующий режим — Power-save

 

set_sleep_mode(SLEEP_MODE_PWR_SAVE);

 

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

 

 

А вот те же самые измерения, которые проделал подписчик ресурса при помощи более точного прибора

 

 

При нажатии на кнопку, управляющую ножкой INT0, также процесс начнётся не сначала, а продолжится с 6 светодиода! То есть, спящий режим не сбрасывает указатель в сегменте кода, отлично!

Ну и самый энергосберегающий режим — POWER-DOWN

 

set_sleep_mode(SLEEP_MODE_PWR_DOWN);

 

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

Вот эти показания, полученные при помощи более точного прибора, чем мой

 

 

Следующая задача, стоящая перед нами — вывести контроллер из спящего режима по прерыванию от сторожевого таймера (WDT). Пусть при этом будет большее энергопотребление, но попробовать данный режим мы обязаны, так как не всегда есть возможность вывести из спящего режима контроллер по внешнему прерыванию, ведь что-то должно его сгенерировать, а это что-то я не думаю, что не будет потреблять энергию совсем.

А заодно, мы попробуем поработать со сторожевым таймером с использованием от него прерываний, мы же ещё этот вопрос не изучили, вот и изучим.

Вообще, мы уже знаем, какой бит в каком регистре разрешает прерывания от WDT, осталось как-то это всё ещё применить на практике.

В функции main() отключим, а затем сбросим Watchdog Timer, так как мы после пробуждения будем попадать уже в начало программы

 

 

В бесконечном цикле после первой большой задержки 4 секунды перед засыпанием сбросим бит сторожевого таймера в статусном регистре MCU, перед этим запретив глобальные прерывания

 

 

Включим сторожевой таймер на 4 секунды

 

 

Включим прерывания от WDT

 

А разрешим мы прерывания после включения спящего режима (так почему-то лучше работает)

 

 

Не забудем добавить обработчик прерывания от WDT где-нибудь вверху файла

 

 

То есть если мы попадём в обработчик прерывания от Watchdog, то он сбросится и отключится и, по идее, должен будет зажечься последний светодиод и процесс должен будет продолжиться, но на деле произойдёт сброс, так как если биты WDE и WDIE включены одновременно, глядя на таблицу, показанную в прошлом занятии, у нас не только произойдёт прерывание, но также произойдёт и системный сброс, так как находясь в режиме сна, мы никак не сможем сбросить таймер до наступления прерывания.

Соберём код, прошьём контроллер. У нас после потухания пятого светодиода система по-прежнему уйдёт в спящий режим, правда ток потребления уже будет другим

 

 

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

То есть у нас загорится 10-й светодиод, а остальные начнут мигать по порядку — от шестого до десятого.

 

 

В данном занятии мы, конечно, не смогли проштудировать все аспекты работы режимов пониженного энергопотребления микроконтроллера AVR. Существует также возможность пробуждения от других источников, например от RTC, но в контроллере ATMega328 такого нет, он может работать только от внешнего RTC, в нём вернее есть RTC, только это не Real Time Clock, а Real Time Counter, что не совсем одно и то же. Это независимый асинхронный счётчик, работающий от внешнего резонатора на 32768 Гц. Но я не сомневаюсь, что мы ещё неоднократно вернёмся к данной теме.

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

Всем спасибо за внимание!

 

 

Предыдущая часть Программирование МК AVR Следующий урок

 

Исходный код

 

 

Приобрести программатор USBASP USBISP с адаптером можно здесь USBASP USBISP 3.3 с адаптером

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

AVR Режимы пониженного энергопотребления

3 комментария на “AVR Урок 54. Режимы пониженного энергопотребления. Часть 3
  1. Сергей:

    Ваш курс очень интересен и полезен. Но хотелось бы чтобы осветили еще один вопрос.
    Просьба сделать один урок создания HID приложения на мк со встроенным USB контроллером. (AT90USB162, AT90USB82 или каким-либо другим).

  2. Artem:

    Добрый день. У меня к Вам огромная просьба. Не могли бы Вы выпустить урок по управлению с помощью МК AVR и STM симистором. Например спецэффекты для елочных гирлянд на 220v. Плавное включение ламп, плавное затухание, моргание не затушенных полностью ламп итд. Очень интересная тема. Для Нас, новичков в этом деле.

  3. Александр:

    Здравствуйте. Мне кажется было бы здорово записать урок о переезде AVR в MPLAB X.
    Большое спасибо Вам за уроки!!!

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*