; Программа 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: