Здравствуйте, уважаемые читатели!
Многие из вас наверняка встречали сообщения на различных форумах, что некоторые “отладочные” платы на ESP32 могут весьма неохотно переключаться в режим программирования по сигналу с компьютера (автоматически), и что для решения проблемы бывает достаточно припаять “лишний” конденсатор к выводу EN микроконтроллера. Признаться, я довольно скептически относился к таким заявлениям, потому что “не видел” физических причин для таких заявлений. И тем не менее, оказалось, что причины эти – они как суслик, их не видно на первый взгляд, но они есть. Давайте разберемся, почему так получается.
Для чего обычно ставят резистор и конденсатор на выводе EN микроконтроллера
Наверное, все знают, что к выводу EN микроконтроллера, который “разрешает” его работу, почти всегда подключена RC-цепочка по схеме на рисунке ниже:
Причем это относится не только к ESP8266 / ESP32, но и к другим микроконтроллерам. Зачем она нужна?
А нужна она в первую очередь для того, чтобы “отложить” запуск процессора до момента, когда только что поданное на плату питание зарядило фильтрующие конденсаторы, а подключенная “периферия” нормально запустилась. При подаче питания конденсатор будет сравнительно медленно заряжаться через резистор, и на время своей зарядки “заблокирует” работу процессора.
Я попытался смоделировать это на цифровом осциллографе:
Верхний (зеленый) канал – это напряжение питания (3.3В), подаваемое через обычный USB-порт и хаб, который не очень “любит” большие токи. Поэтому переходные процессы получились так явно выражены (обведены красным). Нижний канал – сигнал на выводе EN микроконтроллера, и напряжение на этом выводе растет более плавно и медленно – и к тому моменту, когда оно достигнет “разрешающего” запуск уровня, переходные процессы на шине питания в основном завершаются.
Это и есть основное предназначение такого конденсатора. И в этом своем предназначении он, казалось бы, никак не связан с программированием ESP32.
Что необходимо, чтобы перевести ESP32 в режим программирования
На ESP32 режимом работы заведует загрузчик первого уровня, который “сидит” в маленьком ПЗУ SoC и запускает с flash-памяти загрузчик второго этапа. Именно он и определяет текущий режим работы Soc с помощью так называемых strapping pins. Все strapping pins имеют внутренние защелки. При сбросе системы защелки сохраняют значения битов соответствующих strapping pins и сохраняют их до тех пор, пока чип не будет выключен или перезапущен. Состояния защелок strapping pins нельзя изменить после запуска. Это делает состояния strapping pins доступными в течение всей работы ESP32, и выводы освобождаются для использования в качестве обычных выводов ввода-вывода почти сразу после сброса (в течение ~1мс после начала работы процессора – подробности в datasheet-е).
Я уже довольно часто про них писал, но напомню еще раз, что для перевода ESP32 в режим загрузки двоичного дампа прошивки, необходимо подтянуть вывод GPIO0 к “земле” в момент запуска процессора. Это можно сделать с помощью кнопок, если они есть: нажать кнопки EN и GPIO0 (тем самым подтянув их к низкому уровню), затем отпустить EN, удерживая GPIO0, чтобы состояние GPIO0 сохранилось в защелке.
Схема автоматического управления режимом программирования ESP32
На платах ESP32-DevKit и некоторых других, где присутствует USB-порт для программирования, имеется специальная схема для управления сигналами EN и GPIO0. Думаю, все её не раз уже видели:
Эта схема использует сигналы DTR
и RTS
, получаемые с USB-UART моста, для управления режимом работы и сбросом. Формирует эти сигналы утилита esptool.py, с помощью которой, собственно, и программируется микроконтроллер. Подробнее об этом я писал в предыдущей статье.
Если взглянуть на таблицу состояний схемы (справа от схемы), да и на саму схему – то можно увидеть, что она не удовлетворяет условиям, изложенным в предыдущей части – а именно исключается возможность одновременно установить низкий уровень на выводах EN и GPIO0, так как транзисторы взаимно блокируют друг друга. Сделано это, по заявлению espressif, для обеспечения совместимости с различными драйверами виртуальных com-портов – выбирают, так сказать, “меньшую из бед”. Это и есть тот самый суслик.
На скриншоте видно, что сигналы “приходят” на вход схемы одновременно, так как немного меняется уровень на верхнем графике. Но второй сигнал (сброса) его почти полностью блокирует. В момент, когда сигнал “сброса” пропадает – напряжение на выводе GPIO0 резко падает, но с пусть небольшой, но задержкой. И этой задержки может оказаться недостаточно, чтобы защелка GPIO0 обнаружила сигнал перевода в режим программирования.
И вот тут в дело опять вступает этот самый конденсатор и резистор, про которые я упомянул выше. Когда транзистор, управляющий выводом EN, открыт – конденсатор почти мгновенно разряжается. Когда же этот транзистор закрывается, конденсатор опять начинает заряжаться через резистор подтяжки. Если постоянная времени RC-цепи достаточно велика, то напряжение на EN будет опять таки расти медленнее, чем обычно. И этого оказывается вполне достаточно, чтобы к тому моменту второй (заблокированный) транзистор переключился и на GPIO0 уже был установлен необходимый уровень. Этот участок обведен сиреневой линией.
На скриншоте ниже я расширил этот участок для наглядности:
Здесь уже хорошо видно, что напряжение на GPIO0 падает с небольшой, но задержкой, после переключения EN. А напряжение на EN растет медленнее, из-за RC-цепи, и примерно к моменту запуска процессора на GPIO0 уже успевает установиться уверенный “0”. То есть данная схема изначально рассчитана на работу в комплекте с достаточно большим конденсатором на выводе EN. Но сразу установить “слишком большой” конденсатор тоже не очень хорошо – ведь он будет бесконтрольно разряжаться через открытый транзистор.
Соответственно, если емкость данного конденсатора невелика – ни о какой значительной задержке речь идти уже не может! Процессор запустится и защелки защелкнут свое состояние раньше, чем переключится уровень на GPIO0. Это-то, скорее всего, и являлось проблемой на первых ревизиях плат с ESP32. А подпайка дополнительного конденсатора решала проблему. Что и требовалось доказать. Хорошо, что таких “бракованных” плат почти нет в продаже – мне не попадалось ни одной.
А на этом разрешите откланяться, с сами был Александр aka kotyara12.
Пожалуйста, оцените статью:
-= Каталог статей (по разделам) =- -= Архив статей (подряд) =-
Здравствуйте.
Я тоже столкнулся с этой проблемой на платке с ESP32. Получилась некая закономерность.
Исходные данные:
1. Плата ESP-32 38Pin
2. Фирменный провод от какого-то телефона NOKIA USB TYPE-A – micro-USB
Так вот на рабочем компе Dell OptiPlex 3060 любой USB на морде БЕЗ ПРОБЛЕМ заливал прошивку в указанную плату в среде ARDUINO IDE.
Дома комп на старенькой ASUS P5Q (S775). Так вот её наборные USB напрочь отказывались шить эту же плату и этим же кабелем.
Запайка электролита 10 мкФ х 16В между ногами EN и GND полностью решило проблему прошивки платы на домашнем компе. Меньшая ёмкость конденсатора помогает плохо. Ставил от 1 мкФ до 4.7 мкФ. Идеально начинает работать с 10 мкФ (больше не ставил).
Моё предположение такое, что разные реализации контроллеров USB в хабах материнских плат по разному транслируют сигналы DTR и RTS, которые обрабатывают USB-UART-контроллеры типа CH340 и подобные. Имхо.
Скорее всего, проблема именно в контроллере. Даже в справке espressif об этом упоминается