Найти в Дзене
Разумный мир

Микроконтроллеры для начинающих Часть 11. Процессор и память в PIC

В предыдущей статье цикла я рассмотрел подробности организации памяти, включая регистры процессора, для STM8 "Микроконтроллеры для начинающих. Часть 9. Процессор и память в STM8". Правда потом пришлось написать внеплановую статью "Микроконтроллеры для начинающих. Часть 10. RISC и CISC - единство и борьба противоположностей", без которой описать особенности архитектуры 8-битных PIC Microchip было бы сложнее. Дело в том, что PIC яркие представители RISC идеологии. И многие особенности, которые в них есть, продиктованы именно этим. Примерно год назад я написал большую статью "Организация памяти 8 битных микроконтроллеров Microchip PIC", где вопросы организации памяти рассмотрел очень подробно. Однако, она трудна для восприятия новичками. Сегодняшняя статья ориентирована именно на новичков, поэтому некоторые моменты будут рассмотрены немного упрощенно и более подробно. Да, это первая сложность с которой нам сегодня предстоит столкнуться в и без того запутанной (на первый взгляд!) архитект
Оглавление

В предыдущей статье цикла я рассмотрел подробности организации памяти, включая регистры процессора, для STM8 "Микроконтроллеры для начинающих. Часть 9. Процессор и память в STM8". Правда потом пришлось написать внеплановую статью "Микроконтроллеры для начинающих. Часть 10. RISC и CISC - единство и борьба противоположностей", без которой описать особенности архитектуры 8-битных PIC Microchip было бы сложнее.

Дело в том, что PIC яркие представители RISC идеологии. И многие особенности, которые в них есть, продиктованы именно этим.

Примерно год назад я написал большую статью "Организация памяти 8 битных микроконтроллеров Microchip PIC", где вопросы организации памяти рассмотрел очень подробно. Однако, она трудна для восприятия новичками. Сегодняшняя статья ориентирована именно на новичков, поэтому некоторые моменты будут рассмотрены немного упрощенно и более подробно.

8-разрядные PIC Microchip бывают разные

Да, это первая сложность с которой нам сегодня предстоит столкнуться в и без того запутанной (на первый взгляд!) архитектуре PIC. STM8 тоже бываю разные, как я уже упоминал в 9 части цикла, но PIC могут буквально сбить с толку впервые столкнувшихся с ними. Однако, не все так страшно! И логичности в этих микроконтроллерах не меньше, чем в прочих. Сейчас сами все увидите.

Прежде всего, 8-разрядные PIC делятся не несколько основных линеек (я буду рассматривать только контроллеры с Flash памятью):

  • BaseLine. Самые простые микроконтроллеры. Длина команды составляет лишь 12 разрядов. Аппаратный стек имеет только два уровня, но о стеке поговорим позже. И доступны всего 33 команды. Прерывания отсутствуют.
  • Enhanced BaseLine. Немного улучшенная версия BaseLine. Появились прерывания, а стек получил 4 уровня. Всего 36 команд. В реальности вы вряд ли столкнетесь с этими микроконтроллерами.
  • MidRange. Как следует из названия, это микроконтроллеры среднего уровня. Длина команды 14 разрядов. Аппаратный стек имеет 8 уровней. Доступны 35 команд. Одноуровневые прерывания. Одна из самых доступных и распространенных для любителей линеек.
  • Enhanced Mid-range. Немного улучшенная версия MidRange. Аппаратный стек получил 16 уровней. Всего доступно 49 команд. Одна из самых доступных и распространенных среди любителей линеек. Причем Microchip усиленно пытается перевести всех с более простых микроконтроллеров именно на эту линейку (если не считать PIC18).
  • PIC18. Самая продвинутая линейка 8-битных микроконтроллеров. Длина команды 16 бит. Аппаратный стек имеет 31 уровень. Доступно 75 базовых команд, но некоторые модели поддерживают и дополнительные команды. Два уровня прерываний.

Из маркировки микросхемы бывает трудно определить, к какой линейке она относится. Условно, можно считать, что PIC10Fxxxх это BaseLine (пока Microchip не выпустила PIC10F322, который относится к MidRange). PIC12Fxxxx могут быть и BaseLine, и MidRange. PIC16Fxxxx могут быть MidRange и Enhanced Mid-range. С PIC18 все и так ясно.

Однако, часто указывают и другие обозначения в статьях и каталогах, по длине команды ядра. С этой точки зрения PIC12 это BaseLine и Enhanced BaseLine, PIC14 это MidRange и Enhanced MidRange, PIC16 это PIC18.

Зачем я об это рассказываю именно сейчас? Дело в том, что нам сегодня это все понадобится.

Общие замечания по архитектуре PIC

Это ярко выраженная Гарвардская и RISC архитектура. Здесь память программ и память данных очень четко разделены, хотя иногда и есть возможность прочитать память команд как данные. Причем в отдельное адресное пространство вынесен и стек, который не просто является аппаратным, но часто и недоступным в явном виде.

Адресное пространство ввода-вывода отсутствует полностью. Более того, регистры процессора не выделены (в большинстве случаев) как отдельная сущность, а располагаются в адресном пространстве памяти данных.

А еще, все это поделено на страницы и банки памяти. Напугал и запутал? Сейчас увидите, что это страшно звучит, на на самом деле все просто и логично.

Регистры процессора

Да, они не выделены в отдельную сущность, но все таки они существуют. Давайте познакомимся с некоторыми из них.

Счетчик команд PC

Бывает разной разрядности.

  • Для BaseLine адрес команды может составлять от 9 до 12 (для Enhanced BaseLine) разрядов.
  • Для MidRange от 13 разрядный, или 15 разрядный (для Enhanced MidRange)
  • Для PIC18 длина адреса команды составляет 21 бит.

Разумеется, это влияет на максимальный объем памяти программ. Младший байт регистра называется PCL и доступен программно. В том числе, для выполнения арифметических и логических операций. Старший байт называется PCH и напрямую из программы не доступен. Для PIC18 кроме PCL и PCH есть еще и PCU, который хранит самые старшие разряды адреса. И он тоже на доступен напрямую.

Запись в регистры PCH и PCU возможна только через регистры PCLATH и PCLATU. Причем прочитать PCH можно тоже только через PCLATH, и только для PIC18. Аналогично и для PCU, который есть только в PIC18. Обратите внимание, в BaseLine нет регистра PCLATH!

Как именно используются эти регистры я расскажу при описании режимов адресации. Пока просто запомним, что адреса в адресном пространстве данных имеют регистры PCL, PCLATH и PCLATU (только для PIC18).

Указатель стека и связанные с ним регистры

Сам регистр указателя стека конечно имеется во всех микроконтроллерах. Но вот доступен он только в Enhanced MidRange и PIC18 и называется STKPTR. Адрес возврата (содержимое ячейки памяти на вершине стека), на который указывает STKPTR не доступен напрямую, а хранится в регистрах TOSL, TOSH и TOSU (только для PIC18).

Регистр флагов состояния STATUS

Соответствует регистру FLAGS, который я ранее неоднократно упоминал. Хранит флаги переноса, нулевого результата, переноса между тетрадами и два дополнительных флага связанные с тайм-аутами различными видами сбросов. Сегодня я не буду обсуждать эти флаги.

Рабочий регистр WREG

Соответствует аккумулятору в других архитектурах. Полностью аналогичен ему по функционалу. Однако, есть интересная особенность, что результат операции может помещаться или обратно в ячейку памяти, или в этот рабочий регистр. И определяется это специальным битом в коде команды. Но это будет обсуждаться при рассмотрении системы команд.

Индексный регистр, или регистр, которого нет

Да, этого регистра физически не существует. Существует только его адрес. Называется этот регистр INDF. При его указании в качестве операнда команды используется косвенная адресация, о которой я расскажу чуть позднее. Но поскольку этого регистра нет, то адрес памяти на самом деле берется из регистра FSR.

Причем для Enhanced MidRange и PIC18 регистр FSR состоит из двух частей, FSRL и FSRH.

Кстати, в Enhanced MidRange есть не один, а два индексных регистра, INDF0 и INDF1. Соответственно есть и две пары регистров FSR - FSR0H:FSR0L и FSR1H:FSR1L. А в PIC18 к ним добавились еще и INDF2 и FSR2H:FSR2L

Стек и адресация стека

Организацию памяти начну рассматривать со стека, как самой простой части. В PIC стек не просто аппаратный, он вынесен в отдельное адресное пространство и предназначен только для хранения адресов возврата из подпрограмм и прерываний (если они есть).

Как я уже говорил, размер стека очень мал, от 2 ячеек до 31. И именно по той причине, что он не предназначен для использования программистом напрямую. Получить хоть какой то доступ к аппаратному стеку можно только в Enhanced MidRange и PIC18.

Упрощенная схема доступа к аппаратному стеку для Enhanced MidRange и PIC18. Иллюстрация моя
Упрощенная схема доступа к аппаратному стеку для Enhanced MidRange и PIC18. Иллюстрация моя

В регистре STKPTR используются не все разряды, так как стек имеет малый размер. Для Enhanced MidRange используются 4 младших разряда, а для PIC18 5 младших разрядов. Вы можете изменять содержимое STKPTR для получения доступа к другим ячейкам в стеке. Но помните, что стек аппаратный, поэтом обязательно запрещайте прерывания на время ручного доступа к стеку! И не забывайте восстанавливать STKPTR иначе последствия будут разрушительными.

Поскольку стек хранит только адреса возврата размер его ячеек в точности равен разрядности регистра PC. Поэтому и регистр TOS состоит из нескольких байт, как и регистр PC.

На иллюстрации я показал чтение содержимого стека, так как данные копируются в TOS. Но верно и обратное, то есть, все, что вы записываете в TOS (TOSU:TOSH или TOSU:TOSH:TOSL) на самом деле записывается в стек.

Другими словами, TOS это собственно и есть ячейка памяти стека, номер которой хранится в STKPTR.

Специальные команды для работы со стеком (PUSH, POP) есть только в PIC18. Во всех остальных случаях со стеком работают только команды вызова процедур, возврата из процедур, возврата из прерывания.

Память программ и адресация памяти команд

Память программ поделена на страницы, за исключением PIC18 где она представлена непрерывным блоком. Причем единицей информации для памяти программ является не байт, а слово (12 или 14 бит). Опять таки, за исключением PIC18, где адресация побайтная. Поскольку для PIC18 команда может занимать 2 или 4 байта младший разряд регистра PC (младший разряд PCL) всегда равен 0. То есть, адрес в памяти команд PIC18 выровнен на границу двух байт.

BaseLine

Страница памяти программ для BaseLine состоит из 512 слов по 12 бит. Максимально может быть 8 таких страниц. Регистр PC хранит полный адрес команды и автоматически увеличивается на 1 после выполнения команды. Для него не существует границ страниц. Однако, считается, что его три старших разряда и являются номером страницы.

А вот в командах передачи управления адрес формируется из номера страницы и адреса слова внутри страницы. Обратите внимание, в BaseLine нет регистра PCLATH!

Собственно номер страницы хранится в трех старших разрядах регистра STATUS. То есть, этот регистр несет не только информационную функцию, но и управляющую.

Адрес команды внутри страницы хранится в коде команды перехода. Но тут все не так просто. В инструкции перехода GOTO поместился полный адрес команды внутри страницы (9 бит), а вот в инструкции CALL только 8 младших бит. Таким образом, адреса начала всех подпрограмм должны размещаться только в первой (младшей) половине каждой страницы!

Упрощенная схема адресации в памяти программ для BaseLine. Иллюстрация моя
Упрощенная схема адресации в памяти программ для BaseLine. Иллюстрация моя

Однако, переход может быть выполнен не только специальными командами, но и прямым использованием PCL а операциях. В этом 9 разряд адреса (бит 8 PC) получает значение 0, как и в случае команды CALL.

MidRange

Память программ организована аналогичным BaseLine образом, только размер страницы стал равен 2048 слов по 14 бит каждое. Всего может быть 4 страницы. Точно так же, для регистра PC не существует границ страниц. Однако, считается, что его старшие два разряда и являются номером страницы.

Организация памяти программ MidRange. Иллюстрация моя
Организация памяти программ MidRange. Иллюстрация моя

А вот схема адресации в командах передачи управления несколько изменилась. Регистр STATUS более не используется для хранения номера страницы. Теперь номер страницы памяти программ, а фактически, старшие биты адреса команды, хранятся в специальном регистре PCLATH.

Однако, не всегда используются все биты PCLATH, так для команд передачи управления нужны только биты 3 и 4.

Адресация памяти программ MidRange в командах передачи управления. Иллюстрация моя
Адресация памяти программ MidRange в командах передачи управления. Иллюстрация моя

Здесь уже нет "ограничения в правах" для команды CALL. Точно так же, можно напрямую изменять содержимое PCL, что будет фактически соответствовать выполнению перехода. Однако, в этом случае результат операции будет только 8 битным, поэтому потребуются уже все разряды PCLATH

Формирование адреса команды для MidRange при изменении содержимого PCL. Иллюстрация моя
Формирование адреса команды для MidRange при изменении содержимого PCL. Иллюстрация моя

Enhanced MidRange

В целом здесь все аналогично MidRange, только PC стал 15 битным. Размер страницы не изменился, 2048 слов по 14 бит. Но страниц может быть до 16. Для PC границы страниц отсутствуют, но считается, что номер страницы задаю старшие 4 разряда PC.

Я не буду рисовать отдельную иллюстрацию, так как принципиальных отличий от MidRange просто нет. В регистре PCLATH теперь используются биты с 0 по 6, а не с 0 по 4, как для MidRange. В командах перехода теперь используются биты с 3 по 6 (4 бита) PCLATH. А при переходах использующих прямое изменение PCL, как и для MidRange, все биты PCLATH (c 0 по 6).

Однако, здесь появилось три новых команды. Две команды условного перехода (BRA и BRW) которые используют относительную адресацию, и команда CALLW, адрес перехода в которй содержится в WREG. И вот тут я приведу иллюстрации

Формирование адреса перехода для команды CALLW MidRange. Иллюстрация моя
Формирование адреса перехода для команды CALLW MidRange. Иллюстрация моя

Как видите, тут все просто и очень похоже на ситуацию с прямым изменением PCL. А вот в командах BRA и BRW регистр PCLATH участия не принимает.

Формирование адреса перехода командой BRW Enhanced MidRange. Иллюстрация моя
Формирование адреса перехода командой BRW Enhanced MidRange. Иллюстрация моя

Хорошо видно, что это действительно относительная адресация. К содержимому PC прибавляется содержимое WREG (со знаком), а получившися результат и становится новым значением PC.

Формирование адреса перехода командой BRA Enhanced MidRange. Иллюстрация моя
Формирование адреса перехода командой BRA Enhanced MidRange. Иллюстрация моя

Для команды BRA все очень похоже, только смещение адреса берется из кода команды. И теперь это не 8, а 9 бит.

PIC18

Тут все гораздо проще. Теперь у нас нет страниц и все адресное пространство памяти программ линейное. Длина адреса 21 бит. Регистр PC адресует память программ побайтно, однако, фактически память выделяется словами по 2 байта. Поэтому младший бит PC всегда равен 0.

Кстати, это означает, что переход к следующей команде существляется увеличением PC (PCL) на 2 или 4, а не на 1, как это было в младших семействах. И это часто сбивает начинающих программистов привыкших к командам вроде GOTO $+1 для задержки на 2 машинных цикла.

В команад передачи управления теперь задается полный адрес, а не его часть. Однако, новичков тут ожидает небольшой сюрприз. Дело в том, что в коде команды хранится не 21 бит адреса перехода, а только 20. Куда делся еще один бит? А вы забыли, что младший бит адреса команды всегда нулевой и его просто не требуется хранить!

Дополнительные иллюстрации приводить не буду, так как тут все очень просто. Команда относительного перехода BRA теперь содержит в коде команды 11 бит смещения, что соответствует 12 фактическим битам (помните, что нулевой бит PC всегда 0?). А команды условного перехода содержат 8 бит смещения в коде команды.

Память данных

А вот тут все немного сложнее... Память данных разбита на банки абсолютно во всех линейках (семействах).

  • BaseLine. Банки памяти имеют размер 32 байта. Всего может быть до 8 банков.
  • MidRange. Банки памяти имеют размер 128 байт. Всего может быть до 4 банков
  • Enhanced MidRange. Аналогично MidRange, но может быть до 32 банков памяти. Однако тут появляется возможность линейной адресации памяти.
  • PIC18. Банки памяти имеют размер 256 байт. Всего может быть до 16 банков.

Вы можете сказать, что это очень похоже на память программ и мы это уже проходили. Что тут сложного то? Сейчас увидите.

Дело в том, что память программ содержит не только собственно ячейки памяти данных. Здесь находятся и регистры процессора, и регистры устройств ввода-вывода. Все вместе это называется регистровым файлом.

Регистры процессора и внешних устройств называются регистрами специальных функций - SFR. А обычные ячейки памяти данных регистрами общего назначения - GPR.

И это привело такое смешанное размещение вот к чему

Структура банка памяти для микроконтроллеров отличных от PIC18

Каждый банк памяти данных разбит на две части. В младших адресах памяти банка располагаются SFR. Причем их количество может быть различным, в зависимости от конкретного микроконтроллера. Старшую часть адресов банка памяти занимают GPR. Причем там тоже есть деление, но об этом позже.

Другими словами все выглядит, в первом приближении, так

Первый упрощенный взгляд на структуру банка памяти данных. Иллюстрация моя
Первый упрощенный взгляд на структуру банка памяти данных. Иллюстрация моя

Таким образом, ячейки памяти программ у нас располагались последовательно, хоть и постранично. А вот ячейки памяти данных расположены вперемешку со служебными регистрами оборудования.

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

Где же проходит граница между SFR и GPR? В общем и целом, все определяется конкретным микроконтроллером. Причем в разных банках границы могут располагаться в разных местах. При ручном размещении переменных, вне зависимости от выбранного языка программирования, мы должны внимательно смотреть в документацию на микроконтроллер. При автоматическом размещении (так умеет делать, например XC8). компилятор возьмет этот труд на себя.

А где какой SFR располагается? Для BaseLine и MidRange тут нет никакой системы. Причем некоторые регистры могут быть доступны в нескольких банках памяти, а некоторые только в каком то одном. И они не обязаны располагаться последовательно, между ними могут быть свободные участки. Причем эти свободные участки нельзя использовать как GPR.

В Enhanced MidRange расположение SFR несколько упорядочили. Здесь есть несколько регистров доступных в любом банке памяти. Они называются Core Registers и я не буду их перечислять, нам сейчас это не важно. Нам важно только то, что таких регистров 12. При этом область GPR стала всегда начинаться с адреса 20h внутри банка.

Упрощенная структура банка памяти Enhanced MidRange. Иллюстрация моя
Упрощенная структура банка памяти Enhanced MidRange. Иллюстрация моя

Жить стало немного легче, но это еще не все. Дело в том, что часть GPR тоже может быть доступна по адресу любого, или нескольких, банков памяти. Это называется внебанковая, или разделяемая, память.

В результате, мы можем получить такую картину

Организация памяти данных микроконтроллера PIC16F886 (MidRange). Фрагмент из документации на микроконтроллер
Организация памяти данных микроконтроллера PIC16F886 (MidRange). Фрагмент из документации на микроконтроллер

И это еще не самый тяжелый случай... Давайте попробуем тут разобраться.

Во первых, тут видно 6 областей GPR. Первый начинается с адреса 20h внутри банка 0 и предоставляет 96 ячеек. Еще три блока начинаются с адресов 20h внутри банков 1-3, но предоставляют только по 80 ячеек. И два блока начинаются с адресов 10h внутри банков 2 и 4 и предоставляют по 16 ячеек. Сколько всего ячеек простых GPR у нас доступно?

Думаете все так просто? Думаете 368 ячеек? А вот и нет! Обычных ячеек памяти (GPR) будет только 352! Дело в том, что здесь есть еще разделяемая память, на рисунке обозначенная как accesses. И во всех банках, начиная с 1, эти ячейки те же самые, что в банке 0 (диапазон адресов с 70h по 7Fh).

Получается, что из 368 ячеек памяти данных, и в документации указано именно это число, у нас 352 ячейки доступны каждая в своем банке (банковая память) и еще 16 доступны по адресу любого банка (разделяемая память).

Думаете теперь вам все понятно? Тогда вот, в качесвте упражнения, организацияч памяти данных в PIC16F72

Организация памяти данных PIC16F72 (MidRange). Фрагмент из документации.
Организация памяти данных PIC16F72 (MidRange). Фрагмент из документации.

Только попробуйте сначала честно разобраться самомстоятельно. И уже потом, если будет совсем тяжело, загляните в указанную мной в самом начале статью, где я дал ответ на этот вопрос.

Однако в Enhanced MidRange и тут пришло немного облегчения. Область GPR банков памяти тоже подверглась стандартизации.

Общая структура банка памяти Enhanced MidRange. Иллюстрация моя
Общая структура банка памяти Enhanced MidRange. Иллюстрация моя

Shared memory еще называют common memory.

Общая структура памяти данных и адресация памяти данных для микроконтроллеров отличных от PIC18

Теперь мы, разобравшись с форматом банков памяти, готовы взглянуть на картину организации памяти данных в целом.

Обобщенное упрошщенное преставление общей организации памяти данных для микроконтроллеров отличных от PIC18. Иллюстрация моя
Обобщенное упрошщенное преставление общей организации памяти данных для микроконтроллеров отличных от PIC18. Иллюстрация моя

Здесь я не стал уделять внимание содержимому банков памяти, с этим мы уже разобрались. И не стал, пока, делать различия между разными линейками микроконтроллеров. Дело в том, что общий принцип будет почти одинаковым, разными будут лишь детали, которые я покажу чуть позднее.

Итак, полный адрес в памяти данных у нас состоит из двух частей - номер банка и адрес в банке. И это общий принцип. А вот детали действительно отличаются, да еще и от режима адресации зависят.

Адресация памяти данных BaseLine

Как я уже говорил, размер банка памяти в BaseLine равен 32 байтам. А значит, для адресации внутри банка достаточно 5 бит адреса. И в случае прямой адресации этот адрес располагается прямо в коде команды. А вот номер банка располагается в старших байтах регистра FSR.

Однако, если ьыть более точным, регистр FSR содержит полный адрес памяти данных, включая номер банка. Просто при прямой адресации используются только 3 старщих разряда, содержащих собственно номер банка.

При косвенной адресации используются все разряды FSR. Но вот в качестве операнда в команде в этом случае указывается несуществующий регистр INDF.

Прямая адресация BaseLine. Иллюстрация моя
Прямая адресация BaseLine. Иллюстрация моя

Косвенная адресация BaseLine. Иллюстрация моя.
Косвенная адресация BaseLine. Иллюстрация моя.

Как видите, все довольно просто. Я специально показал обращение к ячейке с одним и тем же адресом.

Адресация памяти данных MidRange

Тут все будет похоже, но немного запутаннее. Здесь на сцене снова появляется регистр STATUS, который содержит два бита номера банка для прямой адресации (RP0 и RP1) и один бит номера банка для косвенной адресации (IRP).

При прямой адресации адрес байта в банке точно так же будет браться из кода команды. А вот для косвенной регистр FSR будет содержать адрес байта в банке и один бит номера банка.

Прямая адресация MidRange. Иллюстрация моя
Прямая адресация MidRange. Иллюстрация моя
Косвенная адресация MidRange. Иллюстрация моя
Косвенная адресация MidRange. Иллюстрация моя

Как видно, действительно очень похоже на BaseLine, только номер банка немного по другому задается. Несколько нелогично использование регистра STATUS.

Адресация памяти данных Enhanced MidRange

И опять ситуация немного улучшилась. Самое главное, теперь для указания номера банка у нас не нужно использовать регистр STATUS. Теперь номер банка при прямой адресации хранится в регистре BSR, в 5 его младших разрядах. Что и дает возможность использовать до 32 банков памяти

Прямая адресация Enhanced MidRange. Иллюстрация моя
Прямая адресация Enhanced MidRange. Иллюстрация моя

Для косвенной адресации регистр FSR расширили до регистровой пары FSRH:FSRL. А это позволило помещать в него полный адрес памяти данных. Младшие 7 (с 0 по 6) разрядов FSR (FSRL) хранят адрес байта в банке, а следующие 5 разрядов, с 7 по 11 (7 разряд FSRL и разряды с 0 по 3 FSRH) хранят номер банка

Косвенная адресация Enhanced MidRange. Иллюстрация моя
Косвенная адресация Enhanced MidRange. Иллюстрация моя

Не правда ли, очень похоже на косвенную адресацию для BaseLine? Только FSR имеет больше разрядов. На самом деле такое расширение разрядности FSR чрезвычайно важно. Я уже говорил, что теперь туда помещается полный адрес памяти данных, а значит, банки памяти не нужны. Мы получили линейное пространство данных!

Да, только вот SFR там мешаются... И эту проблему решили введя специальный диапазон адресов! Если мы будем указывать адрес памяти в диапазоне от 2000h до 29AFh, то мы получим линейный доступ к совокупности всех блоков GPR по 80 байт из всех банков.

Линейное адресное пространство данных Enhanced MidRange. Вырезка из документации на PIC16F18323
Линейное адресное пространство данных Enhanced MidRange. Вырезка из документации на PIC16F18323

Да, здесь нет банка 31, но зато есть остальные 31 банк и нет SFR. Более того, таким образом можно получить доступ (только на чтение!) к памяти программ, если использовать адреса начиная с 8000h по 7FFFh. Модно будет читать только младшие 8 бит кода команды. А с адреса F000h начинается EEPROM, если она есть.

Структура памяти и адресация памяти PIC18

Пора переходить к старшей линейке 8-разрядных микроконтроллеров PIC. Тут все и проще, и сложнее одновременно. Проще, так как банки памяти не содержат SFR. Всего есть 16 банков по 256 байт каждый. Теперь SFR у нас расположены в самом конце памяти данных, причем в направлении от старших адресов к младшим. То есть, SFR расположены в банке 15. Они могут занять и часть банка, и банк целиком. Поэтому найдите в документации на свой микроконтроллер нижнюю границу адреса.

В остальном, адресация полностью похожа на таковую в Enhanced MidRange, даже разрядность регистров такая же. За исключением регистров BSR, где на один разряд меньше, так как банков только 16, а не 32. Поэтому дополнительных иллюстраций приводить не буду

То есть, у нас адресное пространство данных фактически линейное, если использовать косвенную адресацию. Но вот возможности собрать воедино и память программ, и EEPROM уже нет. Немного жаль.

Зато существует специальный виртуальный банк, который называется Access Bank. В нем собраны воедино 96 первых байт банка 0 и последние 160 байт банка 15. То есть, это некий аналог разделяемой памяти с добавление части SFR. И в коде команды (некоторых команд) можно указать, использовать ли стандартные банки памяти, или этот специальный банк.

Возможность перемещения базового адреса отображаемой на младшие 96 байт Access Bank памяти, которая существует в режиме работы с расширенным набором инструкция, а так же индексную адресацию со смещением я в данной статье описывать не буду. Это уже будет не "для начинающих". Тех, кто заинтересовался просто отправлю к своей статье "Организация памяти 8 битных микроконтроллеров Microchip PIC", которую уже упоминал.

Кроме того, в PIC18 есть адресация с автоинкрементом и автодекрементом. Реализовано это через виртуальные регистры POSTDEC, POSTINC, PREINC и PLUSW, которые существуют в дополнение к FSR и INDF. При указании их в качестве операндов команд и реализуются автоинкремент и автодекремент. Подробнее тоже в моей статье, ссылка на которую приведена выше.

Заключение

На сегодня точно хватит! Мы рассмотрели пожалуй самые сложные в плане организации памяти микроконтроллеры. Но они и самые интересные и нравятся мне (лично мне) больше всего. Некоторые моменты я опустил при описании, осознанно, что бы совсем вас не запутать. Если нужно пояснения, задавайте вопросы в комментариях.

Непосредственная адресация, которая в данном случае называется литеральной, тоже есть, но реализована специальными командами.

В следующей статье рассмотрим архитектуру памяти AVR, там будет гораздо проще.

До новых встреч!