STM Урок 144. Режимы пониженного энергопотребления. SLEEP. Часть 2

 

 

 

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

Теперь можно приступить и к более практической части.

Проект мы сделаем из проекта урока 140 с именем WWDG01 и дадим ему новое имя — SLEEP. Из папки Src удалим всё, кроме файла main.c, а папку Inc удалим полностью со всем содержимым.

Откроем проект в Cube MX и отключим сначала таймер WWDG

 

 

Также отключим и таймер 2

 

 

В RCC отключим внешнее тактирование

 

 

Активируем RTC

 

 

Настроим в нём будильник с тем расчётом, чтобы прерывание от него срабатывало через 10 секунд после его включения

 

 

Включим в RTC прерывания, в том числе и от 17 линии

 

 

Произведём настройки в Clock Configuration

 

 

Сохраним проект, сгенерируем проект для System Workbench, откроем его там, зайдём в настройки, установим уровень оптимизации в 1 и удалим отладочные настройки при их наличии.

Также настроим сборку проекта в 4 потока, как мы делали в уроке 143.

Откроем файл main.c и удалим функцию WWDG_Refresh со всем содержимым.

Процедуру обработки прерываний от таймера HAL_TIM_PeriodElapsedCallback также удалим со всем содержимым.

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

Получится вот так

 

 

Удалим вот эти глобальные переменные

 

uint8_t tim2_count = 0, fl_no_tirst = 0;

 

Пуск таймера 2 тоже уберём из тела функции main()

 

HAL_TIM_Base_Start_IT(&htim2);

 

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

 

 

Попробуем собрать проект.

Если проект нормально собрался, то попробуем его прошить.

После неудачной прошивки перенастроим отладчик в настройках, как мы делали прежде при работе с таким ST-Link.

Теперь всё будет нормально прошиваться и наши диоды будут поочерёдно мигать

 

 

Давайте сейчас измерим ток потребления в нормальном режиме в момент свечения светодиода и в момент, когда светодиод не светится

 

 

 

Мы видим, что светодиод потребляет около 1,1 милиампера.

Теперь попробуем «погрузить» наш контроллер в режим SLEEP.

Для этого сначала, как мы помним, отключить бит прерываний от системного таймера.

Для этого есть специальная функция библиотеки HAL.

 

 

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

 

 

Давайте зайдём внутрь данной функции библиотеки HAL и посмотрим что она делает.

Там мы увидим всего лишь одну строку

 

CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);

 

А это есть ничто иное, как сброс бита, TICKINT.

Затем вызовем следующую функцию

 

 

Данная функция и переведёт микроконтроллер в спящий режим SLEEP.

Первый, передаваемый в данную функцию, параметр — это макрос, который различает тип питания. При переходе в режим SLEEP он не имеет смысла, поэтому можно выбирать любой, а второй параметр — это собственно то, какую именно команду — WFI или WFE мы будем применять для перехода в спящий режим.

Зайдём внутрь функции и посмотрим, что она делает.

Первым делом сбрасывается бит SLEEPDEEP

 

CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));

 

а затем идёт собственно команда WFI

 

if(SLEEPEntry == PWR_SLEEPENTRY_WFI)

{

  /* Request Wait For Interrupt */

  __WFI();

}

 

или WFE, которая, как мы видели выше, предваряется ещё командой SEV

 

else

{

  /* Request Wait For Event */

  __SEV();

  __WFE();

  __WFE();

}

 

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

Вернёмся в main() и продолжим.

Теперь мы смело можем считать, что мы в спящий режим ушли.

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

Для этого также имеется специальная функция библиотеки HAL

 

 

Давайте теперь попробуем собрать код и прошить контроллер.

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

 

 

Это значит то, что мы попали в спящий режим.

Через примерно 6 секунд наш контроллер должен будет вернуться в обычный режим RUN и процесс продлится, то есть у нас загорится второй светодиод

 

 

После того как второй светодиод отгорит 2 секунды, затем будет пауза в 2 секунды, затем по закону цикла загорится 1 светодиод, пройдёт опять пауза в 2 секунды и контроллер опять уйдёт в режим SLEEP.

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

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

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

 

 

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

 

 

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

 

 

И после этого мы опять настроим будильник, но чтобы он срабатывал не через 10, а через 14 секунд, так как нам надо ещё дать время на работу со вторым светодиодом

 

 

Вот теперь, скорее всего, будет всё нормально.

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

Таким образом, в данном уроке мы узнали, какие режимы пониженного энергопотребления существуют у микроконтроллера STM32, в частности у его линейки STM32F1, также один из этих режимов — режим SLEEP — мы изучили подробно и подтвердили наши знания на практике.

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

 

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

 

Исходный код

 

 

Техническая документация:

 

STM32F10xxx-20xxx-21xxx-L1xxxx-Programming-Manual

 

 

Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6

Программатор недорогой можно купить здесь ST-Link V2

 

 

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

 

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

Один комментарий на “STM Урок 144. Режимы пониженного энергопотребления. SLEEP. Часть 2
  1. Марат:

    Здравствуйте. Для дальнейшего снижения энергопотребления необходимо перевести неиспользуемые порты в режим аналог. Таким образом можно достичь потребления порядка микроампер в режиме Stop. А также потребления заявленного в даташите для других режимов работы. Подробная статья об этом есть на Хабре (ссылку на внешний источник убрал).

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

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

*