Перейти к содержанию

Удержание состояния вывода (pin hold)

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

Обновлено Редакция GAW

Удержание вывода (pin hold) — функция ESP32, которая защёлкивает текущее состояние вывода (у ESP32-C3 TRM уточняет — входное и выходное значение). Пока удержание включено, состояние не меняется, что бы ни происходило внутри чипа — даже если перенастроить IO MUX или матрицу GPIO (TRM ESP32 v5.8, разд. 6.7).

Зачем нужно

По TRM удержание позволяет сохранить состояние вывода при двух событиях: сбросе ядра от сторожевого таймера и переходе в глубокий сон. Типичные случаи (наши примеры): реле или силовой ключ должны оставаться включёнными, пока чип спит; вывод питания датчика должен оставаться выключенным, чтобы датчик не тратил ток; вход с внешней подтяжкой не должен повиснуть в воздухе.

Как устроено у ESP32

Удержание каждого вывода — логическое ИЛИ его собственного сигнала и общего сигнала для группы выводов.

ВыводыИндивидуальное удержаниеОбщее для группы
ЦифровыеRTCIO_DIG_PAD_HOLD_REG[n]RTC_CNTL_DG_PAD_FORCE_HOLD, снятие — RTC_CNTL_DG_PAD_FORCE_UNHOLD
RTC-выводыRTC_CNTL_HOLD_FORCE_REG[n], n = 0–17RTC_CNTL_DG_PAD_FORCE_HOLD / UNHOLD

Порядок по TRM: установить бит удержания до выключения питания, а после пробуждения сбросить его. Номера n у RTC-выводов идут от 0 до 17, как у RTC GPIO.

Как устроено у ESP32-C3

У ESP32-C3 (TRM v1.4, разд. 5.9) разделение такое же. Цифровые выводы GPIO6–21 удерживаются битами RTC_CNTL_DIG_PAD_HOLDn в регистре RTC_CNTL_DIG_PAD_HOLD_REG: 1 — удерживать, 0 — снять. RTC-выводы GPIO0–5 управляются битами регистра RTC_CNTL_PAD_HOLD_REG. Подробнее о чипе — на странице ESP32-C3.

Порядок действий (наша рекомендация)

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

Не путать

С функциями выводов в Light-sleep: там отдельный набор полей MCU_* задаёт поведение вывода во время сна (бит SLP_SEL), а удержание просто замораживает текущее состояние.

Частые вопросы

Как сохранить уровень на выводе ESP32 в глубоком сне?

Включить удержание вывода перед засыпанием. У ESP32-C3 для цифровых выводов GPIO6–21 это бит в RTC_CNTL_DIG_PAD_HOLD_REG, для RTC-выводов GPIO0–5 — бит в RTC_CNTL_PAD_HOLD_REG; после пробуждения бит сбрасывают (TRM ESP32-C3 v1.4, разд. 5.9).

Переживает ли удержание сброс?

По TRM ESP32 v5.8 (разд. 6.7) и ESP32-C3 v1.4 (разд. 5.9) — да, при сбросе ядра от сторожевого таймера и при Deep-sleep: удержание для того и предназначено. Про другие виды сброса TRM в этом разделе ничего не говорит.

Почему вывод не меняется, хотя программа пишет в него?

Возможно, на нём осталось удержание: пока оно включено, состояние вывода не меняется ни от записи в GPIO, ни от перенастройки IO MUX (TRM ESP32, разд. 6.7). После пробуждения удержание нужно снять.

Источники

  1. Espressif. ESP32 Technical Reference Manual v5.8 — разд. 6.7: у каждого вывода, включая RTC-выводы, своя функция удержания под управлением регистра RTC; при удержании состояние защёлкивается и не меняется при изменении внутренних сигналов и настроек IO MUX и GPIO; сохраняет состояние при сбросе ядра от сторожевого таймера и в Deep-sleep; удержание = ИЛИ индивидуального и общего сигнала; цифровые выводы — RTCIO_DIG_PAD_HOLD_REG[n] и RTC_CNTL_DG_PAD_FORCE_HOLD/UNHOLD; RTC-выводы — RTC_CNTL_HOLD_FORCE_REG[n], n = 0–17; после пробуждения биты сбрасывают
  2. Espressif. ESP32-C3 Technical Reference Manual v1.4 — разд. 5.9: то же назначение; цифровые выводы GPIO6–21 — биты RTC_CNTL_DIG_PAD_HOLDn в RTC_CNTL_DIG_PAD_HOLD_REG (1 — удерживать, 0 — снять после пробуждения); RTC-выводы GPIO0–5 — биты RTC_CNTL_PAD_HOLD_REG; табл. регистров RTC_CNTL: RTC_CNTL_PAD_HOLD_REG (0x00D0), RTC_CNTL_DIG_PAD_HOLD_REG (0x00D4)

Нашли ошибку?