С учетом этого ограничения для безопасного хранения данных доступны ячейки памяти с адресами $E060…$FFFE.
Есть более привлекательный вариант распределения памяти: при записи в регистр параллельно производить запись в соответствующую этому регистру ячейку памяти. При этом всегда можно проверить, что именно записывалось в регистр, считав данные из ячейки памяти.
Выберем для регистров следующие адреса:
адрес DD6: 0111 1111 1111 1101 или $7FFD,
адрес DD7: 1011 1111 1111 1110 или $BFFE,
адрес DD6: 1101 1111 1111 1111 или $DFFF.
Теперь для безопасного хранения данных доступны ячейки памяти с адресами $E060…$FFFC, а из ячеек с адресами $FFFD, $FFFE и $FFFF можно считать данные, которые были записаны в регистры DD8, DD7 и DD6 соответственно.
Считывая данные из ячеек, соответствующих регистрам, мы получаем информацию о том, что записывалось в эти регистры. Следовательно, считывание данных правомерно только после первой записи в регистры. Поэтому рекомендую в начале программы записать исходные данные в регистры.
Состояние выходов регистров может не соответствовать считанным из соответствующих ячеек памяти данным
• из-за неисправности регистров;
• из-за возможного соединения выхода регистра с общим проводом во внешнем устройстве.
Создадим новую директорию C: \Avr\Buff\. В AVR Studio создадим новый проект, назовем его Buffers, воспользуемся уже созданной директорией C: \Avr\Buff\, в проекте создадим новый файл BUFSRAM.asm, в котором напишем следующую программу.
; Программа BUF_SRAM.asm
; обращение к внешней памяти, запись данных в буферы
; ========================
.INCLUDE "С: \Avr\Try\8515def.inc”
; Вставка содержимого файла 8515def.inc, находящегося
; в директории C: \Avr\Try в нашу программу
.DEF tmp=r16; Регистру r16 присвоить имя tmp
; (значение переменной tmp будет храниться в
; регистре общего назначения г16)
.DEF cnt = r17; Переменная cnt — счетчик цикла
RESET: IN tmp,MCUCR
; Ввод содержимого регистра MCUCR в регистр tmp
ORI tmp,(1<<SRE)
; Установка бита SRE (режим работы с внешней памятью)
; Бит SRW не устанавливаем; (работа без дополнительного цикла ожидания)
OUT MCUCR,tmp
; Вывод содержимого регистра tmp в регистр MCUCR
;=========ЗАГРУЗКА ДАННЫХ В БУФЕРЫ
.EQU wrBuf1=$7FFD
; Адрес для записи данных в буфер 1 (по схеме — элемент DD6)
.EQU wrBuf2=$BFFE
; Адрес для записи данных в буфер 2 (DD7)
.EQU wrBuf3=$DFFF
; Адрес для записи данных в буфер 3 (DD8)
.EQU rdBuf1=$FFFD
; Адрес для считывания данных из ячейки, соотв. буферу 1
.EQU rdBuf2=$FFFE
; Адрес для считывания данных из ячейки, соотв. буферу 2
.EQU rdBuf3=$FFFF
; Адрес для считывания данных из ячейки, соотв. буферу 3
LDI tmp,$AA; Загрузка константы в tmp
STS wrBuf1, tmp
; Сохранение содержимого регистра tmp в буфере 1
LDI tmp, $55; Загрузка константы в tmp
STS wrBuf2, tmp
LDI tmp,$71; Загрузка константы в tmp
STS wrBuf3, tmp
;======ЧТЕНИЕ / ИЗМЕНЕНИЕ ДАННЫХ В БУФЕРАХ
LDS tmp, rdBuf1
; Передача данных из ячейки с адресом rdBuf1 в регистр tmp
ORI tmp, (1<<7)+(1<<6)+(1<<5)+(1<<4); Установка битов 4.. 7
STS wrBuf1, tmp
; Сохранение содержимого регистра tmp в буфере 1
LDS tmp, rdBuf2
ORI tmp, 0b11110000
; Установка тех же битов, что и для буфера 1,
; только константа представлена в двоичной форме,
; для обозначения двоичной константы 1111 0000; перед ней ставят символы "ноль” и “Ь”
STS wrBuf2, tmp
; Сохранение содержимого регистра tmp в буфере 2
LDS tmp, rdBuf3
ANDI tmp, 0b11110000; сброс тех же битов
STS wrBuf3, tmp
; Сохранение содержимого регистра tmp в буфере 2
; ===== ЗАГРУЗКА В ПАМЯТЬ ПЕРВОГО МАССИВА
.EQU ArSize =10; Размеры массивов
.EQU aArBgn1 =$Е060