Плотно я сейчас занимаюсь этим отечественным микроконтроллером -
КР1878ВЕ1,
который кроме идентичной цоколевки выводов, практически ничем более на
PIC
и не похож, почему я и попытаюсь здесь изложить, что у него там интересного
внутри, и, возможно, кто уже имел опыт работы с
КР1878ВЕ1, меня здесь дополнят,
и, в случае чего - поправят.
Прежде всего блок-схема, которая приведена практически во всех источниках
по
КР1878ВЕ1, особо подробной информации о структуре микроконтроллера (далее -
МК) она не дает, но по крайней мере избавляет от необходимости пересказывать,
что внутри этого МК имеется в наличии.
Отчасти - набор типичный для МК, но есть и нехарактерные узлы: два раздельных стека и
таймер не только с предделителем, но и с 3-мя разрядами переполнения, что позволяет
считать втрое "длиннее" обычного.
Сторожевой таймер имеет как свой независимый генератор, так и возможность подключения
к тактовому генератору, что позволяет использовать его как второй точный интервальный таймер.
А вот дальше начинаются уже особенности и интересности этого МК:
И первое, что меня собственно от него отпугнуло, так это то, что архитектура у него
безаккумуляторная.
Как принято в таких случаях говорить, он "
более ортогонален" и может использовать две
любых ячейки из памяти данных в качестве операндов.
В связи с этим в команде этот МК вынужден держать как код операции, так и адреса
обоих операндов, поэтому команды у
КР1878ВЕ1 шире, чем у
PIC16, составляют они
16 бит - слово, ну и поскольку архитектура у МК гарвардская, а значит память команд
и данных раздельная, то способен он адресовать
1024 слова или
2048 байт памяти
программ и
256 байт памяти данных.
Из
256 байт памяти данных статическое ОЗУ составляет
128 байт, порты УВВ адресуются
как ячейки памяти данных, и
карта памяти данных имеет следующий вид.
----------
И вот тут начинается самое интересное в этом МК, а именно - способ адресации им памяти данных.
Ясно, что
256 байт памяти данных требуют
8 бит для прямого обращения к любому байту,
а у нас в команде на всё отведено
16 бит.
Решение этой проблемы довольно оригинальное для микроконтроллеров, а именно -
сегментная адресация,
или же её в ряде источников называют
базово-индексной, что мне представляется более правильным,
а вот сравнение этого способа с аналогичным у
микропроцессора 8086 мне кажется не совсем удачным,
хотя, чисто для понимания - сойдет и такая аналогия.
Суть заключается в том, что команды, работающие с двумя операндами построены по следующему
принципу :
KKKK.KKSS.DDDS.SDDD, где:
---------------KKKK.KK - код операции;
---------------SS. -
номер сегментного регистра первого операнда;
---------------DDD - смещение к первому операнду в 8-байтном сегменте;
---------------S.S-
номер сегментного регистра второго операнда;
---------------DDD- смещение ко второму операнду в 8-байтном сегменте.
Из этого следует, что
полный исполнительный или физический адрес при обращении к памяти данных
будет складываться из
5 старших бит, которые заносятся в регистр сегмента. (
В нём они хранятся как
5 младших бит) и
3 бит непосредственного смещения в сегменте, указанного в коде команды.
Сегмент и смещение принято называть
логическим адресом.
Для команды сложения двух операндов -
ADD, к примеру, - эта схема выглядит следующим образом:
-------------0001.00SS.DDDS.SDDD
----------
Собственно,
сегментных регистров у микроконтролера - 4 и их дополняют
4 регистра механизма
косвенной адресации. Носят эти все регистры название
служебных:
Посредством
4-х сегментных регистров микроконтроллеру
одновременно доступно 32 байта из памяти
данных по следующей схеме:
----------
Эмпирическое правило следующее: Базовый адрес, записываемый в сегментный регистр должен
быть кратен восьми, а смещение может быть в пределах 0…7.
В мнемониках ассемблера
КР1878ВЕ1 применяются
следующие обозначения:
служебные регистры
(
SR0–SR7)
используются только для адресации, и в командах обозначаются с префиксом “
#”, как
#0 – #7, причем первые четыре обозначаются еще и буквами
#a, #b, #c, #d.
Обычные числа обозначаются без префикса.
ldr #a, 18h; -
сегментный регистр А указывает на
сегмент памяти данных, где расположены
регистры конфигурации портов А и
В, а также
WDT.
При необходимости (например, обслуживание прерывания) регистры сегментов можно сохранить
в специально отведенный для них стек, и указать их новые значения, при этом остаются
работоспособными все подпрограммы, поскольку смещения в новых сегментах можно не менять!!!
Логические адреса ячеек памяти задаются при программировании контроллера конструкцией:
%<буква><цифра>
Например, запись операнда как
%а5 обозначает ячейку, адрес которой определяется
смещением
на 5 байт в сегменте, определяемом
служебным регистром #А.
(В нашем случае - это
ячейка регистра управления WDT.)
movl %а5, 17h; - в
регистр управления WDT заносим константу
17h, её принято называть "
литерой".
Вот тут немного
неудобный момент:
литера не может быть больше 31h непосредственно в команде,
поскольку под нее отведено те же
5 бит:
S.SDDD .
Если надо больше, то следует использовать косвенную адресацию к ячейке, где литера заранее записана.
И что интересно,
посредством механизма косвенной адресации можно считать байт как из памяти данных,
так и из памяти команд.
Этот механизм поддерживают
4 служебных регистра для косвенной адресации: (
SR4–SR7 которые
буквенных синонимов не имеют), но подробно об этом механизме я расскажу в следующем посте...
PS. Обидно, что сам механизм с номерами регистров сегментов в логическом адресе я не освоил перед
моделированием EDUC-8, он там бы зело пригодился!