Описание вычисляемого перехода в памяти команд восьмиразрядного микроконтроллера pic12f675
Вычисляемый переход, представляет собой прибавление к младшему регистру счетчику PCL какого-то числа. Например, командой ADDWF PCL. Единственное условие, чтобы значение PCL, не пересекло границу блока памяти (256 значений). Вычисляемый переход обычно используют для обращения к таблицам или массивам данных.
Рассмотрим принцип действия вычисляемого перехода
На рисунке показана организация памяти программ.
РС – 13 разрядный счетчик команд, указывает адрес выбираемой команды.
Состоит из двух регистров PCL и PCH,
РСL доступен пользователю для записи и чтения.
PCH не доступен пользователю. Для обращения к нему используется дополнительный регистр PCLATH.
Вся память разбита на 4 страницы по 2К слова. Каждая страница разбита на блоки памяти. В каждом блоке памяти сохраняется значение PCL (256).
Вектор сброса – адрес 0000h. Сброс приводит к очистке счетчика PCL и установке на адресе 0000h . Также очищается PCLATH, устанавливая нулевую страницу памяти.
Вектор прерывания – адрес 0004h. При возникновении разрешенного прерывания в счетчике команд РС устанавливается адрес 0004h. При этом значение PCLATH не изменяется.
Одна страница (2К) на 8 блоков памяти по 256. Понятно, что значение в PCL это 8- битный регистр и записать в него больше 256 значений невозможно, так как младший байт счетчика команд PCL однобайтный, и может принимать значения в диапазоне от 0 до 255. При его переполнении не происходит приращения старшего байта счетчика команд PCH. Если больше, произойдет ошибка записи в регистр, просто переполнится и начнет новый отсчет с нуля.
Рассмотрим пример 1. Пусть командой addwf PCL нам надо переместиться на метку с адресом 0xFE в нулевом блоке. Значение PCL до этого 0xFA. Следовательно, надо прибавить к PCL число 0x04, пересечения границы блока (переполнение регистра не будет).
А если прибавим число 0x08? Произойдет переполнение регистра PCL (блока памяти). И определится новый ошибочный адрес в нулевом же блоке. Перехода на метку в первый блок не произойдет.
Рассмотрим подпрограмму табличного чтения
Рассмотрим пример 2. где подпрограмма table расположена в памяти программ начиная с адреса 253 (00FDh) (PCH=xxx00000, PCL=11111101). Значение регистра PCLATH равно 0. При чтении первых двух элементов таблицы никаких проблем не возникает, прибавляя 0 к PCL, попадаем на первый элемент таблицы расположенный по адресу 254, прибавляя 1, попадаем на второй элемент по адресу 255. А вот при чтении третьего элемента произойдет переполнение PCL, инкремента PCH не произойдет, в PCH передается значение из регистра PCLATH, в итоге мы попадем на адрес 0 (0000h) (PCH=xxx00000, PCL=00000000) в памяти программ. Чтобы такого не происходило, подпрограмма table не должна пересекать границы блока памяти программ (размер блока 256 слов), она должна располагаться в пределах одного блока, если нет пересечения, то и переполнения PCL не произойдет.
Данное ограничение можно обойти, если следить за переполнением регистра PCL, и своевременно записать правильное значение в регистр PCLATH.
Перед вызовом подпрограммы table, необходимо записать порядковый номер требуемого элемента таблицы в регистр nomer. Здесь функцией ассемблера high, извлекается значение старшего байта адреса метки tab в памяти программ, напомню что, значение старшего байта адреса памяти программ считает регистр PCH, а значение младшего байта соответственно регистр PCL. Адресу метки tab в памяти программ соответствует первый элемент таблицы, а точнее команда retlw 0x0B. Старший байт адреса метки tab заносится в регистр PCLATH для дальнейшего инкремента, если это будет необходимо. Чтобы проверить возможное переполнение регистра PCL
в результате операции сложения (вычисляемый переход), извлекается младший байт адреса метки tab и складывается с порядковым номером элемента таблицы. В случае переполнения, значение регистра PCLATH инкрементируется. Теперь при возникновении переполнения PCL в результате сложения, в регистр PCH передается правильное значение из регистра PCLATH, и мы попадаем на правильный адрес в памяти программ.
Используя данную подпрограмму табличного чтения, можно не заботиться о переполнении PCL и пересечении границ блока памяти программ, подпрограмма может находиться на любом участке памяти программ.
Рассмотрим способы организации вычисляемых переходов.
1. Вычисляемые переходы располагают в нулевом блоке памяти и контролируют невозможность пересечения границы между нулевым и первым блоками. Также размещают вычисляемый переход в начале любого блока, привязывая к адресу PC директивой org.
Это простой, но неудобный метод.
2. Используя операторы High и Lov. При этом не следят за страницей и тем более границей блока страницы. Суть в том, что перед переходом проверяется значение PCL. Если оно больше 255, то к PCLATH прибавляется 1, таким образом выбирается следующий блок страницы.
3. Используя директиву pageselw
Напомню, что эта директива использует W и копирует в PCLATH старший байт счетчика РC (PCH)
