; Программа SRAM.asm
; Обращение к внешней памяти
; =================
.INCLUDE "8515def.inc"
; Вставка содержимого файла 6515def.inc в нашу программу
; Файл 8515def.inc не обязательно располагать в директории
; проекта тогда следует указать и путь к нему, например:
;.include "d:\Def_dir\8515def.inc"
.DEF tmp =r16
; Регистру r16 присвоить имя tmp; (значение переменной tmp будет храниться в
; регистре общего назначения r16)
.DEF cnt =r16
; Переменная cnt — счетчик цикла; Замечание: одному регистру в программе могут присваиваться
; разные имена, хотя в данном случае в этом и не было
; необходимости, микроконтроллер имеет 32 регистра, но; переменных в программе обычно гораздо больше
.EQU ArSize =10
; Константа ArSize=10 — используем эту константу
; для определения размера массива, записываемого в память
.EOU aArBgn =$0170
; Используем константу аАгВhn как адрес начальной ячейки; для хранения массива
RESET: IN tmp,HCUCR
; Ввод содержимого регистра MCUCR в регистр tmp. Физические
; адреса регистров MCUCR,ZL,ZH и константы SRE и SRW,
; используемые в программе, определены в файле 8515def.inc
; если по директиве. include файл 8515def.inc не будет найден,
; команды с операндами MCUCR,ZL,ZH,SRE и SRW дадут ошибки
ORI tmp,(1<
; Операция V (логическое ИЛИ) содержимого регистра и константы.
; Для работы с внешней памятью надо установить
; биты SRE и SRW в регистре MCUCR (установка SRW — если
; нужно продлить состояние ожидания; для "медленной" микросхемы памяти).
; Открыв файл 8515def.inc, мы обнаружим, что SRE=7, SRW=6,
; значит величина, которую надо занести; в регистр MCUCR в двоичном коде: 11bb bbbb,
; Ь — это значения битов, которые мы не должны изменять; запись (1< ; единицы, сдвинутой влево SRE (или 7) раз (=1000 0000),
; и единицы, сдвинутой влево SRW (или 6) раз (0100 0000)
; Сумма 1000 0000+0100 0000=1100 0000
; операция V (bbbb bbbb VI100 0000 =11bb bbbb)
; дает нужный результат
OUT MCUCR,tmp;
Вывод содержимого регистра tmp в регистр MCUCR
LDI ZL,low(aArBgn)
LDI ZH,high(aArBgn)
; LDI — операции загрузки в регистр однобайтной константы
; аАгВgn — двухбайтная константа — должна быть загружена
; в пару однобайтных регистров ZH: ZL, которые составляют
; двухбайтный регистр Z. Регистр Z и аналогичные ему двухбайтные
; регистры X и Y используются в операциях с памятью (st,Id….).
; aArBgn=$0170, в ZL загрузится low($0170), т. е., младший байт $70
; в ZH загрузится high($0170), то есть, старший байт $01
; в Z (или в ZH: ZL) образуется двухбайтное слово $01:$70.
; то есть, адрес, выбранный для начальной ячейки массива
LDI cnt,ArSize;
Загрузить в cnt размер массиваNEXT: ST Z+,cnt
; ST — операция записи содержимого регистра cnt в ячейку памяти,
; адрес которой — в регистре Z, знак "+" после Z — значит
; с последующим увеличением адреса в регистре Z на единицу.
; В первом цикле данные занесутся по адресу $0170, a Z = $0171:
; во втором цикле — по адресу $0171, Z = $0172 и т. д.
; в память пишется состояние счетчика циклов
DEC cnt
; Уменьшить содержимое регистра cnt на единицу
NOP
; Команда добавляет один пустой циклNOP
; То жеBRNE NEXT
; Если бит (флаг) Z в регистре состояния процессора SREG
; (не путать бит Z регистра SREG с регистром адреса Z)
; не установлен (не равен) — перейти на команду с меткой NEXT:
; последняя команда, воздействующая на бит Z
; регистра SREG — DEC cnt. Команды N0P введены для
; демонстрации отсутствия их влияния на бит Z
; если вместо них вставить, например, команду INC tmp, влияющую
; на состояние бита Z, работа программы будет нарушена
; Далее — блок считывания данных из памяти:
LDI ZL,low(aArBgn)
LDI ZH.high(aArBgn)
LDI cnt.ArSize
RD_BLK:
LD tmp, Z+
; Здесь какие-то действия с tmp, например,
; передача в компьютер через UART
DEC cnt
BRNE RD_BLK
RJMP RESET
; Перейти на команду с меткой RESET: