Когда вы нажимаете кнопку Reset или загружаете скетч через USB, на плате происходит гораздо больше, чем кажется. В первые миллисекунды после сброса выполняется строго определённая последовательность аппаратных и программных событий. Разберём её на примере Arduino Uno с микроконтроллером ATmega328P.
1. Причины сброса: откуда всё начинается
Сброс может быть вызван:
- нажатием кнопки Reset (низкий уровень на выводе RESET),
- автосбросом через USB-UART при открытии порта,
- сторожевым таймером (Watchdog),
- просадкой питания (Brown-Out Detection),
- включением питания (Power-On Reset).
Внутри ATmega328P есть схема детектирования сброса, которая формирует внутренний сигнал Reset и удерживает его, пока напряжение и тактирование не стабилизируются.
2. Тактирование: запуск кварца
На Arduino Uno используется внешний кварцевый резонатор 16 МГц. После сброса:
- Микроконтроллер запускает генератор.
- Ждёт стабилизации колебаний.
- Только после этого начинает выполнение кода.
Время ожидания задаётся fuse-битами. Это важно: если стартовать слишком рано, код начнёт выполняться при нестабильной частоте.
3. Fuse-биты: невидимая конфигурация
Fuse-биты — это конфигурационные флаги, записанные во внутреннюю память микроконтроллера. Они определяют:
- источник тактирования,
- включён ли делитель частоты,
- активен ли bootloader,
- включён ли Brown-Out Detection,
- размер области загрузчика.
На Arduino Uno область bootloader занимает верхние 512 байт Flash-памяти. Именно туда передаётся управление после сброса.
4. Вектор сброса и переход к загрузчику
У AVR есть таблица векторов прерываний. Первый адрес — это вектор сброса.
Но если в fuse-битах установлен флаг BOOTRST, процессор после Reset переходит не к адресу 0x0000, а в область загрузчика — в верхнюю часть Flash.
Таким образом последовательность выглядит так:
Reset → запуск генератора → чтение fuse → переход в bootloader.
5. Что делает загрузчик
На Arduino Uno используется загрузчик Optiboot. Его задача:
- Инициализировать UART.
- Подождать короткое время (обычно около 500 мс).
- Проверить, пришла ли команда прошивки.
- Если команда есть — начать программирование Flash.
- Если нет — передать управление пользовательскому коду.
Загрузчик работает по протоколу STK500. Когда вы нажимаете «Загрузить» в IDE, компьютер:
- открывает последовательный порт,
- подаёт импульс DTR,
- через конденсатор формируется кратковременный Reset,
- микроконтроллер перезапускается и попадает в bootloader.
6. Автосброс через USB
На Uno установлен USB-UART преобразователь (ATmega16U2). Когда IDE открывает COM-порт, линия DTR опускается в ноль.
Через конденсатор 100 нФ этот импульс передаётся на RESET ATmega328P.
Это элегантное аппаратное решение позволяет:
- автоматически входить в bootloader,
- не нажимать кнопку вручную.
7. Если прошивки нет
Если в течение окна ожидания загрузчик не получает команду STK500, он выполняет прыжок по адресу 0x0000 — к пользовательской программе.
Этот переход обычно реализован как:
asm("jmp 0x0000");
После этого начинается выполнение уже вашего кода.
8. Что происходит перед вызовом setup()
До того как выполнится setup(), происходит ещё один этап — инициализация среды Arduino.
Компилятор добавляет служебный код, который:
- Инициализирует стек.
- Копирует глобальные переменные из Flash в SRAM.
- Обнуляет секцию BSS.
- Настраивает таймер 0 для millis() и delay().
- Настраивает прерывания.
Только после этого вызывается:
setup();
А затем в бесконечном цикле:
loop();
9. Временная диаграмма первых миллисекунд
Упрощённо процесс выглядит так:
0 мс — Reset
0–2 мс — стабилизация питания
2–5 мс — запуск кварца
5–10 мс — переход в bootloader
10–500 мс — ожидание команды прошивки
≈500 мс — переход к пользовательской программе

Поэтому при перезагрузке Arduino есть характерная пауза перед стартом скетча.
10. Почему это важно понимать
Понимание работы загрузчика помогает:
- убрать задержку старта (записав код без bootloader через ISP),
- реализовать собственный загрузчик,
- диагностировать проблемы прошивки,
- понять причины «мигания» светодиода при старте,
- избежать ложных срабатываний устройств при Reset.
В критических системах иногда bootloader полностью отключают, чтобы старт происходил мгновенно.
11. Можно ли обойти загрузчик
Да. Если прошивать микроконтроллер через ISP-программатор:
- bootloader не используется,
- старт происходит сразу после Reset,
- освобождаются 512 байт Flash,
- исчезает задержка 0.5 секунды.
Это часто применяют в законченных устройствах.
Итог
В первые миллисекунды после сброса Arduino выполняет строго определённую цепочку:
- аппаратная инициализация,
- запуск тактирования,
- анализ fuse-битов,
- выполнение загрузчика,
- проверка запроса на прошивку,
- переход к пользовательскому коду,
- инициализация среды Arduino,
- вызов setup().
Эти процессы занимают доли секунды, но именно они определяют, насколько стабильно, быстро и предсказуемо стартует устройство.