Главная » Микроконтроллеры
Призовой фонд
на май 2017 г.
1. Тестер компонентов MG328
Паяльник
2. Осциллограф DSO138
Паяльник
3. Регулируемый паяльник 60 Вт
Паяльник
4. 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-микроконтроллеров
LC-измеритель LC100-A Набор для сборки - LED лампа
вверх