Архитектура микроконтроллеров AVR
Микроконтроллер AVR — это 8-битное RISC-ядро с раздельными памятью программ и памятью данных, 32 рабочими регистрами и периферией, которая видна как регистры ввода-вывода. Разбираем по даташиту ATmega328P, как устроены ядро и конвейер, три адресных пространства, порты, прерывания, сброс, тактирование и режимы сна — то общее, что есть у классических ATmega и ATtiny.
Обновлено Редакция GAW
AVR — семейство 8-битных микроконтроллеров Atmel, которое теперь выпускает Microchip. В классических ATmega и ATtiny одно и то же ядро и одинаковое устройство памяти, прерываний и портов; отличаются объём памяти, набор периферии и корпуса. Здесь всё разобрано на примере ATmega328P из Arduino Uno и Nano — с адресами и цифрами из его даташита.
Коротко
- Ядро: гарвардская архитектура, конвейер на одну команду, 32 рабочих регистра — до 1 MIPS на 1 МГц.
- Память ATmega328P: флеш 32 КБ (16K слов), SRAM 2 КБ, EEPROM 1 КБ — три отдельных адресных пространства.
- Периферия: 64 регистра ввода-вывода (команды IN, OUT, SBI, CBI) и 160 регистров расширенного ввода-вывода.
- Прерывания: 26 векторов в начале флеш-памяти; чем меньше адрес, тем выше приоритет; реакция — от 4 тактов.
- Запуск: с завода — внутренний генератор 8 МГц, делённый на 8, то есть 1 МГц.
Гарвардская архитектура и конвейер
Память программ и память данных подключены к ядру AVR разными шинами. Пока одна команда выполняется, следующая уже выбирается из флеш-памяти, — это конвейер на одну ступень. Выполнение простой команды — чтение двух регистров, операция АЛУ и запись результата — укладывается в один такт, поэтому ядро завершает команду каждый такт.
Тактовая частота ядра не делится внутри: на 16 МГц AVR выполняет до 16 миллионов простых команд в секунду. Большинство команд — 16-битные, четыре занимают два слова: JMP, CALL, LDS и STS. Обращение к SRAM занимает 2 такта, переходы и вызовы — 2–4 такта. Число тактов каждой команды — в статье «Система команд AVR».
Рабочие регистры
У ядра 32 восьмибитных рабочих регистра r0–r31, и почти все команды работают с ними напрямую. АЛУ берёт операнды из регистров и туда же пишет результат — память данных для арифметики не нужна. Шесть старших регистров образуют три 16-битных указателя: X (r27:r26), Y (r29:r28) и Z (r31:r30). Ими адресуют память данных — с автоинкрементом, автодекрементом и смещением до 63 байт от Y и Z, а указатель Z ещё и читает константы из флеш-памяти командой LPM.
Регистры отображены на первые 32 адреса памяти данных, хотя физически это не ячейки SRAM. Результат операций АЛУ отражается во флагах регистра состояния SREG: перенос, ноль, знак, переполнение и другие. Схема регистров, флаги SREG и режимы адресации подробно разобраны в статье «Система команд AVR».
Три адресных пространства
Флеш-память программ
У ATmega328P 32 КБ флеш-памяти. Все команды AVR — по 16 или 32 бита, поэтому память организована 16-битными словами: 16K слов с адресами 0x0000–0x3FFF, а счётчик команд PC — 14-битный. В начале памяти — таблица векторов сброса и прерываний, в конце — загрузочная секция, размер которой задают фьюзы BOOTSZ. Только код из загрузочной секции может перезаписывать флеш командой SPM, на этом основаны загрузчики вроде загрузчика Arduino.
Флеш-память выдерживает не меньше 10 000 циклов записи и стирания. Константные таблицы можно размещать в любой её части и читать командой LPM.
Память данных
Память данных ATmega328P — 2304 адреса подряд, от 0x0000 до 0x08FF:
| Адреса | Что там | Как обращаться |
|---|---|---|
| 0x0000–0x001F | 32 рабочих регистра r0–r31 | любые команды с регистрами |
| 0x0020–0x005F | 64 регистра ввода-вывода | IN, OUT по адресам 0x00–0x3F; биты первых 32 — SBI, CBI, SBIS, SBIC |
| 0x0060–0x00FF | 160 регистров расширенного ввода-вывода | только LD, LDS, LDD, ST, STS, STD |
| 0x0100–0x08FF | 2048 байт SRAM | переменные и стек |
Пять режимов адресации — прямой, косвенный, косвенный со смещением, с предекрементом и с постинкрементом — достают до всего этого пространства. Доступ к SRAM занимает два такта.
EEPROM
EEPROM — отдельное пространство в 1 КБ, которое не входит ни в память программ, ни в память данных. К нему обращаются через регистры ввода-вывода EEAR (адрес), EEDR (данные) и EECR (управление). Запись байта длится около 3,3 мс и выдерживает не меньше 100 000 циклов; на время чтения ядро останавливается на 4 такта, на время запуска записи — на 2. Чтобы случайно не испортить данные, запись требует последовательности: сначала бит EEMPE, затем в течение четырёх тактов — EEPE. При пониженном питании EEPROM портится, поэтому даташит советует держать микроконтроллер в сбросе с помощью детектора пониженного питания (BOD).
Порты и регистры ввода-вывода
Вся периферия AVR — порты, таймеры, USART, SPI, АЦП — управляется регистрами в пространстве ввода-вывода. Каждый порт описывают три регистра: DDRx задаёт направление (1 — выход), PORTx — уровень выхода или включение подтягивающего резистора у входа, PINx — читает уровень на выводах. Запись единицы в бит PINx переключает соответствующий бит PORTx — так вывод инвертируют одной командой.
Регистры портов B, C и D у ATmega328P лежат в первых 32 адресах пространства ввода-вывода, поэтому отдельный бит меняют командами SBI и CBI за два такта без риска затереть соседние биты. Регистры таймеров, АЦП и USART в основном находятся в расширенном пространстве — к ним обращаются командами LDS и STS. Как номера выводов Arduino соответствуют портам и битам, показывает карта выводов Arduino.
Стек
Стек — область в конце SRAM, которая растёт к младшим адресам. Указатель стека SP — пара регистров SPH:SPL в пространстве ввода-вывода; у ATmega328P после сброса он уже равен последнему адресу SRAM (0x08FF). PUSH уменьшает SP на 1, вызов подпрограммы или прерывание кладут в стек адрес возврата — 2 байта при 16-битном счётчике команд и 3 байта у кристаллов с флеш-памятью больше 128 КБ, например ATmega2560. Стек и переменные делят одну и ту же SRAM: глубокая рекурсия или большой локальный массив могут незаметно затереть глобальные данные.
Прерывания
Таблица векторов занимает начало флеш-памяти: у ATmega328P это 26 векторов по два слова — сброс, внешние прерывания INT0 и INT1, прерывания по изменению уровня, сторожевой таймер, таймеры, SPI, USART, АЦП, EEPROM, компаратор, TWI и SPM. В векторе обычно стоит переход к обработчику. Приоритет определяется адресом: чем меньше адрес вектора, тем выше приоритет; самый высокий — у сброса, следом — INT0.
Чтобы прерывание сработало, нужно установить его собственный бит разрешения и общий флаг I в SREG (команда SEI). Когда прерывание принимается:
- Аппаратно сбрасывается флаг I — вложенные прерывания запрещены, пока программа сама их не разрешит.
- Не меньше чем за 4 такта счётчик команд сохраняется в стек, затем выполняется команда вектора — переход за 3 такта.
- Флаг прерывания, по которому оно пришло, обычно сбрасывается аппаратно.
- Команда RETI за 4 такта возвращает адрес из стека и снова устанавливает флаг I.
Регистр SREG аппаратно не сохраняется — это задача обработчика. После возврата ядро обязательно выполнит одну команду основной программы, прежде чем принять следующее прерывание. Если прерывание пришло, когда оно было запрещено, флаг запоминает событие, и обработчик вызовется после разрешения. Векторы можно перенести в начало загрузочной секции битом IVSEL регистра MCUCR — это нужно загрузчику, который пользуется прерываниями.
Сброс и запуск
ATmega328P сбрасывают четыре источника:
- включение питания — напряжение ниже порога сброса при включении;
- внешний сброс — низкий уровень на выводе RESET дольше минимальной длительности;
- сторожевой таймер — истёк его период в режиме сброса системы;
- детектор пониженного питания — напряжение ниже порога BOD, если детектор включён.
При сбросе выводы сразу переходят в начальное состояние (входы без подтяжки) — даже без тактового сигнала. Когда все источники сброса отпускают, внутренний счётчик ещё удерживает сброс, пока стабилизируется питание и запускается генератор; длительность задержки выбирают фьюзы SUT и CKSEL. Затем выполнение начинается с вектора сброса по адресу 0x0000 или, если запрограммирован фьюз BOOTRST, с начала загрузочной секции.
Тактирование
Источник тактового сигнала выбирают фьюзы CKSEL:
| Источник | CKSEL3…0 |
|---|---|
| Кварц, экономичный генератор | 1111–1000 |
| Кварц, генератор с полным размахом | 0111–0110 |
| Часовой кварц 32,768 кГц | 0101–0100 |
| Внутренний генератор 128 кГц | 0011 |
| Калиброванный RC-генератор 8 МГц | 0010 |
| Внешний тактовый сигнал | 0000 |
С завода выбран внутренний RC-генератор 8 МГц и запрограммирован фьюз CKDIV8, поэтому новый ATmega328P работает на 1 МГц. Делитель системной частоты можно поменять и из программы регистром CLKPR — от 1 до 256. Значения фьюзов для своего источника удобно подобрать в калькуляторе фьюзов AVR.
Режимы сна
Шесть режимов сна выключают разные части микроконтроллера: Idle, ADC Noise Reduction, Power-down, Power-save, Standby и Extended Standby. Режим выбирают биты SM2–SM0 регистра SMCR, разрешают битом SE, а входят в сон командой SLEEP. Разрешённое прерывание будит микроконтроллер: после 4 тактов и времени запуска генератора выполняется обработчик, а затем — команда после SLEEP. Содержимое регистров и SRAM во сне сохраняется. Кроме сна, ток снижают регистром PRR — он отключает тактирование неиспользуемой периферии.
Классические AVR и новые серии
Всё сказанное относится к классическим ATmega и ATtiny. У XMEGA и у новых серий с ядром AVRxt — tinyAVR 0/1/2, megaAVR 0, AVR Dx и Ex — устройство другое: контроллер прерываний с уровнями приоритета, другие интерфейсы программирования (PDI у XMEGA, UPDI у AVRxt), а у AVRxt флеш-память ещё и видна в общем адресном пространстве данных. Различия ядер и наборов команд сведены в статье «Система команд AVR», а обзор семейств — в разделе «Микроконтроллеры AVR».
Частые вопросы
Почему AVR выполняет команду за один такт?
У AVR гарвардская архитектура: память программ и память данных подключены к ядру разными шинами, поэтому следующая команда выбирается из флеш-памяти, пока выполняется текущая. А операнды берутся из 32 рабочих регистров, к которым есть доступ за один такт: чтение двух регистров, операция в АЛУ и запись результата укладываются в такт. Отсюда до 1 миллиона команд в секунду на каждый мегагерц. Команды, которые обращаются к SRAM или переходят по адресу, занимают 2–4 такта.
Сколько памяти у ATmega328P и как она устроена?
Три независимых адресных пространства. Флеш-память программ — 32 КБ, организована как 16K слов по 16 бит, адреса слов 0x0000–0x3FFF. Память данных — адреса 0x0000–0x08FF: 32 рабочих регистра, 64 регистра ввода-вывода, 160 регистров расширенного ввода-вывода и 2048 байт SRAM. EEPROM — отдельные 1024 байта, к которым обращаются через регистры EEAR, EEDR и EECR.
Сколько тактов проходит от прерывания до обработчика?
Не меньше четырёх тактов: за это время счётчик команд сохраняется в стек. Затем выполняется команда в векторе — обычно переход к обработчику, ещё три такта. Если в момент прерывания выполнялась многотактная команда, она сначала завершается, а из режима сна реакция удлиняется ещё на четыре такта плюс время запуска генератора. Возврат командой RETI занимает четыре такта.
Сохраняет ли AVR регистр SREG при прерывании?
Нет. Аппаратно в стек попадает только адрес возврата, а флаг I в SREG сбрасывается, чтобы запретить вложенные прерывания. Если обработчик меняет флаги, он должен сам сохранить SREG и восстановить его перед RETI; компилятор avr-gcc делает это в функциях с ISR() автоматически.
На какой частоте работает новый ATmega328P?
На 1 МГц: с завода выбран внутренний RC-генератор 8 МГц и запрограммирован фьюз CKDIV8, который делит частоту на 8. Чтобы работать на 8 МГц, снимают CKDIV8 или пишут делитель в регистр CLKPR из программы; для кварца меняют фьюзы CKSEL и SUT. Частоту и фьюзы можно подобрать в калькуляторе фьюзов AVR.
Сколько раз можно перезаписать флеш и EEPROM AVR?
По даташиту ATmega328P — не меньше 10 000 циклов записи и стирания для флеш-памяти и не меньше 100 000 для EEPROM. Запись байта EEPROM длится около 3,3 мс, и всё это время новую запись начинать нельзя. Для данных, которые меняются часто, например счётчиков, запись распределяют по разным ячейкам.
Источники
- Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet, DS40002061B — 7 — ядро: гарвардская архитектура, конвейер, регистры, указатели X, Y, Z, стек, время реакции на прерывание; 8 — флеш, SRAM, EEPROM, карта памяти данных, время записи EEPROM; 9 — источники тактирования, заводская настройка; 10 — режимы сна; 11 — источники сброса; 12 — таблица векторов; 14 — порты; 27 — размеры загрузочной секции
- Microchip. AVR Instruction Set Manual, DS40002198C — форматы команд, такты, работа со стеком на кристаллах с 22-битным счётчиком команд
Нашли ошибку?
Смотрите также
- Система команд AVRВсе инструкции с флагами и тактами, адресация, примеры кода
- ATmega328PРаспиновка, фьюзы, Optiboot, периферия, питание, схема и код на C
- ATmega128Память, распиновка, фьюзы, M103C и JTAG, ISP через PE0/PE1
- Arduino и AVRЧто делают init(), millis(), analogWrite(), analogRead() и загрузчик
- Фьюзы AVRБиты фьюзов, заводские значения и avrdude
- AVRATmega, ATtiny, AVR Dx/Ex: семейства, прошивка, инструменты