Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

Команды пересылки данных

Табл 2. Команды пересылки данных:

Команда

Описание

Действие

Циклы

Код операции

Флаги

ATtiny

ATmega

mov   Rd,Rr

Move Between Registers

Rd←Rr

1

0010 11rd dddd rrrr

None

+

+

movw  Rd,Rr

Copy Register Word

Rd+1:Rd←Rr+1:Rr

1

0000 0001 dddd rrrr

None

±

+

ldi   Rd,K

Load Immediate

Rd←K

1

1110 KKKK dddd KKKK

None

+

+

ld   Rd,X

Load Indirect

Rd←(X)

2

1001 000d dddd 1100

None 

 ±

+

ld   Rd,X+

Load Indirect and
Post-Inc.

Rd←(X), X←X+1

2

1001 000d dddd 1101

None

±

+

ld   Rd,-X

Load Indirect and
Pre-Dec.

X←X-1, Rd←(X)

2

1001 000d dddd 1110

None

±

+

ld   Rd,Y

Load Indirect

Rd←(Y)

2

1000 000d dddd 1000

None 

 ±

+

ld   Rd,Y+

Load Indirect and
Post-Inc.

Rd←(Y), Y←Y+1

2

1001 000d dddd 1001

None

±

+

ld   Rd,-Y

Load Indirect and
Pre-Dec.

Y←Y-1, Rd←(Y)

2

1001 000d dddd 1010

None

±

+

ldd   Rd,Y+q

Load Indirect with Displacement

Rd←(Y+q)

2

10q0 qq0d dddd 1qqq

None

±

+

ld   Rd,Z

Load Indirect

Rd←(Z)

2

1000 000d dddd 0000

None 

 +

+

ld   Rd,Z+

Load Indirect and
Post-Inc.

Rd←(Z), Z←Z+1

2

1001 000d dddd 0001

None

±

+

ld   Rd,-Z

Load Indirect and
Pre-Dec.

Z←Z-1, Rd←(Z)

2

1001 000d dddd 0010

None

±

+

ldd   Rd,Z+q

Load Indirect with Displacement

Rd←(Z+q)

2

10q0 qq0d dddd 0qqq

None

±

+

lds   Rd,k

Load Direct from SRAM

Rd←(k)

2

1001 000d dddd 0000
kkkk kkkk kkkk kkkk

None

±

+

st   X,Rr

Store Indirect

(X)←Rr

2

1001 001r rrrr 1100

None

±

+

st   X+,Rr

Store Indirect and
Post-Inc.

(X)←Rr, X←X+1

2

1001 001r rrrr 1101

None

±

+

st   -X,Rr

Store Indirect and
Pre-Dec.

X←X-1, (X)←Rr

2

1001 001r rrrr 1110

None

±

+

st    Y,Rr

Store Indirect

(Y)←Rr

2

1000 001r rrrr 1000

None

±

+

st   Y+,Rr

Store Indirect and
Post-Inc.

(Y)←Rr, Y←Y+1

2

1001 001r rrrr 1001

None

±

+

st   -Y,Rr

Store Indirect and
Pre-Dec.

Y←Y-1, (Y)←Rr

2

1001 001r rrrr 1010

None

±

+

std   Y+q,Rr

Store Indirect with Displacement

(Y+q)← Rr

2

10q0 qq1r rrrr 1qqq

None

±

+

st   Z,Rr

Store Indirect

(Z)←Rr

2

1000 001r rrrr 0000

None

+

+

st   Z+,Rr

Store Indirect and
Post-Inc.

(Z)←Rr, Z←Z+1

2

1001 001r rrrr 0001

None

±

+

st   -Z,Rr

Store Indirect and
Pre-Dec.

Z←Z-1, (Z)←Rr

2

1001 001r rrrr 0010

None

±

+

std   Z+q,Rr

Store Indirect with Displacement

(Z+q)← Rr

2

10q0 qq1r rrrr 0qqq

None

±

+

sts   k,Rr

Store Direct to SRAM

(k)←Rr

2

1001 001r rrrr 0000
kkkk kkkk kkkk kkkk

None

±

+

lpm

Load Program Memory

R0←(Z)

3

1001 0101 1100 1000

None

+

+

lpm   Rd,Z

Load Program Memory

Rd←(Z)

3

1001 000d dddd 0100

None

±

+

lpm   Rd,Z+

Load Program Memory
and  Post-Inc.

Rd←(Z), Z←Z+1

3

1001 000d dddd 0101

None

±

+

elpm

Extended Load
Program Memory

R0←(RAMPZ:Z)

3

1001 0101 1101 1000

None

-

±

elpm  Rd,Z

Extended Load
Program Memory

Rd←(RAMPZ:Z)

3

1001 000d dddd 0110

None

-

±

elpm  Rd,Z+

Extended Load Program Memory and Post-Inc.

Rd←(RAMPZ:Z),
(RAMPZ:Z)←
←(RAMPZ:Z)+1

3

1001 000d dddd 0111

None

-

±

spm

 

Store Program Memory

(Z)←R1:R0

-

1001 0101 1110 1000

None

±

+

in   Rd,P

In Port

Rd←P

1

1011 0PPd dddd PPPP

None

+

+

out   P,Rr

Out Port

P←Rr

1

1011 1PPr rrrr PPPP

None

+

+

push  Rr

Push Register in Stack

STACK←Rr, SP←SP-1

2

1001 001r rrrr 1111

None

±

+

pop   Rd

Pop Register from Stack

SP←SP+1, Rd←STACK

2

1001 000d dddd 1111

None

±

+

Группа команд пересылки данных сведена в табл.2. Под определением пересылки (перемещения) в данном случае понимается копирование содержимого источника без его изменения в приёмник. При этом ни одна из инструкций пересылок не влияет ни на какие флаги регистра состояния SREG. Множество возможностей адресации позволяют с одинаковым успехом обрабатывать как отдельные байты так и массивы данных. При этом часто существует несколько путей для реализации той или иной операции.

В пределах РОН пересылка производится с помощью команды mov Rd,Rr (Пересылка между регистрами). Кроме этого, имеется возможность перемещения двухбайтовых чисел (регистровых пар R1:R0, R3:R2,…, R29:R28, R31:R30) с помощью команды movw  Rd,Rr (Пересылка между регистровыми парами), где на месте операндов Rd и Rr должны стоять младшие регистры в обозначениях регистровых парах приёмника и источника соответственно (например, movw  R0, R30 для пересылки R1:R0 ← R31:R30). Обе эти команды выполняются за один машинный цикл:

     mov   R17,R16  ; возведение в квадрат R16 
     mul   R17,R16  ; с помещением двухбайтового результата 
     movw  R16,R0   ; в регистровую пару R17:R16  

Для загрузки константы в регистр служит команда с непосредственной адресацией ldi Rd,K (Загрузка константы в регистр). Она работает только со старшими РОНами (R16…R31).

Команды для работы с SRAM микроконтроллера используют, в основном, косвенную адресацию. Для этих целей применяются три 16-разрядных индексных регистра X,Y,Z, которые находятся в адресном пространстве РОН и по совместительству также являются регистровыми парами R27:R26, R29:R28, R31:R30.

Копировать байт из памяти ОЗУ в РОН можно любой из команд: ld Rd,X, ld Rd,Y, ld Rd,Z (Косвенное чтение из памяти данных). В этом случае в регистре приёмнике окажется содержимое ячейки памяти данных, адрес которой находится в одном из индексных регистров. Кроме этого, существует ещё две вариации данного действия. В одной из них после копирования производится инкрементирование регистров X,Y,Z, на что указывает знак “+” в командах: ld Rd,X+, ld Rd,Y+, ld Rd,Z+ (Косвенное чтение из памяти данных с постинкрементом). Во втором случае, перед пересылкой, содержимое индексного регистра сначала уменьшается на 1 (знак “-” в команде): ld Rd,-X, ld Rd,-Y, ld Rd,-Z (Косвенное чтение из памяти данных с преддекрементом).

Команды косвенного чтения с постинкрементом/преддекрементом очень эффективны при работе с массивами однотипных данных. Для обращения же к элементам структуры (набору данных разного типа) удобно использовать ld Rd,Y+q, ld Rd,Z+q (Косвенное относительное чтение из памяти данных), в которых в качестве указателей используется Y,Z со смещением q (адрес ячейки памяти определяет сумма (Y)+q или (Z)+q). Смещение q в командах -фиксированная величина, лежащая в пределах 0…63.

Пересылка данных из РОН в ОЗУ посредством косвенной адресации реализуется с помощью команд: st X,Rr, st Y,Rr, st Z,Rr (Косвенная запись в память данных). Содержимое регистра в них копируется в ячейку памяти, адрес которой определяется указателями X,Y и Z соответственно. Точно также существуют команды загрузки с постинкрементом st X+,Rr, st Y+,Rr, st Z+,Rr (Косвенная запись в память данных с постинкрементом) и с преддекрементом индексного регистра st -X,Rr, st -Y,Rr, st -Z, Rr (Косвенная запись в память данных с преддекрементом). Ещё две команды этой группы используют косвенную адресацию со смещением: st Y+q,Rr, st Z+q,Rr (Косвенная относительная запись в память данных). Здесь смещение q может находится в пределах 0…63.

Как видно между командами выгрузки из памяти и загрузки в память существует полная симметрия. У каждой операции пересылки существует аналогичная, для пересылки в обратном направлении, причём с использованием трёх равноправных индексных регистров. Кроме того все они выполняются за один промежуток времени в 2 машинных цикла. Типичный пример их совместного использования может выглядеть следующим образом:

      ldi  YL, low(buffer1)  ; копирование SIZE байт из 
      ldi  YH, high(buffer1) ; буфера buffer1 в буфер buffer2 
      ldi  ZL, low(buffer2)  ; перед копированием в индексные 
      ldi  ZH, high(buffer2) ; регистры Y и Z заносятся адреса 
      ldi  R16,SIZE         ; буферов buffer1 и buffer2  
copy: ld   R17,Y+
      st   Z+,R17
      dec  R16
      brne copy
      .	

Копирование данных из ОЗУ в РОН и обратно может быть произведено и с использованием прямой адресации по командам lds Rd,k (Прямое чтение из памяти данных) и sts k,Rr (Прямая запись в память данных) соответственно. В этом случае двухбайтовый адрес k ячейки памяти находится в коде операции, а сами команды занимают 2 слова (4 байта) памяти программ.

Все вышеуказанные команды пересылок работают в едином адресном пространстве где под РОН отведены адреса 0x00…0x1F, под РВВ от 0x20…0x5F, остальное под ячейки ОЗУ. Поэтому, например, копирование R16←R17 может быть произведено разными путями: mov R16,R17, lds R16,0x0011, ld R16,X (в регистре X адрес 0x0011) и т.д. Первый способ здесь, конечно, более предпочтительный (использует пересылку типа регистр-регистр и выполняется быстрее), но остальные команды позволяют получить доступ к произвольному элементу любой области памяти и поэтому очень универсальны.

Для обращения к РВВ служат команды: in Rd,P (Ввод из порта), out P,Rr (Вывод в порт). Первая считывает значение РВВ в один из РОНов, а вторая производит пересылку РОН в РВВ.

Поскольку напрямую модифицировать РВВ невозможно, приходится сначала копировать их содержимое в рабочие РОН, производить необходимые изменения, а потом заносить обратно:

    in    R16,PORTC      ; запись и модификация РВВ,
    andi  R16,0b00001111 ; отвечающего за содержимое порта
    out   PORTC,R16        

Тоже самое относится и к данным, расположенным в ОЗУ:

    lds   R16,0x0200 ; запись и модификация байта из ОЗУ,
    inc   R16        ; находящегося по абсолютному адресу 0x0200
    sts   0x0200,R16

В группе команд пересылки данных имеются две, специально разработанные для работы со стеком. Это push Rr (Сохранение в стеке) и pop Rd (Извлечение из стека). Не смотря на то, что основное назначение стека это сохранение адресов возврата при вызове подпрограмм, эти инструкции позволяют использовать его и для оперативного сохранения данных, находящихся в РОН. Командой push Rr содержимое регистра копируется в ячейку памяти (вершину стека), адрес которой содержится в указателе стека SP, после чего значение SP уменьшается на 1. По команде pop Rd указатель стека возвращается на предыдущий элемент (SP+1), а значение, байта записанное по этому адресу копируется в регистр.

Таким образом реализуется память магазинного типа, где вообще не надо заботиться о задании адресов сохраняемых и восстанавливаемых из в памяти ОЗУ данных. Единственное, про что всегда необходимо помнить, - это порядок доступа к элементам стека Last In First Out (Последний Вошел Первый  Вышел). Очередность, в которой регистры восстанавливаются из стека, должна быть обратной по отношению к очередности сохранения регистров:

      ldi  R16, low(RAMEND) ;установка вершины стека 
      out  SPL,R16        
      ldi  R16, high(RAMEND)
      out  SPH,R16  
      .    
      push R16             ;сохранение регистров в стеке
      push R17
      push R18
      .
      pop  R18             ;восстановление регистров из стека
      pop  R17
      pop  R16

Имеется и другая возможность программно реализовать стек данных. Команды ld Rd,X+, ld Rd,Y+, ld Rd,Z+ по сути являются иной реализацией действия push Rr, а st -X,Rd, st -Y,Rd, st -Z, Rd подобны pop Rd. Разница состоит лишь в том, что в качестве индексного регистра выступает не SP, а один из регистров–указателей (X,Y,Z) и вершина стека перемещается в сторону увеличения адресов ОЗУ:

      ldi  ZL, low(stack)  ;установка вершины стека         
      ldi  ZH, high(stack) 
      .            
      ld   R16, Z+         ;сохранение регистров в стеке
      ld   R17, Z+              
      ld   R18, Z+              
      .
      st   -Z, R18         ;восстановление регистров из стека
      st   -Z, R17         
      st   -Z, R16 

Учитывая то, что SP расположен в пространстве РВВ, а X,Y,Z в РОН, использование эмуляции стека может быть даже более предпочтительной. Регистры X,Y,Z могут быть быстрей модифицированы и кроме того отсутствует опасность повредить их содержимое при вызове подпрограмм и возникновении прерываний.

Подобно большинству микроконтроллеров, у AVR имеется возможность хранения таблиц констант в памяти программ. Для их чтения разработаны команды lpm (Загрузка памяти программ), lpm Rd,Z (Загрузка памяти программ), lpm Rd,Z+ (Загрузка памяти программ с постинкрементом). Все они переписывают содержимое байта из FLASH памяти программ (адрес байта находится в Z) в один из РОН. С помощью первой инструкции, не имеющей параметров, копирование производится в R0. Вторая и третья модификации команды используют в качестве приёмника любой РОН. Команда lpm Rd,Z+ при этом осуществляет ещё и инкрементирование индексного регистра Z после считывания. Типичный пример копирования строки из памяти программ в ОЗУ может выглядеть следующим образом:

        ldi  ZL,low(2*string) ;копирование строки "Hello World"
	    ldi  ZH,high(2*string);длиной 11 байт из памяти программ
        ldi  YL,low(buffer)   ;в ОЗУ микроконтроллера по
	    ldi  YH,high(buffer)  ;адресу buffer 
        ldi  R16,11
cycle:  lpm  R17,Z+            
	    st   Y+,R17
	    dec  R16
	    brne cycle
        .

        .org 0x1000
string: .db  "Hello World", 0

Здесь последовательно осуществляется считывание строки "Hello World !" (13 байт в кодировке ASCII) расположенной в памяти программ начиная с адреса 0x1000 (задан директивой .org 0x1000). Для резервирования FLASH памяти используется директива ассемблера .db, после которой непосредственно следуют данные. Строка переписывается в ОЗУ по адресу buffer.

Есть два важных момента при использовании операций такого типа. В приведённом выше фрагменте программы в качестве указателя на строку в индексный регистр Z заносится удвоенный адрес метки 2*string и это не случайность. Дело в том, что метке string соответствует адрес слова программ 0x1000. Но слово программ у AVR имеет блину 2 байта, а в указатель Z необходимо занести именно адрес байта т.е. 2*0x1000 = 0x2000. По той же причине в памяти программ необходимо выделять только чётное (кратное двум) количество байтов и если это не так, то надо добавлять незначащий байт 0 в самом конце, как это и случилось в нашем примере (строка "Hello World !" содержит 13 байт). Попутно заметим, что строки символов ASCII, как правило, и хранят в таком формате (добавляют в конце 0). Это позволяет автоматически распознавать конец строки и считывать, не зная заранее её длины.

Использование 2-байтового регистра Z позволяет адресовать только 64 кб при считывании памяти программ. Этого явно недостаточно для тех моделей AVR, которые имеют 128 и 256 кб FLASH-памяти. Для того чтобы работать во всём диапазоне адресов к указателю Z в этом случае добавляется регистр RAMPZ из пространства РВВ, в котором используются 1 или 2 младших бита. Этот 3-байтовый индексный регистр RAMPZ:ZH:ZL используют инструкции elpm (Расширенная загрузка памяти программ), elpm Rd, Z (Расширенная загрузка памяти программ), elpm Rd,Z+ (Расширенная загрузка памяти программ с постинкрементом).

Последняя инструкция в группы команд пересылки spm (Запись памяти программ). Она реализует возможность самопрограммирования микроконтроллеров AVR. Конкретное действие, которое выполняет эта команда, зависит от установок в управляющем РВВ SPMCSR. Это может быть стирание страницы памяти программ, занесение данных для записи во временный буфер или копирование буфера в память программ, а также чтение ячеек идентификаторов и защиты. В любом случае для задания адреса области используется указатель Z, а данные, если они необходимы, передаются в регистровой паре R1:R0. Так как действие данной инструкции связано с модификацией программного кода, для ее корректного применения предпринят ряд мер предосторожности, о чём подробно будет сказано в разделе “Самопрограммирование микроконтроллеров AVR”.

Перейти к следующей части:

Теги:

Котов Игорь Юрьевич Опубликована: 2012 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (0) | Я собрал (0) | Подписаться

Статью еще никто не комментировал. Вы можете стать первым.
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется напряжение?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Arduino UNO Осциллограф DSO138
вверх