Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
sp_avr_2009.doc
Скачиваний:
50
Добавлен:
21.04.2023
Размер:
819.2 Кб
Скачать

3.9. Работа с оперативной памятью данных

Внутренняя оперативная память данных RAM доступна как для чтения, так и для записи. Существуют команды двух типов. Команды типа LD – загрузить регистр из оперативной памяти и команды типа ST – сохранить содержимое регистра в оперативной памяти. То есть доступ к оперативной памяти данных RAM осуществляется через регистры общего назначения.

Пример:

Загрузить константу 01Н в ячейку RAM с адресом 0060Н (младшая ячейка RAM). Будем использовать команду STS (Сохранить непосредственно). В указанной команде явно указан адрес регистра источника и ячейки памяти приемника. В качестве временного регистра используем регистр R16. В данном примере могут быть использованы регистры с номерами с R16 до R31 включительно и любая ячейка памяти, существующая для конкретной модели микроконтроллера.

ldi r16, $01 ; загрузка в регистр R16 константы 01Н

sts $0060, r16 ; сохранение содержимого регистра R16 в ячейке памяти

; RAM с адресом 0060Н

Пример:

Загрузить в регистр R0 содержимое ячейки RAM с адресом 0060Н (младшая ячейка RAM). Будем использовать команду LDS (загрузить непосредственно). В указанной команде явно указан адрес регистра источника и ячейки памяти приемника. В данном примере могут быть использованы регистры с номерами с R0 до R31 включительно и любая ячейка памяти, существующая для конкретной модели микроконтроллера.

lds r0, $0060 ; загрузка в регистр R0 содержимого ячейки памяти RAM

; с адресом 0060Н

Пример:

Скопировать содержимое ячейки RAM с адресом 0060Н в ячейку RAM с адресом 0061Н. Воспользуемся двумя приведенными выше примерами.

lds r0, $0060 ; загрузка в регистр R0 содержимого ячейки памяти RAM

; с адресом 0060Н

sts $0061, r0 ; сохранение содержимого регистра R0 в ячейке памяти

; RAM с адресом 0061Н

Организация массивов во внутренней оперативной памяти данных RAM:

При организации массивов используется косвенная адресация. Адрес ячейки памяти, с которой будет осуществляться обмен данными, находится в регистровой паре. Шестнадцатиразрядный адрес ячейки памяти разбивается на старшую и младшую части. Старшая часть адреса хранится в старшем регистре, а младшая часть – в младшем регистре. Для этого реализованы три регистровые пары: X, Y, Z. Регистровая пара образуется двумя специально выделенными регистрами:

XR27: R26, (R27 – старший, R26 – младший);

YR29: R28, (R29 – старший, R28 – младший);

ZR31: R30, (R31 – старший, R30 – младший).

Рассмотрим команды для операций чтения-записи оперативной памяти RAM с косвенной адресацией. Для указанных выше регистровых пар существует группа команд типа LD и ST. В качестве примера приведем команды для регистровой пары XR27:R26, (R27 – старший, R26 – младший). Знак «+» обозначает операцию «пост инкремент» – увеличение адреса после операции, знак «–» обозначает операцию «пре декремент» – уменьшение адреса до операции.

ld r16, X ; загрузить в регистр R16 содержимое ячейки памяти

; с адресом, хранящимся в регистровой паре X (R27:R26)

ld r16, X+ ; загрузить в регистр R16 содержимое ячейки памяти

; с адресом, хранящимся в регистровой паре X (R27:R26)

; и увеличить содержимое регистровой пары на один

ld r16, -X ; уменьшить содержимое регистровой пары X (R27: R26)

; и загрузить в регистр R16 содержимое ячейки памяти

; с адресом, хранящимся в регистровой паре X (R27:R26)

st X, r16 ; сохранить в ячейке памяти с адресом, хранящимся в

; регистровой паре X (R27:R26), содержимое регистра R16

st X+, r16 ; сохранить в ячейке памяти с адресом, хранящимся в

; регистровой паре X (R27:R26), содержимое регистра R16

; и увеличить содержимое регистровой пары на один

st -X, r16 ; уменьшить содержимое регистровой пары X (R27:R26)

; сохранить в ячейке памяти с адресом, хранящимся в

; регистровой паре X (R27:R26), содержимое регистра R16

Пример: «Заполнение массива константой»:

Пояснение к приведенному ниже примеру: в оперативной памяти данных RAM создается массив из шестнадцати ячеек памяти; количество использованных ячеек памяти задается в регистре R20; начальный адрес массива (базовый адрес) определяется парой регистров R27:R26 (регистровая пара Х). В регистр R16 записывается начальная константа, которая затем на каждом цикле увеличивается на единицу. Таким образом, данный фрагмент программы заполняет оперативную память, начиная с ячейки 0100H константами 0, 1, 2….14, 15.

MASSIV: wdr ; начало программного модуля и сброс сторожевого таймера

ldi r16, $00 ; начальная константа

ldi r27, $01 ; старшая часть базового адреса RAM

ldi r26, $00 ; младшая часть базового адреса RAM

ldi r20, $10 ; счетчик циклов

MASSIV_0: wdr ; начало внутреннего цикла и сброс сторожевого таймера

st X+, r16 ; запомнить содержимое регистра R16 в ячейке RAM,

; адрес которой находится в регистровой паре X(R27: R26)

inc r16 ; увеличить на единицу константу

dec r20 ; уменьшить на единицу счетчик циклов

brne MASSIV_0 ; проверка на ноль (флаг Z) содержимого счетчика циклов

; и переход, если не ноль (флаг Z – сброшен)

nop ; выход из процедуры

Пример: «Копирование одного массива в другой»:

В данном примере производится копирование шестнадцати ячеек памяти RAM, начиная с адреса 0060Н в ячейки с адреса 0100H.

COPY_RAM: wdr ; начало программного модуля и сброс

; сторожевого таймера

ldi r27, $00 ; старшая часть адреса источника (пары Х)

ldi r26, $60 ; младшая часть адреса источника (пары Х)

ldi r29, $01 ; старшая часть адреса приемника (пары Y)

ldi r28, $00 ; младшая часть адреса приемника (пары Y)

ldi r20, $10 ; счетчик циклов

COPY_RAM_0: wdr ; начало внутреннего цикла и сброс

; сторожевого таймера

ld r16, Y+ ; загрузить в регистр R16 содержимое ячейки

; источника RAM, адрес которой находится

; в регистровой; паре Y (R29:R28)

st X+, r16 ; запомнить содержимое регистра R16 в ячейке RAM,

; адрес которой находится в регистровой

; паре X(R27:R26)

dec r20 ; уменьшить на единицу счетчик циклов

brne COPY_RAM_0 ; проверка на ноль (флаг Z) содержимого счетчика

; циклов и переход если не ноль (флаг Z – сброшен)

nop ; выход из процедуры

Использование памяти программ для хранения констант и текстовых сообщений:

Память программ может содержать константы, которые могут являться или числовыми данными, или текстовыми сообщениями. Загружаются эти константы при помощи директив «.db» и «.dw». Подробно они рассмотрены в разделе, посвященном директивам.

В приведенном ниже примере в памяти программ хранится текстовое сообщение “Hello World”. В следующей после текстового сообщения ячейке размещена константа «0», которая обозначает конец сообщения. Программа извлекает из памяти программ символы и выводит их в PORTB. После этого проверяет, есть ли конец сообщения. Если находит «0» (конец сообщения), происходит выход из программы, если не «0», то происходит переход на повтор указанных выше действий.

Пример:

; Приведенный ниже фрагмент программы загружает адрес «сообщения» в

; регистр Z. Умножает адрес слова на 2, чтобы получить адреса байта, и ; использует функции high() и low(), чтобы вычислить старший и младший ; байт адреса

ldi ZH, high(2*message) ; загрузка старшей части адреса байта в ZH

ldi ZL, low(2*message) ; загрузка старшей части адреса байта в ZH

LOAD_BYTE: wdr ; метка начала цикла и сброс сторожевого таймера

lpm ; загрузка байта из памяти программ в регистр R0

tst r0 ; проверка, достигли ли мы конца сообщения

breq quit ; если ноль, то выход из процедуры

out PORTB, r0 ; вывод в PORTB символа

adiw ZL,1 ; инкремент адреса ячеек памяти программ,

; где хранятся сообщения

rjmp LOAD_BYTE

quit: rjmp quit ; бесконечный цикл (конец процедуры)

message: ; метка начала сообщения

.dbHello World” ; текст сообщения

.db 0 ; константа «0» (конец сообщения)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]