Во всех случаях в чтении и записи SRAM используются регистры X, Y и Z — т. е. пары r27:r26, r29:r28 и r31:r30 соответственно, которые по отдельности еще именуют ХН, XL, YH, YL, ZH, ZL в том же порядке (т. е. старшим в каждой паре служит регистр с большим номером). Если обмен данными производится между памятью и другим регистром общего назначения, то достаточно только одной из этих пар (любой), если же между областями памяти — целесообразно задействовать две. Независимо от того, какую из пар мы используем, чтение и запись происходят по идентичным схемам, меняются только имена регистров.

Покажем основной порядок действий при чтении из памяти для регистра Z (r31:r30). Чтение одной ячейки с заданным адресом Address, коррекция ее значения и последующая запись выполняются так:

ldi ZH,High(Address)  ;старший байт адреса RAM

ldi ZL,Low(Address)  ;младший байт адреса RAM

ld temp,Z  ;читаем ячейку в temp

inc temp  ;например, увеличиваем значение на 1

st Z,temp  ;и снова записываем

Заметки на полях

При всех подобных манипуляциях нужно внимательно следить за двумя вещами: во-первых, за тем, чтобы не залезть в несуществующую область памяти (если объем SRAM составляет 512 байт, как в большинстве моделей, которые мы будем использовать, то ZH в данном примере может иметь значения только 0 или 1). Во-вторых, не забыть, что младшие адреса SRAM заняты регистрами (в большинстве моделей под это зарезервированы первые 96 адресов от $00 до $5F). И запись, например, по адресу $0000 (ZH=0, ZL=0) равносильна записи в регистр r0. Во избежание коллизий я по возможности поступаю следующим образом: резервирую пару ZH, ZL только под запись/чтение в память, и устанавливаю с самого начала регистр ZH в единицу. Тогда при любом значении ZL мы будем «шарить» только в старших 256 байтах из 512, чего для любых практических нужд обычно достаточно (а если недостаточно, то, скорее всего, все равно придется задействовать внешнюю память), а случайно пересечься с регистрами нет никакой возможности. Обязательно нужно также помнить, что и последние адреса памяти также нельзя занимать: мы сами дали в начале программы команду задействовать их под стек.

Режимы с преддекрементом и постинкрементом удобны, когда нужно прочесть или записать в память целый фрагмент (эти команды недействительны для большинства МК семейства Tuny). Схема действий аналогичная, только при этом команды выглядят так:

st -Z,temp  ;с преддекрементом, запись в ячейку с адресом Z-1, после выполнения команды Z = Z-1

st Z+,temp  ;с постинкрементом, запись в ячейку с адресом Z, после выполнения команды Z = Z+1

Аналогично выглядят команды чтения:

ld temp, -Z  ;с преддекрементом, чтение из ячейки с адресом Z-1, после выполнения команды Z = Z-1

ld temp,Z+  ;с постинкрементом, чтение из ячейки с адресом Z, после выполнения команды Z = Z+1

Вот как можно в цикле записать 16 ячеек памяти подряд одним и тем же значением из temp, начиная с нулевого адреса старших 256 байтов памяти:

           ldi ZH,1

           clr ZL

LoopW:

           st Z+,temp  ;сложили в память

           cpi ZL,16 ; счетчик до 16

           brne LoopW

Перейти на страницу:

Поиск

Похожие книги