Выбрать главу

С учетом этого ограничения для безопасного хранения данных доступны ячейки памяти с адресами $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