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

Микроконтроллер ATmega328P

ATmega328P — 8-битный микроконтроллер AVR с 32 КБ флеш-памяти, 2 КБ ОЗУ и частотой до 20 МГц, на нём работают Arduino Uno и Nano. Ниже — характеристики и распиновка с номерами выводов Arduino, фьюзы и загрузчик, периферия, питание, минимальная схема и примеры на C по даташиту Microchip.

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

ATmega328P — микроконтроллер серии megaAVR с 8-битным RISC-ядром AVR, который выпускает Microchip (до 2016 года — Atmel). Он входит в семейство ATmega48/88/168/328: у всех моделей одинаковые корпуса, выводы и периферия, а различаются объём памяти и поддержка загрузчика. Буква P означает технологию picoPower. Именно ATmega328P стоит в Arduino Uno, Nano и Pro Mini, поэтому примеров и библиотек под него больше, чем под любой другой AVR. Цифры ниже взяты из даташита Microchip DS40002061B и исходников ядра Arduino.

Коротко

  • Память: 32 КБ флеш-памяти, 2 КБ ОЗУ, 1 КБ EEPROM; ресурс — 10 000 циклов записи флеш-памяти и 100 000 — EEPROM.
  • Частота и питание: до 20 МГц при 4,5–5,5 В, до 10 МГц при 2,7 В, до 4 МГц при 1,8 В. Arduino Uno работает на 16 МГц от 5 В.
  • Выводы: 23 линии ввода-вывода в корпусах DIP-28, TQFP-32, VQFN-28 и VQFN-32; в 32-выводных корпусах есть ещё два аналоговых входа ADC6 и ADC7.
  • Периферия: два 8-битных и один 16-битный таймер, 6 каналов ШИМ, 10-битный АЦП, USART, SPI, TWI (I²C), компаратор, сторожевой таймер, прерывания по изменению уровня на всех 23 линиях.
  • Фьюзы: с завода — внутренний RC-генератор 8 МГц с делителем на 8, то есть 1 МГц (Low 0x62, High 0xD9, Extended 0xFF); у Arduino Uno — 0xFF, 0xDE, 0xFD и загрузчик Optiboot на 512 байт.
  • Сигнатура 0x1E 0x95 0x0F; у ATmega328 без буквы P — 0x1E 0x95 0x14, у ATmega328PB — 0x1E 0x95 0x16.

Характеристики ATmega328P

ПараметрЗначение
ЯдроAVR (AVRe+), 131 команда, 32 регистра общего назначения, умножение за 2 такта
Производительностьдо 20 MIPS на 20 МГц: большинство команд выполняется за один такт
Флеш-память32 КБ (16K слов), загрузочная секция от 512 байт до 4 КБ
ОЗУ (SRAM)2 КБ, адреса 0x0100–0x08FF
EEPROM1 КБ, запись байта — 3,3 мс
Тактовая частота0–20 МГц, предел зависит от напряжения питания
Питание1,8–5,5 В
Температура−40…+85 °C; исполнения -AN, -MN, -PN — до +105 °C
Линии ввода-вывода23: порт B — 8, порт C — 7, порт D — 8
ТаймерыTimer0 и Timer2 — 8 бит, Timer1 — 16 бит; Timer2 умеет считать от часового кварца
ШИМ6 каналов
АЦП10 бит, 6 входов в DIP-28, 8 — в TQFP-32 и VQFN-32, встроенный датчик температуры
ИнтерфейсыUSART0 (может работать ведущим SPI), SPI, TWI — совместимый с I²C
Прерывания26 векторов, включая сброс
Прошивка и отладкаISP по SPI, debugWIRE, высоковольтное параллельное программирование
КорпусаSPDIP-28, TQFP-32, VQFN-28 (4 × 4 мм), VQFN-32 (5 × 5 мм)

Ядро и система команд у всех классических ATmega общие: регистры, флаги и такты каждой инструкции разобраны в статье «Система команд AVR», сравнение семейств и программаторов — в разделе об AVR.

Семейство ATmega48/88/168/328

Даташит у четырёх моделей один и прямо говорит, что они отличаются только объёмом памяти, поддержкой загрузчика и размером вектора прерываний. Варианты с буквой A и без буквы — обычное исполнение, с буквой P — picoPower.

МодельФлешОЗУEEPROMЗагрузочная секцияВектор прерыванияСигнатура A / P
ATmega48A/PA4 КБ512 байт256 байтнет, SPM работает из любой области1 слово1E 92 05 / 1E 92 0A
ATmega88A/PA8 КБ1 КБ512 байт128–1024 слова1 слово1E 93 0A / 1E 93 0F
ATmega168A/PA16 КБ1 КБ512 байт128–1024 слова2 слова1E 94 06 / 1E 94 0B
ATmega328/P32 КБ2 КБ1 КБ256–2048 слов2 слова1E 95 14 / 1E 95 0F

Вектор в два слова нужен моделям с флеш-памятью больше 8 КБ: в нём помещается команда JMP, которая достаёт до любого адреса. Поэтому прошивку для ATmega88 нельзя просто записать в ATmega328P — таблица векторов устроена иначе, программу пересобирают с другим ключом -mmcu. Предшественник семейства — ATmega8: та же разводка 28-выводного корпуса, но другие регистры, фьюзы и меньше периферии.

ATmega328, ATmega328P и ATmega328PB

ATmega328 и ATmega328P — один кристалл в двух исполнениях: выводы, память, периферия, фьюзы и код у них общие. Отличий три:

  • Отключение BOD во сне. Биты BODS и BODSE в регистре MCUCR есть только у picoPower-моделей с буквой P: детектор пониженного питания можно выключить программно на время сна, и потребление в Power-down упадёт до уровня, как будто BOD выключен фьюзами. После пробуждения он включается сам, а пробуждение удлиняется примерно до 60 мкс.
  • Нормы потребления. Типовые токи одинаковые, а максимальные у ATmega328P ниже: например, 9 мА против 12 мА в активном режиме на 8 МГц при 5 В и 8 мкА против 15 мкА в Power-down со сторожевым таймером.
  • Сигнатура. 0x1E 0x95 0x0F у ATmega328P и 0x1E 0x95 0x14 у ATmega328. Программатор, настроенный на m328p, остановится с ошибкой сигнатуры — частая история с купленными «не теми» кристаллами.

ATmega328PB — уже другой кристалл. Указание по применению AT15007 называет его не прямой заменой, а новым устройством с обратно совместимыми функциями: программа для ATmega328P на нём работает без изменений, а программа для 328PB на ATmega328P — не обязательно.

ATmega328PATmega328PB
КорпусаDIP-28, TQFP-32, VQFN-28, VQFN-32только TQFP-32 и VQFN-32
Линии ввода-вывода2327: добавлен порт E (PE0–PE3)
Выводы 3 и 6 корпуса TQFPвторые GND и VCCPE0 (выход компаратора ACO) и PE1
Выводы 19 и 22только входы АЦП ADC6, ADC7ADC6/PE2 и ADC7/PE3
Таймерыдва 8-битных, один 16-битныйдва 8-битных, три 16-битных (добавлены TC3, TC4)
ШИМ6 каналов10 каналов
USART / SPI / TWIпо одномупо два
Что ещё добавлено—сенсорный контроллер PTC, контроль отказа генератора CFD, модулятор OCM1C2, уникальный серийный номер
Генератор кварца с полным размахоместьубран
Заводская калибровка RC-генератора 8 МГц±10 %±2 %
Температура−40…+85 °C, есть исполнения до +105 °C−40…+105 °C
Сигнатура1E 95 0F1E 95 16

На плате, разведённой под ATmega328P в TQFP-32, выводы 3 и 6 соединены с питанием, а у 328PB это линии порта E — перед заменой разводку стоит проверить. В Arduino IDE ATmega328PB поддерживается, например, сторонним ядром MiniCore.

Распиновка ATmega328P

Разводка 28-выводного корпуса одинакова у ATmega48/88/168/328 и совпадает с ATmega8; у 32-выводных TQFP и VQFN свой порядок выводов. Рядом с выводами в рамках — номера выводов Arduino Uno и Nano, значок ~ отмечает выводы с аппаратным ШИМ.

Распиновка ATmega328P в корпусе DIP-28Вид сверху, ключ вверху. Слева выводы 1–14: PC6/RESET, PD0/RXD, PD1/TXD, PD2/INT0, PD3/INT1/OC2B, PD4/XCK/T0, VCC, GND, PB6/XTAL1, PB7/XTAL2, PD5/T1/OC0B, PD6/AIN0/OC0A, PD7/AIN1, PB0/ICP1/CLKO. Справа сверху вниз выводы 28–15: PC5/ADC5/SCL, PC4/ADC4/SDA, PC3/ADC3, PC2/ADC2, PC1/ADC1, PC0/ADC0, GND, AREF, AVCC, PB5/SCK, PB4/MISO, PB3/MOSI/OC2A, PB2/SS/OC1B, PB1/OC1A. Рамками отмечены номера выводов Arduino: D0–D7 на порту D, D8–D13 на PB0–PB5, A0–A5 на порту C; ШИМ — D3, D5, D6, D9, D10, D11.ATmega328PDIP-28, вид сверху1PC6RESET2PD0RXDD03PD1TXDD14PD2INT0D25PD3INT1/OC2BD3~6PD4XCK/T0D47VCC8GND9PB6XTAL1/TOSC110PB7XTAL2/TOSC211PD5T1/OC0BD5~12PD6AIN0/OC0AD6~13PD7AIN1D714PB0ICP1/CLKOD815PB1OC1AD9~16PB2SS/OC1BD10~17PB3MOSI/OC2AD11~18PB4MISOD1219PB5SCKD1320AVCC21AREF22GND23PC0ADC0A024PC1ADC1A125PC2ADC2A226PC3ADC3A327PC4ADC4/SDAA428PC5ADC5/SCLA5D9~вывод Arduino Uno и Nano; ~ — аппаратный ШИМVCC, GND, AVCC, AREF — питание и опорное напряжение АЦП
Распиновка ATmega328P в корпусе DIP-28 (Arduino Uno). Номера PCINT не показаны: они идут по порядку портов — PB0–PB7 это PCINT0–7, PC0–PC6 — PCINT8–14, PD0–PD7 — PCINT16–23
Распиновка ATmega328P в корпусе TQFP-32Вид сверху, вывод 1 — верхний на левой стороне, нумерация против часовой стрелки. Слева выводы 1–8: PD3, PD4, GND, VCC, GND, VCC, PB6/XTAL1, PB7/XTAL2. Снизу выводы 9–16: PD5, PD6, PD7, PB0, PB1, PB2, PB3, PB4. Справа снизу вверх выводы 17–24: PB5/SCK, AVCC, ADC6, AREF, GND, ADC7, PC0, PC1. Сверху справа налево выводы 25–32: PC2, PC3, PC4/SDA, PC5/SCL, PC6/RESET, PD0/RXD, PD1/TXD, PD2/INT0. ADC6 и ADC7 — только аналоговые входы, их нет в корпусе DIP-28. В Arduino Nano они выведены как A6 и A7.ATmega328PTQFP-32, вид сверху1PD3INT1/OC2BD3~2PD4XCK/T0D43GND4VCC5GND6VCC7PB6XTAL1/TOSC18PB7XTAL2/TOSC29PD5T1/OC0BD5~10PD6AIN0/OC0AD6~11PD7AIN1D712PB0ICP1/CLKOD813PB1OC1AD9~14PB2SS/OC1BD10~15PB3MOSI/OC2AD11~16PB4MISOD1217PB5SCKD1318AVCC19ADC6A620AREF21GND22ADC7A723PC0ADC0A024PC1ADC1A125PC2ADC2A226PC3ADC3A327PC4ADC4/SDAA428PC5ADC5/SCLA529PC6RESET30PD0RXDD031PD1TXDD132PD2INT0D2D9~вывод Arduino Uno и Nano; ~ — аппаратный ШИМVCC, GND, AVCC, AREF — питание; ADC6 и ADC7 — только аналоговые входы
Распиновка ATmega328P в корпусе TQFP-32 (Arduino Nano, Pro Mini). Выводов питания здесь больше: VCC — 4 и 6, GND — 3, 5 и 21; входы ADC6 и ADC7 выведены только в этом корпусе и в VQFN-32

Как выводы связаны с Arduino:

  • D0–D7 — порт D целиком, D0 и D1 — это RXD и TXD, по ним Arduino загружает скетчи и работает Serial.
  • D8–D13 — PB0–PB5. D10–D13 — это SS, MOSI, MISO и SCK интерфейса SPI; MOSI, MISO и SCK выведены ещё и на разъём ICSP, через который кристалл прошивают программатором. Светодиод L на плате Uno подключён к D13.
  • A0–A5 — порт C, входы АЦП ADC0–ADC5. A4 и A5 — это ещё и SDA и SCL шины I²C.
  • A6 и A7 на Nano и Pro Mini — входы ADC6 и ADC7. Это не линии порта: цифрового режима и подтягивающих резисторов у них нет.
  • PB6 и PB7 заняты кварцем. Если кристалл работает от внутреннего RC-генератора, это обычные линии порта B, а для асинхронного Timer2 — выводы часового кварца TOSC1 и TOSC2.
  • PC6 — вывод RESET. Обычной линией порта он становится, только если запрограммировать фьюз RSTDISBL, и тогда прошить кристалл по ISP уже нельзя.

AVCC питает АЦП, линии PC0–PC3 и входы ADC6, ADC7; линии PC4–PC6 питаются от VCC. Даташит требует подключать AVCC к питанию даже без АЦП, а с АЦП — через фильтр; разница напряжений AVCC и VCC — не больше 0,3 В. AREF — вход и выход опорного напряжения АЦП.

Нагрузочная способность. Абсолютный максимум — 40 мА на вывод и 200 мА через выводы VCC и GND. Выходные уровни нормированы при 20 мА и питании 5 В: низкий не выше 0,9 В, высокий не ниже 4,2 В. Кроме того, суммарный ток ограничен группами: втекающий — не больше 100 мА на каждую из групп PC0–PC5 с ADC6 и ADC7; PB0–PB5, PD5–PD7, XTAL1 и XTAL2; PD0–PD4 с RESET; вытекающий — не больше 150 мА на группу PC0–PC5, PD0–PD4, ADC7 и RESET и на группу PB0–PB5, PD5–PD7, ADC6, XTAL1 и XTAL2. Внутренние подтягивающие резисторы — 20–50 кОм, на RESET — 30–60 кОм. Ток светодиода на выводе удобно посчитать калькулятором резистора для светодиода.

Память и загрузчик

Флеш-память — 16K слов по 16 бит, страницы по 64 слова (128 байт), всего 256 страниц. Она делится на секцию приложения и загрузочную секцию в конце памяти. Команда SPM, записывающая флеш-память, работает только из загрузочной секции. Последние 4 КБ (адреса слов 0x3800–0x3FFF) — область NRWW: пока код отсюда переписывает остальную флеш-память, ядро не останавливается. Размер загрузочной секции задают фьюзы BOOTSZ1:0, а фьюз BOOTRST = 0 заставляет ядро после сброса начинать с загрузчика, а не с адреса 0.

BOOTSZ1:0Размер секцииНачало, адрес словаНачало, адрес байтаГде встречается
11256 слов (512 байт)0x3F000x7E00Arduino Uno: Optiboot
10512 слов (1 КБ)0x3E000x7C00—
011024 слова (2 КБ)0x3C000x7800Arduino Nano, старый загрузчик ATmegaBOOT
002048 слов (4 КБ)0x38000x7000заводская настройка

Загрузчик Arduino. На Uno стоит Optiboot версии 4.4 — по описанию авторов, он занимает 512 байт, на 1,5 КБ меньше старых загрузчиков. Optiboot принимает скетч по протоколу STK500 на 115 200 бит/с (в avrdude это программатор arduino). После внешнего сброса он ждёт загрузки около секунды, а после включения питания или сброса сторожевым таймером сразу передаёт управление скетчу. С 2018 года Optiboot ставят и на официальные Nano, но фьюзы Nano оставлены от старого загрузчика: под него отведено 2 КБ, поэтому скетч на Nano может занимать 30 720 байт, а на Uno — 32 256. Запуск загрузчика по команде с компьютера делает автосброс: сигнал DTR преобразователя USB–UART через конденсатор 100 нФ даёт короткий импульс на RESET.

После записи загрузчика Arduino IDE ставит биты защиты 0x0F: команда SPM не может перезаписать загрузочную секцию, так что скетч не испортит загрузчик. Снимаются биты защиты только полным стиранием кристалла.

ОЗУ — 2 КБ по адресам 0x0100–0x08FF, сразу за регистрами и областью ввода-вывода; стек растёт от конца ОЗУ вниз. Карта памяти данных с адресами регистров приведена в статье о системе команд AVR.

EEPROM — 1 КБ, байт записывается за 3,3 мс, ресурс — 100 000 циклов. Фьюз EESAVE = 0 сохраняет содержимое EEPROM при стирании кристалла, например при перепрошивке через ISP.

Тактирование ATmega328P

Источник тактового сигнала выбирают фьюзы CKSEL3:0, задержку запуска — SUT1:0, деление частоты на 8 при старте — CKDIV8.

CKSEL3:0ИсточникЧастотаОсобенности
1111–1000кварц или керамический резонатор, генератор с пониженным размахом0,4–16 МГцнаименьшее потребление; 1111 и 1110 — для 8–16 МГц
0111–0110кварц или резонатор, генератор с полным размахом0,4–20 МГцдля шумной обстановки и для 20 МГц; работает только при 2,7–5,5 В
0101–0100часовой кварц 32,768 кГц32,768 кГцвнутренняя нагрузочная ёмкость на выводах
0011внутренний RC-генератор 128 кГц128 кГцточность не нормирована
0010внутренний RC-генератор 8 МГц7,3–8,1 МГцзаводская настройка
0000внешний тактовый сигнал на XTAL10–20 МГцот генератора или другой микросхемы

Конденсаторы кварца C1 и C2 должны быть одинаковыми. Даташит рекомендует для кварцев 12–22 пФ, AVR042 — 22–33 пФ для обычных высокочастотных кварцев. Точнее — по нагрузочной ёмкости CL из даташита кварца: C = 2·CL − CS, где CS — паразитная ёмкость вывода и дорожки, по AVR042 5–10 пФ. Для кварца с CL = 16 пФ при CS = 10 пФ получаются 22 пФ.

Внутренний RC-генератор после заводской калибровки точен до ±10 % при 3 В и 25 °C, после подстройки регистром OSCCAL — до ±1 %. Для UART этого мало без калибровки: допуск по скорости — около 2 % на каждую сторону. Частоту можно менять и на ходу: регистр CLKPR делит её на 1–256. Запись в него защищена: сначала бит CLKPCE, затем в течение четырёх тактов новое значение. В avr-libc эту последовательность делает функция clock_prescale_set() из <avr/power.h>.

Фьюзы ATmega328P

Фьюзы — три байта конфигурации, которые хранятся отдельно от флеш-памяти и не стираются вместе с ней. Бит, равный 0, считается запрограммированным, равный 1 — нет.

Байт76543210
LowCKDIV8CKOUTSUT1SUT0CKSEL3CKSEL2CKSEL1CKSEL0
HighRSTDISBLDWENSPIENWDTONEESAVEBOOTSZ1BOOTSZ0BOOTRST
Extended—————BODLEVEL2BODLEVEL1BODLEVEL0
  • CKDIV8 — делить частоту на 8 при старте; CKOUT — вывести тактовый сигнал на PB0 (CLKO).
  • RSTDISBL — превратить RESET в линию PC6; DWEN — включить debugWIRE; SPIEN — разрешить программирование по SPI, по ISP его не изменить; WDTON — сторожевой таймер всегда включён; EESAVE — не стирать EEPROM при стирании кристалла.
  • BODLEVEL2:0 — порог детектора пониженного питания (BOD): 111 — выключен, 110 — 1,8 В (1,7–2,0 В), 101 — 2,7 В (2,5–2,9 В), 100 — 4,3 В (4,1–4,5 В).

Заводские значения и фьюзы Arduino

НастройкаLowHighExtendedЧто получится
Заводская0x620xD90xFFRC-генератор 8 МГц / 8 = 1 МГц, загрузочная секция 4 КБ без перехода в неё, BOD выключен
RC-генератор без деления0xE20xD90xFF8 МГц без кварца
Arduino Uno0xFF0xDE0xFDкварц или резонатор 8–16 МГц, загрузчик 512 байт, старт с загрузчика, BOD 2,7 В
Arduino Nano0xFF0xDA0xFDто же, но загрузочная секция 2 КБ
Кварц 16 МГц, без загрузчика0xFF0xD90xFCвся флеш-память под программу, BOD 4,3 В
Кварц 20 МГц0xF70xD90xFCгенератор с полным размахом, BOD 4,3 В

Значения для Uno и Nano взяты из boards.txt ядра Arduino AVR. В старых Makefile загрузчиков Arduino тот же расширенный байт записан как 0x05: у него значимы только три младших бита. Для частоты 16 МГц порог BOD 4,3 В надёжнее 2,7 В: по графику ниже 16 МГц разрешены лишь от 3,78 В, и при просадке питания между 2,7 и 3,78 В кристалл работает вне допустимой области.

Прочитать и записать фьюзы можно avrdude через ISP-программатор:

avrdude -c usbasp -p m328p -U lfuse:r:-:h -U hfuse:r:-:h -U efuse:r:-:h
avrdude -c usbasp -p m328p -B 10 -U lfuse:w:0xFF:m -U hfuse:w:0xDE:m -U efuse:w:0xFD:m

Ключ -B 10 задаёт период SCK 10 мкс, около 100 кГц. По даташиту низкий и высокий уровни SCK должны длиться больше двух тактов ядра, а при частоте от 12 МГц — больше трёх, то есть SCK должна быть ниже четверти тактовой частоты (от 12 МГц — ниже шестой части). Новый кристалл на 1 МГц требует SCK ниже 250 кГц.

Как не «окирпичить» кристалл и как его вернуть

Через ISP нельзя испортить только SPIEN — этот фьюз программатору недоступен. Остальные ошибки бывают обратимыми и не очень:

Что записалиЧто происходитКак вернуть
CKSEL выбрал кварц, а кварца нет — например, «Записать загрузчик» для Uno на макеткеядро не тактируется, программатор не видит кристаллпоставить кварц 8–16 МГц с конденсаторами или подать внешний такт на XTAL1
CKSEL = 0000 — внешний тактовый сигнал, которого нетто жеподать на XTAL1 меандр 1–8 МГц от генератора или вывода ШИМ другой платы, медленным SCK исправить фьюзы
RC-генератор 128 кГц или часовой кварц, да ещё CKDIV8ISP работает, но очень медленноSCK ниже четверти частоты: при 128 кГц — меньше 32 кГц, при 16 кГц — меньше 4 кГц
RSTDISBL = 0вывод 1 стал линией PC6, ISP не входит в режим программированиятолько высоковольтное параллельное программирование: 11,5–12,5 В на RESET
DWEN = 0RESET занят debugWIRE, ISP недоступенотладчиком с поддержкой debugWIRE, например Atmel-ICE, отключить debugWIRE на время сеанса и снять DWEN по ISP
Биты защиты LB1, LB2флеш-память не читается и не пишется, фьюзы заблокированыполное стирание кристалла — оно снимает биты защиты, фьюзы не меняются

Безопасный порядок: сначала прочитать фьюзы, посчитать новые значения и записывать по одному байту, проверяя, что кристалл отвечает. RSTDISBL и DWEN стоит трогать, только когда есть высоковольтный программатор или отладчик.

Периферия ATmega328P

Таймеры и ШИМ

ТаймерРазрядностьВыходы ШИМДелитель и особенностиЧто делает в Arduino
Timer08 битOC0A — PD6 (D6), OC0B — PD5 (D5)1, 8, 64, 256, 1024; внешний вход T0 (PD4)millis(), micros(), delay(): делитель 64, переполнение каждые 1,024 мс; fast PWM 976,6 Гц
Timer116 битOC1A — PB1 (D9), OC1B — PB2 (D10)1, 8, 64, 256, 1024; захват по ICP1 (PB0) или от компаратора, внешний вход T1 (PD5)ШИМ 490,2 Гц (phase correct, 8 бит); библиотека Servo
Timer28 битOC2A — PB3 (D11), OC2B — PD3 (D3)1, 8, 32, 64, 128, 256, 1024; асинхронный режим от кварца 32,768 кГцШИМ 490,2 Гц; функция tone()

Частота ШИМ зависит от режима: в fast PWM счётчик идёт только вверх, в phase correct — вверх и вниз, поэтому частота вдвое ниже, зато импульсы симметричны относительно середины периода.

ffast PWM=fclkN (1+TOP),fphase correct=fclk2N⋅TOPf_\text{fast PWM} = \frac{f_\text{clk}}{N\,(1 + \text{TOP})}, \qquad f_\text{phase correct} = \frac{f_\text{clk}}{2N \cdot \text{TOP}}

Здесь N — делитель, TOP — верхнее значение счётчика: 0xFF у 8-битного режима, у Timer1 — 0x1FF, 0x3FF или любое число в ICR1 или OCR1A. Отсюда частоты Arduino: 16 МГц / (64 · 256) = 976,6 Гц на D5 и D6 и 16 МГц / (2 · 64 · 255) = 490,2 Гц на остальных выводах ШИМ. Отсюда же ограничения ядра: перенастройка Timer0 ломает millis() и delay(), библиотека Servo забирает Timer1 и отключает ШИМ на D9 и D10, а tone() занимает Timer2 и мешает ШИМ на D3 и D11.

Timer2 может считать от часового кварца 32,768 кГц на выводах TOSC1 и TOSC2 и будить кристалл из режима Power-save — это часы реального времени почти без затрат энергии. Но выводы TOSC совпадают с XTAL1 и XTAL2, поэтому системная частота в таком режиме — только от внутреннего RC-генератора, и она должна быть хотя бы в четыре раза выше частоты кварца.

USART0, SPI и TWI

  • USART0 — выводы RXD (PD0) и TXD (PD1), кадры с 5–9 битами данных, асинхронный и синхронный режим (такт XCK на PD4), а также режим ведущего SPI. Скорость задаёт 12-битный регистр UBRR0: на 16 МГц 9600 бит/с получаются при UBRR0 = 103 с ошибкой +0,2 %, наибольшая скорость — 1 Мбит/с, а с удвоением U2X0 — 2 Мбит/с. Подобрать UBRR и оценить ошибку для любой частоты поможет калькулятор скорости UART, формат кадра, допуски и приём по прерыванию разобраны в статье про UART, а подключение к COM-порту — в статье про RS-232.
  • SPI — PB2–PB5 (SS, MOSI, MISO, SCK), ведущий до fclk/2, то есть 8 МГц на 16 МГц. Регистры SPCR, SPSR и SPDR, делитель частоты, ловушка с выводом SS и пример обмена с флеш-памятью — в разделе «SPI в микроконтроллерах AVR на примере ATmega328P».
  • TWI — модуль I²C на PC4 (SDA) и PC5 (SCL), частота SCL до 400 кГц. Регистры TWBR, TWCR, TWSR, расчёт подтягивающих резисторов и восстановление зависшей шины — в статье про I²C.

АЦП

10-битный АЦП последовательного приближения с мультиплексором на 8 внешних входов (6 в DIP-28), внутренний датчик температуры и два служебных канала: опорный источник 1,1 В и общий провод. Результат преобразования:

ADC=Uвх⋅1024Uоп\text{ADC} = \frac{U_\text{вх} \cdot 1024}{U_\text{оп}}
REFS1:0Опорное напряжениеЗамечания
00внешнее на AREFвнутренние источники отключены
01AVCCна AREF — конденсатор на общий провод
10—зарезервировано
11внутренний источник 1,1 Вот 1,0 до 1,2 В по даташиту, на AREF — конденсатор

Полные 10 бит АЦП даёт при тактовой частоте 50–200 кГц. Её получают из системной частоты делителем ADPS2:0 на 2–128: на 16 МГц подходит только деление на 128, это 125 кГц, и так делает Arduino. Преобразование занимает 13 тактов АЦП, первое после включения — 25, значит, на 125 кГц одно измерение длится 104 мкс, а предельная скорость при полной точности — около 15 тысяч измерений в секунду. Абсолютная погрешность по даташиту — ±2 младших разряда.

Практические правила из даташита:

  • источник сигнала должен иметь выходное сопротивление не больше 10 кОм — иначе конденсатор выборки не успевает зарядиться; делитель на входе удобно рассчитать калькулятором делителя напряжения;
  • если на AREF подано внешнее напряжение, внутренние опоры выбирать нельзя: в Arduino analogReference(EXTERNAL) нужно вызвать до первого analogRead();
  • цифровые входные буферы аналоговых выводов лучше отключить регистром DIDR0 — сигнал около половины питания на цифровом входе увеличивает потребление;
  • для точных измерений есть режим сна ADC Noise Reduction: ядро и ввод-вывод останавливаются на время преобразования.

Канал ADC8 подключает встроенный датчик температуры: напряжение на нём растёт примерно на 1 мВ/°C — типично 314 мВ при +25 °C, — а точность без калибровки ±10 °C. Измеряют его с внутренней опорой 1,1 В.

Запускать преобразования может не только программа: в режиме автозапуска их начинают компаратор, прерывание INT0, совпадение или переполнение Timer0, Timer1 и захват Timer1 — так АЦП работает с ровным шагом без участия ядра.

Компаратор, внешние прерывания, PCINT и сторожевой таймер

  • Аналоговый компаратор сравнивает AIN0 (PD6, D6) и AIN1 (PD7, D7). Вместо AIN0 можно подать внутренний источник 1,1 В, вместо AIN1 — любой вход мультиплексора АЦП, если сам АЦП выключен. Выход компаратора вызывает прерывание или запускает захват Timer1.
  • INT0 и INT1 — PD2 (D2) и PD3 (D3): прерывание по низкому уровню, любому изменению, спаду или фронту.
  • PCINT — прерывание по любому изменению уровня на каждом из 23 выводов. Векторов всего три — по одному на порт B, C и D, — поэтому обработчик сам выясняет, какой вывод изменился. Маски задают регистры PCMSK0–PCMSK2.
  • Сторожевой таймер считает импульсы отдельного генератора 128 кГц; таймаут — от 16 мс до 8 с. Он умеет сбрасывать кристалл, вызывать прерывание или сначала прерывание, затем сброс — тогда он годится и как будильник для выхода из сна.

Питание и потребление

Напряжение и допустимая частота

Чем ниже напряжение питания, тем медленнее переключаются транзисторы, поэтому допустимая тактовая частота зависит от VCC. По даташиту граница проходит через 4 МГц при 1,8 В, 10 МГц при 2,7 В и 20 МГц при 4,5 В, а между этими точками она линейна.

Максимальная тактовая частота ATmega328P в зависимости от напряжения питанияОбласть допустимой работы ATmega328P: 4 МГц при 1,8 В, дальше граница растёт линейно до 10 МГц при 2,7 В и до 20 МГц при 4,5 В, от 4,5 до 5,5 В — 20 МГц. При 3,3 В допустимо до 13,3 МГц, частота 16 МГц разрешена начиная с 3,78 В. Arduino Uno работает на 16 МГц при 5 В — внутри области.0481216201,82,73,34,55,05,5МГцнапряжение питания VCC, Вдопустимая область3,3 В: до 13,3 МГц16 МГц — от 3,78 ВArduino Uno4 МГц при 1,8 В10 МГц при 2,7 В20 МГц при 4,5 В
Наибольшая тактовая частота ATmega328P в зависимости от напряжения питания по рис. 29-1 даташита. Точки 3,3 В и 16 МГц получены линейной интерполяцией

Для напряжения между 2,7 и 4,5 В:

fmax=10 МГц+(Uпит−2,7 В)⋅10 МГц1,8 Вf_\text{max} = 10\ \text{МГц} + (U_\text{пит} - 2{,}7\ \text{В}) \cdot \frac{10\ \text{МГц}}{1{,}8\ \text{В}}
ПитаниеНаибольшая частотаТипичная конфигурация
1,8 В4 МГцбатарейные устройства, RC-генератор 1 МГц
2,7 В10 МГц—
3,3 В13,3 МГцкварц 8 МГц, Arduino Pro Mini на 3,3 В
3,78 В16 МГцнижняя граница для 16 МГц
4,5–5,5 В20 МГцкварц 16 МГц, Arduino Uno и Nano

Режимы сна и потребление

Режим выбирают биты SM2:0 регистра SMCR, бит SE разрешает сон, а засыпает ядро по команде SLEEP. Ниже — типовые токи из таблицы 29-8 даташита при 25 °C. Максимальные значения выше: например, в Power-down без сторожевого таймера — до 2 мкА, а не 0,1 мкА.

РежимЧто продолжает работатьЧем разбудитьТок ATmega328P
Активныйвсё—0,3 мА (1 МГц, 2 В); 1,7 мА (4 МГц, 3 В); 5,2 мА (8 МГц, 5 В)
Idleвсё, кроме ядра и флеш-памятилюбое прерывание0,04 мА (1 МГц, 2 В); 0,3 мА (4 МГц, 3 В); 1,2 мА (8 МГц, 5 В)
ADC Noise ReductionАЦП, внешние прерывания, TWI, Timer2 в асинхронном режиме, сторожевой таймерокончание преобразования, сброс, сторожевой таймер, BOD, низкий уровень на INT0 или INT1, PCINT, совпадение адреса TWI, Timer2, готовность EEPROM—
Power-downтолько асинхронные модулисброс, сторожевой таймер, BOD, совпадение адреса TWI, низкий уровень на INT0 или INT1, PCINT0,1 мкА без сторожевого таймера, 4,2 мкА с ним (3 В)
Power-saveто же и Timer2 от часового кварцато же и Timer20,8 мкА при 1,8 В, 0,9 мкА при 3 В с кварцем 32 кГц
Standby, Extended Standbyкак Power-down и Power-save, но кварцевый генератор не останавливаетсято же—

Из Standby и Extended Standby кристалл просыпается за 6 тактов — генератор не нужно запускать заново. Чтобы реально получить микроамперы, перед сном выключают всё лишнее: АЦП (ADEN = 0), компаратор, BOD (у ATmega328P — программно на время сна) и debugWIRE, а свободные выводы не оставляют висеть в воздухе. Время работы от батареи при таком потреблении посчитает калькулятор времени работы батареи.

Детектор пониженного питания BOD держит кристалл в сбросе, пока напряжение ниже порога, заданного фьюзами BODLEVEL. Порог выбирают по частоте: на 16 МГц — 4,3 В, на 8 МГц при 3,3 В подходит 2,7 В — по графику при 2,7 В допустимы 10 МГц.

Минимальная схема: Arduino на макетке

ATmega328P работает и без платы Arduino. Ниже — схема, повторяющая Uno по сути: тот же кварц 16 МГц, те же фьюзы и загрузчик, а для прошивки — разъём ISP и преобразователь USB–UART.

Минимальная схема включения ATmega328P: кварц, сброс, питание, ISP и USB–UARTATmega328P в корпусе DIP-28. Кварц Q1 16 МГц между XTAL1 (вывод 9) и XTAL2 (вывод 10), от каждого вывода конденсатор 22 пФ на общий провод. RESET (вывод 1) подтянут к +5 В резистором R1 10 кОм и соединён с контактом RST разъёма ISP и через конденсатор C6 100 нФ — с выходом DTR преобразователя USB–UART. VCC (вывод 7) — к +5 В с конденсатором C1 100 нФ; AVCC (вывод 20) — к +5 В через дроссель L1 10 мкГн с конденсатором C2 100 нФ; AREF (вывод 21) — конденсатор C3 100 нФ на общий провод; выводы 8 и 22 — общий провод. SCK, MISO и MOSI (выводы 19, 18, 17) — к разъёму ISP. RXD (вывод 2) — к TXD преобразователя, TXD (вывод 3) — к его RXD.ATmega328PDIP-287VCC20AVCC8GND22GND21AREF9XTAL110XTAL21RESET19SCK18MISO17MOSI2RXD3TXDQ116 МГцC422 пФC522 пФ+5 ВC1100 нФ+5 ВL110 мкГнC2100 нФC3100 нФ+5 ВR110 кОмC6100 нФISPRSTSCKMISOMOSIVCCGND+5 ВUSB–UARTTXDRXDGNDDTRVCC+5 В
Минимальная схема ATmega328P в корпусе DIP-28: кварц, сброс, развязка питания, разъём ISP для записи загрузчика и USB–UART для загрузки скетчей. Номера выводов — для DIP-28
  • Кварц 16 МГц с конденсаторами 22 пФ — как можно ближе к выводам 9 и 10. Фьюзы — как у Uno: Low 0xFF.
  • Сброс: R1 10 кОм на +5 В. AVR042 советует подтяжку не меньше 10 кОм, если нужен debugWIRE. Конденсатор от RESET на общий провод в этом случае не ставят, а на время отладки отключают и C6 автосброса: даташит требует, чтобы к RESET не было подключено ни одного конденсатора.
  • Развязка: по 100 нФ у каждой пары выводов питания — C1 у выводов 7 и 8, C2 у 20 и 22, — и ещё танталовый или керамический конденсатор на входе питания. AVR042 подчёркивает: конденсатор должен стоять у самых выводов, иначе петля тока замыкается через полигоны питания и помеха расходится по всей плате.
  • AVCC подключён всегда. Если нужен точный АЦП — через дроссель 10 мкГн с конденсатором 100 нФ, как на схеме из раздела даташита о шумах АЦП; частоту среза такого LC-фильтра можно оценить калькулятором LC-контура. Без АЦП достаточно перемычки к VCC и конденсатора C2.
  • AREF — конденсатор 100 нФ на общий провод, если опора — AVCC или внутренний источник 1,1 В.
  • ISP — шестиконтактный разъём: 1 — MISO, 2 — VCC, 3 — SCK, 4 — MOSI, 5 — RESET, 6 — GND. Через него программатор записывает фьюзы и загрузчик.
  • USB–UART — модуль на CH340, CP2102 или FT232: TXD модуля — к RXD (вывод 2), RXD модуля — к TXD (вывод 3), DTR — через C6 100 нФ к RESET, это и есть автосброс для загрузчика. Если плата питается от модуля, его VCC подключают к +5 В.

Порядок запуска: выбрать в Arduino IDE плату Arduino Uno и программатор, нажать «Записать загрузчик» — IDE запишет фьюзы 0xFF, 0xDE, 0xFD и Optiboot. После этого программатор можно отключить и загружать скетчи через USB–UART кнопкой «Загрузить». Если загрузчик не нужен, программы записывают сразу через ISP, а USB–UART остаётся только для обмена данными.

Схема включения ATmega8 в том же корпусе отличается только фьюзами, а у 64-выводного ATmega128 выводы питания и ISP расположены иначе.

Пример на C: USART, АЦП и ШИМ на Timer1

Программа для avr-gcc и avr-libc без библиотек Arduino. Потенциометр на A0 задаёт длительность импульса сервопривода на D9 (OC1A), а измерения выводятся через USART0 на 9600 бит/с. Работает на Uno, Nano и схеме выше; частота — 16 МГц.

Регистр скорости для 9600 бит/с при U2X0 = 0:

UBRR0=fclk16⋅BAUD−1=16 000 00016⋅9600−1≈103,2  ⇒  103\text{UBRR0} = \frac{f_\text{clk}}{16 \cdot \text{BAUD}} - 1 = \frac{16\,000\,000}{16 \cdot 9600} - 1 \approx 103{,}2 \;\Rightarrow\; 103

Реальная скорость — 16 000 000 / (16 · 104) = 9615 бит/с, на 0,2 % выше номинала. Тот же расчёт при компиляции делает <util/setbaud.h>: он сам включает U2X0, если без него ошибка превышает 2 %.

Таймер настроен в режим 14 — fast PWM с верхним значением в ICR1. При делителе 8 один шаг счётчика длится 0,5 мкс, ICR1 = 39 999 даёт период 20 мс (50 Гц), а импульс длится (OCR1A + 1) · 0,5 мкс: 1–2 мс для OCR1A от 1999 до 3999.

/* ATmega328P at 16 MHz (Arduino Uno, Nano or the breadboard circuit above).
 * A potentiometer on ADC0 (A0) sets the pulse of a hobby servo on OC1A (PB1, D9);
 * the readings go out of USART0 at 9600 baud, 8N1. */
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#define BAUD 9600

#include <avr/io.h>
#include <stdint.h>
#include <stdio.h>
#include <util/delay.h>
#include <util/setbaud.h>

static int uart_putchar(char c, FILE *stream)
{
  if (c == '\n') uart_putchar('\r', stream);
  while (!(UCSR0A & _BV(UDRE0))) {}      /* wait for an empty transmit buffer */
  UDR0 = c;
  return 0;
}

static FILE uart_out = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

static void uart_init(void)
{
  UBRR0H = UBRRH_VALUE;                  /* UBRR0 = 103 at 16 MHz and 9600 baud */
  UBRR0L = UBRRL_VALUE;
#if USE_2X
  UCSR0A |= _BV(U2X0);
#else
  UCSR0A &= ~_BV(U2X0);
#endif
  UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);    /* 8 data bits, no parity, 1 stop bit */
  UCSR0B = _BV(TXEN0);                   /* transmitter only */
  stdout = &uart_out;
}

static void servo_init(void)
{
  DDRB |= _BV(PB1);                      /* OC1A (D9) is an output */
  ICR1 = 39999;                          /* TOP: 16 MHz / 8 / 40000 = 50 Hz */
  OCR1A = 2999;                          /* (2999 + 1) x 0.5 us = 1.5 ms */
  TCCR1A = _BV(COM1A1) | _BV(WGM11);     /* clear OC1A on match, set at BOTTOM */
  TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);  /* mode 14, TOP = ICR1, clk/8 */
}

static uint16_t adc_read(uint8_t channel)
{
  ADMUX = _BV(REFS0) | (channel & 0x07); /* reference AVCC, inputs ADC0-ADC7 */
  ADCSRA |= _BV(ADSC);
  while (ADCSRA & _BV(ADSC)) {}          /* 13 ADC clocks = 104 us at 125 kHz */
  return ADC;
}

int main(void)
{
  uart_init();
  servo_init();
  ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);  /* 16 MHz / 128 = 125 kHz */
  DIDR0 = _BV(ADC0D);                    /* no digital input buffer on ADC0 */

  for (;;) {
    uint16_t raw = adc_read(0);                                      /* 0...1023 */
    uint16_t pulse = 1000 + (uint16_t)((uint32_t)raw * 1000 / 1023); /* 1000...2000 us */
    OCR1A = pulse * 2 - 1;               /* one timer tick is 0.5 us */
    printf("ADC0 = %u, pulse = %u us\n", raw, pulse);
    _delay_ms(100);
  }
}

В режиме 14 новое значение OCR1A вступает в силу в начале следующего периода, поэтому менять его на ходу можно без «рваных» импульсов. Диапазон 1–2 мс — типичный для сервоприводов; библиотека Servo в Arduino по умолчанию выдаёт импульсы от 544 до 2400 мкс с периодом 20 мс, крайние значения конкретного привода стоит проверить осторожно.

Сборка и прошивка — через загрузчик Arduino или ISP-программатор:

avr-gcc -mmcu=atmega328p -Os -o servo.elf servo.c
avr-objcopy -O ihex -R .eeprom servo.elf servo.hex
avrdude -c arduino -p m328p -P COM3 -b 115200 -U flash:w:servo.hex:i
avrdude -c usbasp -p m328p -U flash:w:servo.hex:i

Порт COM3 — пример для Windows, в Linux плата Uno обычно видна как /dev/ttyACM0. Третья строка загружает программу через Optiboot, четвёртая — через USBasp, и в этом случае загрузчик будет стёрт.

Типичные ошибки и отладка

СимптомВероятная причинаЧто сделать
Новый кристалл не отвечает программатору или отвечает через разс завода частота 1 МГц, а SCK программатора выше 250 кГцзамедлить SCK: -B 10 в avrdude или перемычка медленного режима на программаторе
avrdude сообщает сигнатуру 0x1E9514 или 0x1E9516это ATmega328 без P или ATmega328PBуказать -p m328 или -p m328pb, в Arduino IDE — ядро с поддержкой этих кристаллов, например MiniCore
delay() тянется в 16 раз дольше, Serial выдаёт мусорфьюзы оставили 1 МГц (при 8 МГц — ошибка вдвое), а программа собрана для 16 МГцзаписать фьюзы под кварц или собрать программу с верным F_CPU
stk500_getsync(): not in sync при загрузке через USB–UARTнет загрузчика, нет цепи DTR — 100 нФ — RESET, перепутаны TXD и RXD или не та скоростьзаписать загрузчик по ISP, проверить автосброс; старый загрузчик Nano работает на 57 600 бит/с
После «Записать загрузчик» кристалл на макетке перестал отвечатьфьюзы Uno выбрали кварц, а его нетпоставить кварц 16 МГц с конденсаторами 22 пФ
Случайные перезапуски при включении нагрузкинет конденсаторов 100 нФ у выводов питания, BOD срабатывает при просадкеразвязка у выводов, достаточный ток источника, порог BOD по рабочему напряжению
После срабатывания сторожевого таймера кристалл перезапускается бесконечнопосле такого сброса таймер остаётся включённым с таймаутом 16 мсв самом начале программы сбросить MCUSR и выключить таймер (wdt_disable()); на Nano заменить старый загрузчик на Optiboot
АЦП показывает ерунду, линии PC0–PC3 не работаютне подключён AVCCAVCC всегда к питанию, с АЦП — через фильтр
На AREF внешнее напряжение, а показания странныевыбрана внутренняя опора или AVCC, и источник на AREF замкнут на неёпри внешней опоре — только REFS1:0 = 00
Пропал ШИМ на D9 и D10 или на D3 и D11библиотека Servo заняла Timer1, tone() — Timer2перенести ШИМ на другие выводы
Сбоят millis() и delay()программа перенастроила Timer0для своих задач брать Timer1 или Timer2

Причина бесконечных перезапусков на Nano видна в исходниках Arduino: Makefile старого загрузчика ATmegaBOOT собирает вариант для ATmega328P без опции WATCHDOG_MODS, которая выключает сторожевой таймер. Даташит предупреждает, что после сброса от таймера его бит WDE остаётся установленным, пока не сброшен флаг WDRF, — и загрузчик, ожидающий скетч, сбрасывается раньше, чем дождётся его. Optiboot после такого сброса сразу запускает скетч, и программа успевает выключить таймер сама.

Для 8-килобайтного предшественника с другой периферией и фьюзами — статья об ATmega8, для старшего кристалла с 128 КБ флеш-памяти и JTAG — об ATmega128. Подключение дисплея к ATmega328P разобрано в статье про HD44780, а другие семейства и программаторы — в разделе об AVR.

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

Чем ATmega328P отличается от ATmega328 и ATmega328PB?

ATmega328 и ATmega328P описаны в одном даташите и совпадают по выводам, памяти, периферии и фьюзам. Буква P означает picoPower: у ATmega328P можно программно отключать детектор пониженного питания во сне, и максимальные токи в таблицах у него ниже. Сигнатуры разные — 0x1E 0x95 0x14 и 0x1E 0x95 0x0F, поэтому avrdude с ключом m328p откажется шить ATmega328. ATmega328PB — новый кристалл: четыре линии порта E, по два USART, SPI и TWI, три 16-битных таймера, 10 каналов ШИМ, сенсорный контроллер PTC, сигнатура 0x1E 0x95 0x16 и только 32-выводные корпуса. Программы для ATmega328P на нём работают, обратная совместимость не гарантируется.

Какие фьюзы у Arduino Uno и что они означают?

Low = 0xFF, High = 0xDE, Extended = 0xFD. Младший байт выбирает внешний кварц или резонатор 8–16 МГц с самой долгой задержкой запуска и без деления частоты на 8. Старший байт оставляет программирование по SPI, отводит под загрузчик 256 слов (512 байт) и заставляет ядро после сброса стартовать с загрузчика. Расширенный включает детектор пониженного питания на 2,7 В. У Arduino Nano High = 0xDA: под загрузчик отведено 2 КБ, поэтому скетч может занимать 30 720 байт, а не 32 256.

Можно ли запустить ATmega328P на 16 МГц от 3,3 В?

По даташиту нет. Допустимая частота растёт линейно от 10 МГц при 2,7 В до 20 МГц при 4,5 В, поэтому при 3,3 В гарантированы около 13,3 МГц, а 16 МГц — только от 3,78 В. Для питания 3,3 В ставят кварц 8 МГц, как в Arduino Pro Mini на 3,3 В, или делят частоту регистром CLKPR. Детектор пониженного питания при этом стоит настроить так, чтобы кристалл не работал за пределами допустимой области.

Как прошить ATmega328P без Arduino?

Подойдёт любой ISP-программатор: USBasp, AVRISP mkII, Atmel-ICE или плата Arduino со скетчем ArduinoISP. Его подключают к MOSI (вывод 17), MISO (18), SCK (19), RESET (1), питанию и общему проводу и прошивают командой avrdude -c usbasp -p m328p -U flash:w:main.hex:i. Прошивка по ISP стирает весь кристалл вместе с загрузчиком Arduino; вернуть его можно командой «Записать загрузчик» в Arduino IDE.

Почему новый ATmega328P не прошивается или работает медленно?

С завода кристалл тактируется от внутреннего RC-генератора 8 МГц с делителем на 8, то есть на 1 МГц. Для ISP частота SCK должна быть меньше четверти тактовой — ниже 250 кГц, а многие программаторы по умолчанию работают быстрее. Помогает ключ -B в avrdude, например -B 10 (около 100 кГц), или перемычка медленного режима на программаторе. После записи нужных фьюзов программатор снова можно ускорить.

Сколько потребляет ATmega328P?

Типовые значения из даташита при 25 °C: 0,3 мА в активном режиме на 1 МГц при 2 В, 1,7 мА на 4 МГц при 3 В, 5,2 мА на 8 МГц при 5 В. В режиме Power-down при 3 В — 0,1 мкА с выключенным сторожевым таймером и 4,2 мкА с включённым, в Power-save с часовым кварцем 32,768 кГц — 0,9 мкА. Плата Arduino целиком потребляет много больше: ток добавляют стабилизатор, светодиоды и USB-мост.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B), 2020 — рис. 1-1 — распиновка; табл. 2-1 — память моделей; разд. 9 — тактирование и CKDIV8; разд. 10 — режимы сна и BOD disable; разд. 15–18 — таймеры; табл. 20-7 — UBRR при 16 МГц; разд. 24 — АЦП; разд. 27–28 — загрузчик, фьюзы, сигнатуры, ISP; разд. 29 — токи, рис. 29-1 — частота от напряжения
  2. Microchip. ATmega328PB Data Sheet (DS40001906C), 2018 — состав периферии, 27 линий ввода-вывода, корпуса TQFP-32 и VQFN-32, диапазон температур
  3. Atmel. AT15007: Differences between ATmega328/P and ATmega328PB (Atmel-42559C), 11/2016 — порт E на выводах 3, 6, 19, 22; новая периферия; нет генератора с полным размахом; калибровка RC ±2 %; сигнатуры
  4. Atmel. AVR042: AVR Hardware Design Considerations (Atmel-2521R), 09/2016 — развязка питания на каждую пару выводов, AVCC и AREF, подтяжка RESET не меньше 10 кОм для debugWIRE, конденсаторы кварца
  5. Arduino. ArduinoCore-avr: boards.txt, cores/arduino (wiring.c, wiring_analog.c, Tone.cpp), variants/standard/pins_arduino.h, bootloaders — фьюзы и размер скетча Uno и Nano; Timer0–Timer2 и делитель АЦП в init(); analogReference(); выводы ШИМ и таймер tone(); Optiboot 4.4 и Makefile загрузчика ATmegaBOOT
  6. Optiboot: README — размер 512 байт, установка на Uno и Nano
  7. Arduino. Servo library: Servo.h, src/avr/ServoTimers.h — Timer1 на ATmega328P, длительности импульса 544–2400 мкс и период 20 мс
  8. MCUdude. MiniCore: README — минимальная схема с автосбросом через 100 нФ, поддержка ATmega328, 328P и 328PB
  9. AVR-LibC User Manual: <util/setbaud.h> — UBRRH_VALUE, UBRRL_VALUE, USE_2X, допуск BAUD_TOL = 2 %
  10. AVRDUDE: руководство (avrdude.1) — ключи -B (частота SCK) и -U с форматом m для записи фьюзов