Архитектура микроконтроллера 8051
Как устроен микроконтроллер 8051: раздельные памяти программ и данных, регистры специальных функций, машинный цикл из 12 периодов генератора, порты, таймеры, последовательный порт и система прерываний. Все адреса, биты и формулы — по руководству Intel MCS 51 и даташиту AT89S52, с примером инициализации на ассемблере.
Обновлено Редакция GAW
Архитектура 8051 задана руководством Intel MCS 51 (272383-002) и почти без изменений повторяется в совместимых кристаллах. Ниже — то, что нужно для программирования ядра: карта памяти, регистры специальных функций, тактирование, порты, таймеры, UART и прерывания. Команды, которыми всё это используется, описаны на странице «Система команд 8051».
Коротко
- Гарвардская схема: память программ до 64 КБ (только чтение), внутренняя память данных 128 или 256 байтов, внешняя память данных до 64 КБ.
- Регистры SFR занимают прямые адреса 80h–FFh; адресуемы по битам те, чей адрес оканчивается на 0 или 8.
- Машинный цикл — 6 состояний S1–S6 по 2 периода генератора, всего 12 периодов: 1 мкс при 12 МГц.
- Таймеры 0 и 1 — 16-битные, 4 режима; у 8052 есть Timer 2 с захватом, автоперезагрузкой и генератором скорости UART.
- Прерывания: 5 источников у 8051 и 6 у 8052, два уровня приоритета, реакция — от 3 до 9 машинных циклов.
Память
Память программ и память данных у 8051 разнесены по разным адресным пространствам. Программа выполняется с адреса 0000h, а с 0003h через каждые 8 байтов идут векторы прерываний. Младшие 4 КБ памяти программ (у других кристаллов — 8 или 16 КБ) находятся на кристалле или во внешней ПЗУ — выбор делает вывод EA; внешнюю память программ кристалл читает по сигналу PSEN. Внешняя память данных до 64 КБ подключается по сигналам RD и WR, при этом порт P0 служит мультиплексированной шиной адреса и данных, а P2 выдаёт старший байт адреса.
Внутренняя память данных устроена так (руководство Intel, глава 1):
| Адреса | Область | Доступ |
|---|---|---|
| 00h–1Fh | 4 банка регистров R0–R7 по 8 байтов | прямой и косвенный, R0–R7 текущего банка |
| 20h–2Fh | 16 байтов = 128 бит с адресами 00h–7Fh | прямой, косвенный и побитовый |
| 30h–7Fh | ОЗУ общего назначения, стек | прямой и косвенный |
| 80h–FFh | старшие 128 байтов ОЗУ — только у кристаллов с 256 байтами, например 8052 | только косвенный (@R0, @R1, стек) |
| 80h–FFh | регистры специальных функций SFR | только прямой |
Бит 00h — младший бит байта 20h, бит 07h — старший, бит 08h — младший бит байта 21h и так далее до бита 7Fh в байте 2Fh. Указатель стека после сброса равен 07h, и стек растёт вверх — прямо в банк 1, поэтому SP обычно переносят выше области, которую занимают банки и битовые переменные.
Регистры специальных функций
| SFR | Адрес | После сброса | Назначение |
|---|---|---|---|
| P0, P1, P2, P3 | 80h, 90h, A0h, B0h | FFh | защёлки портов |
| SP | 81h | 07h | указатель стека |
| DPL, DPH | 82h, 83h | 00h | указатель данных DPTR |
| PCON | 87h | 0XXXXXXX (HMOS), 0XXX0000 (CHMOS) | SMOD, флаги GF1, GF0, режимы PD и IDL |
| TCON | 88h | 00h | запуск таймеров, флаги переполнения и внешних прерываний |
| TMOD | 89h | 00h | режимы таймеров 0 и 1 |
| TL0, TL1, TH0, TH1 | 8Ah, 8Bh, 8Ch, 8Dh | 00h | счётчики таймеров 0 и 1 |
| SCON | 98h | 00h | режим и флаги последовательного порта |
| SBUF | 99h | не определено | буфер передатчика и приёмника |
| IE | A8h | 0XX00000 (8051), 0X000000 (8052) | разрешение прерываний |
| IP | B8h | XXX00000 (8051), XX000000 (8052) | приоритет прерываний |
| T2CON | C8h | 00h | управление Timer 2 (8052) |
| RCAP2L, RCAP2H, TL2, TH2 | CAh, CBh, CCh, CDh | 00h | Timer 2 (8052) |
| PSW | D0h | 00h | флаги и выбор банка |
| ACC | E0h | 00h | аккумулятор |
| B | F0h | 00h | регистр B |
Адреса — по таблице 1 главы 2 руководства Intel, значения после сброса — по её таблице 2; X — неопределённый бит. Регистры с адресами, оканчивающимися на 0 или 8 (P0, TCON, P1, SCON, P2, IE, P3, IP, T2CON, PSW, ACC, B), адресуются и побайтно, и побитно: SETB TR0 — это установка бита 4 регистра TCON. Конкретные кристаллы добавляют свои регистры в свободные адреса: например, у AT89S52 по адресу 8Eh находится AUXR.
Тактирование и сброс
Машинный цикл состоит из 6 состояний S1–S6, каждое длится два периода генератора — фазы 1 и 2. Весь цикл занимает 12 периодов, что при 12 МГц равно 1 мкс. Команды выполняются за 1, 2 или 4 машинных цикла. У AT89S52 вывод ALE в обычной работе выдаёт импульсы с частотой 1/6 частоты генератора, пропуская по одному импульсу при каждом обращении к внешней памяти данных.
Сброс происходит, если на выводе RST удерживается высокий уровень не меньше двух машинных циклов (24 периодов генератора) при работающем генераторе (руководство Intel, глава 3). После сброса PC = 0000h, порты переведены в единицы, SP = 07h, выбран банк регистров 0.
Порты ввода-вывода
Все четыре порта 8-битные и адресуются побитно. Порты P1, P2 и P3 имеют внутренние подтягивающие резисторы и называются квазидвунаправленными: записанная в защёлку единица отключает выходной ключ, вывод подтягивается к питанию, и внешняя схема может опустить его в ноль — так вывод работает входом. У порта P0 внутренних подтяжек нет, его выходы — с открытым стоком: единица переводит вывод в высокоимпедансное состояние, и для работы выходом нужен внешний резистор. Подтяжка P0 включается только тогда, когда он выдаёт адрес и данные внешней памяти.
| Вывод | Альтернативная функция (AT89S52) |
|---|---|
| P3.0, P3.1 | RXD, TXD — вход и выход последовательного порта |
| P3.2, P3.3 | INT0, INT1 — внешние прерывания |
| P3.4, P3.5 | T0, T1 — внешние входы таймеров |
| P3.6, P3.7 | WR, RD — стробы записи и чтения внешней памяти данных |
| P1.0, P1.1 | T2, T2EX — вход и вход захвата/перезагрузки Timer 2 |
| P1.5, P1.6, P1.7 | MOSI, MISO, SCK — внутрисхемное программирование |
Команды, которые читают порт, изменяют и записывают обратно, — ANL, ORL, XRL, CPL, INC, DEC, DJNZ, JBC, CLR и SETB бита порта, MOV бита порта из C — берут значение из защёлки, а не с вывода; уровень на самом выводе читают обычные MOV A, P1 и MOV C, P1.0.
Таймеры 0 и 1
Таймеры считают машинные циклы (режим таймера, C/T = 0) или спады на входах T0 и T1 (режим счётчика, C/T = 1). Режим задаёт регистр TMOD — младшая тетрада для Timer 0, старшая для Timer 1, в каждой биты GATE, C/T, M1 и M0:
| M1 M0 | Режим | Что делает |
|---|---|---|
| 00 | 0 | 13-битный таймер, совместимый с MCS-48 |
| 01 | 1 | 16-битный таймер-счётчик TH:TL |
| 10 | 2 | 8-битный с автоперезагрузкой: при переполнении TL загружается из TH |
| 11 | 3 | Timer 0: TL0 и TH0 — два отдельных 8-битных таймера, TH0 управляется битами Timer 1; Timer 1 в этом режиме стоит |
При GATE = 0 таймер считает, пока установлен бит TRx в TCON; при GATE = 1 — пока TRx = 1 и на выводе INTx высокий уровень, что позволяет измерять длительность импульса. Типовые значения TMOD (таблицы 3–6 руководства Intel): 01h — Timer 0 в режиме 1, 02h — в режиме 2, 10h — Timer 1 в режиме 1, 20h — Timer 1 в режиме 2; для двух таймеров значения объединяют по ИЛИ, например 21h.
В режиме 1 таймер переполняется через (65 536 − TH:TL) машинных циклов, и начальное значение нужно перезагружать в обработчике. При 11,0592 МГц машинный цикл длится 12 / 11,0592 МГц ≈ 1,085 мкс, и для периода 10 мс нужно 9216 циклов: TH0:TL0 = 65 536 − 9216 = 56 320 = DC00h. Подобрать предделитель и значение регистра таймера для других микроконтроллеров поможет калькулятор таймера.
Регистр TCON содержит биты запуска TR0 и TR1, флаги переполнения TF0 и TF1, флаги внешних прерываний IE0 и IE1 и биты IT0 и IT1: 0 — прерывание по низкому уровню, 1 — по спаду. TF0, TF1, IE0 и IE1 (при срабатывании по спаду) сбрасываются аппаратно при переходе к обработчику.
Timer 2 (8052)
У 8052 и AT89S52 есть третий 16-битный таймер с регистром управления T2CON. Он работает в трёх режимах: 16-битная автоперезагрузка из RCAP2H:RCAP2L, 16-битный захват значения в RCAP2H:RCAP2L по спаду на входе T2EX и генератор скорости последовательного порта (биты RCLK и TCLK). Флаги TF2 и EXF2 вызывают одно прерывание с вектором 002Bh и сбрасываются программно.
Последовательный порт
Полнодуплексный UART управляется регистром SCON (биты SM0, SM1, SM2, REN, TB8, RB8, TI, RI), данные передаются и принимаются через SBUF:
| SM0 SM1 | Режим | Формат | Скорость |
|---|---|---|---|
| 00 | 0 | сдвиговый регистр | f_осц / 12 |
| 01 | 1 | 8-битный UART | задаётся Timer 1 или Timer 2 |
| 10 | 2 | 9-битный UART | f_осц / 64 или f_осц / 32 |
| 11 | 3 | 9-битный UART | задаётся Timer 1 или Timer 2 |
В режимах 1 и 3 с Timer 1 в режиме 2:
где SMOD — старший бит PCON (регистр не адресуется по битам, бит ставят командой ORL PCON, #80h). При кварце 11,0592 МГц и TH1 = FDh получается ровно 9600 бод, с SMOD = 1 — 19 200. С частотой 12 МГц точных стандартных скоростей не получается, поэтому для UART и выбирают кварцы 11,0592 МГц. Значение TH1 и ошибку скорости для любого кварца считает калькулятор скорости UART в режиме 8051.
Флаги TI и RI устанавливаются аппаратно — TI в начале стоп-бита передачи, RI в середине стоп-бита приёма — и должны сбрасываться программой. Бит SM2 в режимах 2 и 3 включает режим многопроцессорного обмена: RI устанавливается только при девятом бите, равном 1.
Прерывания
| Источник | Флаг | Вектор | Бит IE | Бит IP |
|---|---|---|---|---|
| Внешнее прерывание 0 | IE0 | 0003h | EX0 (IE.0) | PX0 |
| Timer 0 | TF0 | 000Bh | ET0 (IE.1) | PT0 |
| Внешнее прерывание 1 | IE1 | 0013h | EX1 (IE.2) | PX1 |
| Timer 1 | TF1 | 001Bh | ET1 (IE.3) | PT1 |
| Последовательный порт | RI или TI | 0023h | ES (IE.4) | PS |
| Timer 2 (8052) | TF2 или EXF2 | 002Bh | ET2 (IE.5) | PT2 |
Чтобы прерывание работало, нужно установить общий бит EA (IE.7) и бит конкретного источника, а обработчик разместить по его вектору. Бит в регистре IP переводит источник на высокий уровень приоритета: обработчик не может быть прерван запросом того же или более низкого уровня. При одновременных запросах одного уровня порядок задан аппаратно — в последовательности строк таблицы, от внешнего прерывания 0 к Timer 2.
В системе с одним прерыванием реакция занимает больше 3 и меньше 9 машинных циклов (руководство Intel, глава 3): запрос опрашивается в каждом цикле, вызов обработчика занимает 2 цикла, а задержку добавляют незавершённая команда — до 3 циклов для MUL и DIV — и запрет на переход к обработчику сразу после RETI или записи в IE и IP. Обработчик завершают командой RETI, а аккумулятор, PSW и используемые регистры сохраняют в стеке сами — аппаратно туда попадает только адрес возврата.
Режимы пониженного потребления
У КМОП-кристаллов — CHMOS-версий Intel с буквой C в названии, например 80C51BH, и у AT89S52 — регистр PCON содержит биты IDL и PD. В режиме Idle останавливается ядро, а ОЗУ и периферия продолжают работать; по руководству Intel, ток 80C51BH снижается примерно до 15 % от рабочего. Выходят из Idle по любому разрешённому прерыванию или сбросом. В режиме Power Down останавливается генератор, содержимое ОЗУ и регистров SFR сохраняется, ток 80C51BH — обычно меньше 10 мкА. У 80C51 выйти из Power Down можно только сбросом, а AT89S52 умеет просыпаться и по прерыванию. Если одновременно записать единицы в PD и IDL, приоритет у PD.
Пример инициализации
UART на 9600 бод и прерывание Timer 0 каждые 10 мс при кварце 11,0592 МГц:
ORG 0000h
LJMP MAIN
ORG 000Bh ; Timer 0 vector
LJMP T0_ISR
ORG 0030h
MAIN: MOV SP, #2Fh ; stack above the banks and bit area
MOV TMOD, #21h ; Timer 1 mode 2 (baud rate), Timer 0 mode 1
MOV TH1, #0FDh ; 9600 baud at 11.0592 MHz, SMOD = 0
MOV SCON, #50h ; UART mode 1, receiver enabled
SETB TR1
MOV TH0, #0DCh ; 65536 - 9216 = DC00h: 10 ms
MOV TL0, #00h
SETB ET0
SETB EA
SETB TR0
LOOP: SJMP LOOP
T0_ISR: MOV TH0, #0DCh ; reload for the next 10 ms
MOV TL0, #00h
CPL P1.0 ; toggle a pin, PSW is not touched
RETI
Обработчик не меняет ни аккумулятор, ни флаги, поэтому ничего не сохраняет в стеке; если бы он использовал A или PSW, их пришлось бы сохранить командами PUSH ACC и PUSH PSW и восстановить в обратном порядке перед RETI.
Частые вопросы
Как настроить UART 8051 на 9600 бод?
При кварце 11,0592 МГц: Timer 1 в режиме 2 (TMOD = 20h), TH1 = FDh, SCON = 50h (режим 1, приём разрешён), затем SETB TR1. Скорость равна 11 059 200 / (32 · 12 · (256 − 253)) = 9600 бод. Бит SMOD в PCON удваивает её до 19 200 при том же TH1.
Какие прерывания есть у 8051?
Пять источников с векторами: внешнее прерывание 0 (0003h), Timer 0 (000Bh), внешнее прерывание 1 (0013h), Timer 1 (001Bh) и последовательный порт (0023h); у 8052 добавляется Timer 2 (002Bh). Каждому можно задать один из двух уровней приоритета в регистре IP, общий запрет — бит EA в IE.
Почему вывод порта 8051 не читается как ноль после записи нуля?
Читается — после записи нуля вывод притянут к земле и читается как 0. Проблема обратная: чтобы вывод работал входом, в его защёлку нужно сначала записать 1. Тогда у P1–P3 вывод подтягивается внутренним резистором и внешний сигнал может опустить его в 0, а у P0 вывод переходит в высокоимпедансное состояние.
Сколько длится сброс 8051?
Высокий уровень на RST нужно удерживать не меньше двух машинных циклов — 24 периодов генератора — при работающем генераторе. После сброса PC = 0000h, SP = 07h, порты P0–P3 = FFh, остальные регистры SFR в основном обнулены, а содержимое SBUF не определено.
Источники
- Intel. MCS 51 Microcontroller Family User's Manual (272383-002, февраль 1994); копия на сайте курса MIT 6.115 — глава 1 — память, векторы, машинный цикл; глава 2 — таблицы 1 и 2 (адреса SFR и значения после сброса), PCON, IE, IP, TCON, TMOD и таблицы 3–6, T2CON, SCON, формулы скорости UART; глава 3 — порты, сброс, время реакции на прерывание, сброс флагов прерываний, режимы Idle и Power Down
- Atmel. AT89S52 8-bit Microcontroller with 8K Bytes In-System Programmable Flash (1919D, 6/08) — порты P0–P3 и альтернативные функции, выводы ISP, RST, ALE, регистр AUXR, выход из Power Down по прерыванию
Нашли ошибку?
Смотрите также
- 8051 (MCS-51)Ядро MCS-51, 8051 и 8052, AT89S52, AT89C2051, система команд
- Система команд 8051111 команд с байтами, циклами и флагами, карта кодов, примеры
- Скорость UARTUBRR, BRR, TH1 и ошибка скорости
- Таймер AVR и STM32Предделитель, OCRnA, PSC и ARR под частоту, мёртвое время, энкодер
- Архитектура AVRЯдро, конвейер, память, порты, прерывания, сброс, такты и сон