Таблица данных



Таблица данных применяется для задания большого количества констант (чисел) в памяти программ. Например, требуется получить сигнал заданной формы с помощью ШИМ или резистивного ЦАП (R-2R), для этого необходимо загнать в таблицу заранее рассчитанные коэффициенты, и считывать их через определенные промежутки времени, как это сделано в статье про регулировку яркости светодиода. Также таблица данных используется для реализации знакогенератора при выводе символов на жидкокристаллический индикатор (например, дисплей мобильного телефона).

Таблица данных задается с помощью директивы dt (определение таблицы) в памяти программ, при этом табличное чтение организуется в виде отдельной подпрограммы с применением вычисляемого перехода. В простейшем варианте подпрограмма выглядит следующим образом:

После компиляции кода, записи вида dt 0x0B, 0xDC, 0x5D, заменяются на команды возврата, с записью числа в аккумулятор: retlw 0x0B, retlw 0xDC, retlw 0x5D, расположенные последовательно (по адресам) в памяти программ. Чтобы считать из таблицы определенную константу (коэффициент, число), необходимо перед вызовом подпрограммы table записать в аккумулятор W порядковый номер элемента таблицы, содержащий искомую константу. Например, если в аккумуляторе лежит число 0, то после прибавления к регистру PCL (младший байт счетчика команд), мы попадем на первый элемент таблицы, точнее на команду retlw 0x0B, после исполнения которой произойдет выход из подпрограммы с записью числа 0x0B в аккумулятор. Предварительно записав в аккумулятор число 1, мы попадем на второй элемент таблицы, после выхода из подпрограммы в аккумуляторе будет лежать число 0xDC. Всего в одной таблице можно задать 256 констант, так как младший байт счетчика команд PCL однобайтный, и может принимать значения в диапазоне от 0 до 255.

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

Рассмотрим вариант, где подпрограмма 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 не произойдет. Другими словами подпрограмма не должна пересекать следующие адреса в памяти программ: 256 (0100h), 512 (0200h), 768 (0300h), 1024 (0400h), и так далее. Для исключения пересечения можно воспользоваться директивой org для размещения подпрограммы на удобном участке памяти программ.

Данное ограничение можно обойти, если следить за переполнением регистра PCL, и своевременно записать правильное значение в регистр PCLATH. Код подпрограммы в этом случае выглядит следующим образом:

Перед вызовом подпрограммы table, необходимо записать порядковый номер требуемого элемента таблицы в регистр nomer. Здесь функцией ассемблера high, извлекается значение старшего байта адреса метки tab в памяти программ, напомню что, значение старшего байта адреса памяти программ считает регистр PCH, а значение младшего байта соответственно регистр PCL. Адресу метки tab в памяти программ соответствует первый элемент таблицы, а точнее команда retlw 0x0B. Старший байт адреса метки tab заносится в регистр PCLATH для дальнейшего инкремента, если это будет необходимо. Чтобы проверить возможное переполнение регистра PCL в результате операции сложения (вычисляемый переход), извлекается младший байт адреса метки tab и складывается с порядковым номером элемента таблицы. В случае переполнения, значение регистра PCLATH инкрементируется. Теперь при возникновении переполнения PCL в результате сложения, в регистр PCH передается правильное значение из регистра PCLATH, и мы попадаем на правильный адрес в памяти программ.

Используя данную подпрограмму табличного чтения, можно не заботиться о переполнении PCL и пересечении границ блока памяти программ, подпрограмма может находиться на любом участке памяти программ.

Последние записи:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *