Руководство · Начальный · 30 min

Архитектура 8051: выводы, карта памяти и регистры

Что на самом деле содержит 8051: гарвардское ядро, четыре порта с разными свойствами, 256 байт ОЗУ и машинный цикл, который можно подсчитать.

Введение

Большинство курсов по микроконтроллерам начинается с 8051, и большинство студентов знакомится с ним как со списком фактов для запоминания: четыре порта, 128 байт ОЗУ (RAM), два таймера, шесть прерываний. Запомнить его таким образом бесполезно. Если понять его как набор осознанных компромиссов, сделанных в 1980 году — когда ОЗУ стоило реальных денег, а кристалл должен был поместиться в 40 выводов, — оно объясняет почти все принципы работы современных небольших микроконтроллеров.

Это экскурсия по архитектуре: что находится внутри корпуса, как разделена память и почему расчёт времени здесь особенно прост. В двух следующих материалах рассматриваются управление выводами и формирование PWM с помощью таймера.

«8051» — это семейство, а не кристалл

Intel представила MCS-51 в 1980 году, а затем широко лицензировала ядро, поэтому сегодня никто не покупает Intel 8051. Покупают совместимый компонент — чаще всего AT89S52 от Atmel (ныне Microchip), в котором к исходной ROM, стираемой ультрафиолетом (UV), добавлена flash-память, перепрограммируемая через четыре вывода.

Различия, о которых стоит знать:

8051 (оригинал) AT89S52 (то, что у вас)
Память программ 4 KB ROM 8 KB flash-памяти
Внутреннее ОЗУ 128 байт 256 байт
Таймеры 2 3
Источники прерываний 5 6
Программирование Масочная ROM на заводе В системе, через выводы SPI

Всё остальное — набор команд, порты, расположение регистров и расчёт времени — идентично. Учебные материалы, написанные для 8051, без изменений применимы к кристаллу на вашем столе.

Что находится внутри корпуса

В одном 40-выводном DIP-корпусе находится полноценный компьютер: 8-разрядный ЦП (CPU), flash-память программ, ОЗУ данных, три таймера/счётчика, полнодуплексный последовательный порт, контроллер прерываний и четыре 8-разрядных порта ввода-вывода. Операционной системы нет, и ничего не работает, кроме вашего кода.

Схема выводов 8051 в 40-выводном DIP-корпусе, нарисованная вертикально, с выемкой для вывода 1 сверху. Левая колонка содержит выводы от 1 до 20: выводы порта 1 P1.0–P1.7 с их альтернативными функциями T2, T2EX, MOSI, MISO и SCK, затем RST, затем выводы порта 3 P3.0–P3.7 с обозначениями RXD, TXD, INT0, INT1, T0, T1, WR и RD, затем XTAL2, XTAL1 и GND. Правая колонка содержит выводы от 40 до 21: VCC, выводы порта 0 P0.0–P0.7, которые одновременно являются AD0–AD7, затем EA, ALE и PSEN, затем выводы порта 2 P2.7–P2.0, которые одновременно являются адресными линиями A15–A8. Цветовое кодирование отделяет порты ввода-вывода (I/O), альтернативные функции порта 3, выводы тактового сигнала и управления, а также питание.
Из сорока выводов тридцать два предназначены для ввода-вывода. Порт 0 пронумерован в обратном порядке относительно остальных, а альтернативные обозначения порта 3 указывают, где находятся последовательный порт, внешние прерывания и входы таймеров. Скачать SVG

Четыре вывода вообще не являются вводами-выходами, и все четыре должны быть подключены правильно, прежде чем что-либо заработает: XTAL1 и XTAL2 для кварца, RST для цепи сброса и EA для выбора внутренней или внешней памяти программ. Если EA подключён неверно, кристалл молча ничего не делает.

Минимальная схема, необходимая 8051 для работы. На блоке кристалла AT89S52 показаны шесть выводов: вывод VCC 40 подключён к шине пяти вольт, а вывод GND 20 — к земле; вывод EA 31 красным подключён к шине пяти вольт с пометкой поднять EA на высокий уровень, иначе кристалл ничего не делает; вывод XTAL2 18 и XTAL1 19 подключены по разные стороны кварца 11.0592 MHz, причём от каждого вывода кварца к земле подключён конденсатор 33 пикофарада; вывод RST 9 подключён к конденсатору 10 микрофарад, идущему к шине пяти вольт, и резистору 10 килом, идущему к земле, с пометкой, что сброс активен по высокому уровню (HIGH).
Четыре соединения и несколько пассивных элементов. Обратите внимание на цепь сброса: конденсатор идёт к источнику питания, а не к земле, потому что RST активен по высокому уровню. Скачать SVG

Гарвардская архитектура: код и данные — разные миры

8051 хранит память программ и память данных в отдельных адресных пространствах. Адрес 0x0030 означает одно для выборки команды и совершенно другое для обращения к данным: это разные виды памяти, к которым обращаются разными командами.

Именно поэтому компиляторы C для 8051 заставляют задуматься о классах памяти, которые другие платформы скрывают. Строковый литерал, который вы никогда не изменяете, должен находиться в памяти code, где есть запас в килобайты. Если по ошибке поместить его в data, он съест часть тех 256 байт, которые нужны для всего остального:

// In code (flash) — costs nothing from your 256 bytes of RAM.
const char code banner[] = "Line follower v1";

// In RAM — 17 of your 256 bytes, gone, for a string that never changes.
const char banner_bad[] = "Line follower v1";

В Arduino это различие и есть причина существования PROGMEM. В 8051 это не оптимизация, а разница между программой, которая помещается, и программой, которая не помещается.

Карта внутреннего ОЗУ

256 байт внутреннего ОЗУ — не единая область временной памяти. Они разделены на области с разными возможностями, и знание того, где какая область находится, составляет большую часть смысла карты памяти.

Карта внутренней памяти данных 8051, нарисованная как расположенные друг над другом блоки от адреса 00h внизу до FFh вверху. Снизу: четыре 8-байтовых банка регистров по адресам 00h–07h, 08h–0Fh, 10h–17h и 18h–1Fh; 16-байтовая побитово адресуемая область 20h–2Fh, содержащая 128 отдельно адресуемых битов; 80 байт ОЗУ для временных данных и стека по адресам 30h–7Fh; и по адресам 80h–FFh блок, содержащий как специальные функциональные регистры, доступные при прямой адресации, так и верхние 128 байт ОЗУ, доступные только при косвенной адресации. Стрелка показывает, что указатель стека сбрасывается в 07h, поэтому стек начинается с 08h поверх банка регистров 1, а вторая стрелка отмечает область 80h–FFh как две памяти, разделяющие один диапазон адресов.
Четыре области с четырьмя разными задачами. Два отмеченных факта особенно важны: стек попадает на банк регистров 1, а верхняя половина диапазона адресов — это две отдельные памяти. Скачать SVG

00h–1Fh — четыре банка регистров. R0–R7 не являются фиксированными адресами: это окно в один из четырёх 8-байтовых банков, выбранный двумя битами (RS0 и RS1) в слове состояния программы. Переключение банков — запись двух битов, поэтому это очень дешёвый способ выделить собственные регистры обработчику прерывания вместо сохранения и восстановления восьми регистров.

20h–2Fh — побитовая адресация. Эти 16 байтов также адресуются как 128 отдельных битов, от 00h до 7Fh. В 8051 есть настоящие команды работы с одним битом — SETB, CLR, JB, JNB, — поэтому флаг здесь занимает один бит и одну команду, а не байт и маску. Поэтому компиляторы C для 8051 предлагают тип bit, которого нет больше нигде.

30h–7Fh — временные данные и стек. Восемьдесят байт для переменных и стека вызовов, и именно этот ресурс реально заканчивается.

80h–FFh — две памяти, один диапазон адресов. Прямая адресация здесь обращается к специальным функциональным регистрам; косвенная адресация (через R0 или R1) обращается к верхним 128 байтам ОЗУ. Номера одинаковы, памяти разные, а выбор задаётся формой используемой команды. У исходного 8051 с 128 байтами верхнего ОЗУ просто нет.

Специальные функциональные регистры — это просто память

Каждое периферийное устройство 8051 управляется записью байтов по адресам прямого диапазона 80h–FFh. API нет — есть регистр, и установка бита в нём меняет работу микросхемы.

Регистр Адрес Что управляет
P0 P1 P2 P3 80h, 90h, A0h, B0h Четыре порта ввода-вывода
TMOD 89h Выбор режима таймеров 0 и 1
TCON 88h Биты запуска таймеров и флаги переполнения
TH0 TL0 TH1 TL1 8Ch, 8Ah, 8Dh, 8Bh Регистры счёта таймеров
SCON SBUF 98h, 99h Управление последовательным портом и данные
IE IP A8h, B8h Разрешение и приоритет прерываний
PSW D0h Флаги и биты выбора банка регистров
SP 81h Указатель стека

Запись P1 = 0x0F; в C — это запись по адресу 90h, и восемь выводов меняют состояние. Именно в этой непосредственности заключается весь интерес к кристаллу как учебному устройству.

Расчёт времени

Один машинный цикл на классическом ядре 8051 составляет двенадцать периодов генератора, а большинство команд занимает один или два машинных цикла. Это фиксированное отношение позволяет точно рассчитать время выполнения, а не измерять его:

machine cycle = 12 / f_osc

at 11.0592 MHz : 12 / 11 059 200 = 1.085 µs
at 12 MHz      : 12 / 12 000 000 = 1.000 µs

Цикл из трёх команд, выполняемых за один машинный цикл, на частоте 11.0592 MHz каждый раз занимает 3.26 µs: без кэша, конвейера и нестабильности из-за прерываний, кроме той, которую вы включаете сами. Немногие современные процессоры позволяют рассуждать так, и именно поэтому 8051 до сих пор встречается в критичных по времени периферийных устройствах.

Почему частота кварца равна 11.0592 MHz

Это число кажется произвольным, но это не так. Последовательный порт получает скорость передачи делением тактового сигнала машинного цикла, и 11.0592 MHz делится на стандартные скорости передачи точно:

baud = f_osc / (12 × 32 × (256 − TH1))

11.0592 MHz, TH1 = 253 :  11 059 200 / (12 × 32 × 3) = 9600.0   ✓ exact
12 MHz,      TH1 = 253 :  12 000 000 / (12 × 32 × 3) = 10416.7  ✗ 8.5% off

UART допускает несколько процентов ошибки; ошибка 8.5% портит каждый кадр. Если ваша плата 8051 выводит по последовательному порту мусор, сначала проверьте кварц, а не код.

Чего у 8051 нет

Две отсутствующие возможности определяют каждый проект на 8051, и ни одна из них не очевидна из списка функций:

  • Нет аналого-цифрового преобразователя. Для чтения потенциометра, термистора или аналогового датчика линии нужен внешний аналого-цифровой преобразователь (ADC), например ADC0804. Функции analogRead() здесь нет.
  • Нет аппаратного PWM. Ничто на кристалле не создаёт сигнал с переменным рабочим циклом. Для затемнения светодиода (LED) или задания скорости двигателя нужно самостоятельно построить PWM из прерывания таймера и заплатить за это временем ЦП.

В Arduino Uno есть обе возможности. Честное сравнение такое: 8051 — не худший Arduino, а нижний слой под ним, из которого убрали удобства, чтобы увидеть, что именно они делали.

Когда всё идёт не так

  • Плата не подаёт признаков жизни и ничего не греется. Проверьте, что EA (вывод 31) находится на +5 V. Если он плавает или заземлён, кристалл выбирает код из внешней памяти, которой нет, и не выполняет ничего, без каких-либо симптомов.
  • Он постоянно сбрасывается или вообще не запускается. Сброс в 8051 активен по высокому уровню. Цепь включения питания — конденсатор 10 µF от +5 V к RST и резистор 10 kΩ от RST к земле. Если подключить её как сброс с активным низким уровнем, кристалл останется в постоянном сбросе.
  • Последовательный вывод содержит мусор. Почти всегда виноват кварц. Кристалл на 12 MHz не может получить стандартные скорости передачи.
  • Переменные повреждают друг друга без причины. Скорее всего, закончились 80 байт по адресам 30h–7Fh или стек вырос вниз до переменных. Проверьте карту памяти, которую выводит компилятор.
  • Регистры неожиданно меняются внутри прерывания. Указатель стека сбрасывается в 07h, поэтому стек начинается с 08h — это и есть банк регистров 1. Либо измените SP в коде запуска, либо не используйте банк 1.

Исследуйте граф

Входит в эти сборки

Проекты и учебные пути, в которые входит это руководство.

Дополнительные материалы

Источники