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

Похожие статьи:


Реклама ⓘ

Арифметические и логические команды

Табл.1. Арифметические и логические команды:

Команда

Описание

Действие

Циклы

Код операции

Флаги

ATtiny

ATmega

add   Rd,Rr

Add two Registers

Rd←Rd+Rr

1

0000 11rd dddd rrrr

Z,C,S,
N,V,H

+

+

adc   Rd,Rr

Add with Carry two Registers

Rd←Rd+Rr+C

1

0001 11rd dddd rrrr

Z,C,S,
N,V,H

+

+

adiw  Rdl,K

Add Immediate to Word

Rdh:Rdl←Rdh:Rdl+K

2

1001 0110 KKdd KKKK

Z,C,S,
N,V

±

+

sub   Rd,Rr

Subtract two Registers

Rd←Rd-Rr

1

0001 10rd dddd rrrr

Z,C,S,
N,V,H

 +

+

sbc   Rd,Rr

Subtract with Carry two Registers

Rd←Rd-Rr-C

1

0000 10rd dddd rrrr

Z,C,S,
N,V,H

+

+

subi  Rd,K

Subtract Constant from Register

Rd←Rd-K

1

1010 KKKK dddd KKKK

Z,C,S,
N,V,H

+

+

sbci  Rd,K

Subtract with Carry Constant from Register

Rd←Rd-K-C

1

0100 KKKK dddd KKKK

Z,C,S,
N,V,H

+

+

sbiw  Rdl,K

Subtract Immediate from Word

Rdh:Rdl←Rdh:Rdl-K

2

1001 0111 KKdd KKKK

Z,C,S,
N,V

±

+

and   Rd,Rr

Logical AND Registers

Rd←Rd AND Rr

1

0010 00rd dddd rrrr

 

Z,S,N

+

+

andi  Rd,K

Logical AND Register and Constant

Rd←Rd AND K

1

0111 KKKK dddd KKKK

 

Z,S,N

+

+

or   Rd,Rr

Logical OR Registers

Rd←Rd OR Rr

1

0010 10rd dddd rrrr

 

Z,S,N

 +

+

ori   Rd,K

Logical OR Register and Constant

Rd←Rd OR K

1

0110 KKKK dddd KKKK

 

Z,S,N

+

+

eor   Rd,Rr

 

Exclusive OR Registers

Rd←Rd EOR Rr

1

0010 01rd dddd rrrr

 

Z,S,N

+

+

com   Rd

One’s complement

Rd←0xFF-Rd

1

1001 010d dddd 0000

 

Z,S,N

+

+

neg   Rd

Two’s complement

Rd←0x00-Rd

1

1001 010d dddd 0001

Z,C,S,
N,V,H

+

+

sbr   Rd,K

Set Bit(s) in Register

Rd←Rd OR K

1

0110 KKKK dddd KKKK

Z,S,N

+

+

cbr   Rd,K

Clear Bit(s) in Register

Rd←Rd AND (0xFF- K)

1

0111 KKKK dddd KKKK

 

Z,S,N

+

+

inc   Rd

Increment

Rd←Rd+1

1

1001 010d dddd 0011

Z,S,
N,V

+

+

dec   Rd

Decrement

Rd←Rd-1

1

1001 010d dddd 1010

Z,S,
N,V

+

+

tst   Rd

Test for Zero or Minus

Rd←Rd AND Rd

1

0010 00dd dddd dddd

 

Z,S,N

+

+

clr   Rd

Clear Register

Rd←Rd EOR Rd

1

0010 01dd dddd dddd

 

Z,S,N

+

+

ser   Rd

Set Register

Rd←0xFF

1

1110 1111 dddd 1111

None

+

+

mul   Rd,Rr

 

Multiply Unsigned

R1:R0←Rd*Rr

2

1001 11rd dddd rrrr

Z,C

-

+

muls  Rd,Rr

Multiply Signed

R1:R0←Rd*Rr

2

0000 0010 dddd rrrr

Z,C

-

+

mulsu Rd,Rr

Multiply Signed with Unsigned 

R1:R0←Rd*Rr

2

0000 0011 0ddd 0rrr

Z,C

-

+

fmul  Rd,Rr

Fractional Multiply
Unsigned

R1:R0←(Rd*Rr)<<1

2

0000 0011 0ddd 1rrr

Z,C

-

+

fmuls  Rd,Rr

Fractional Multiply
Signed

R1:R0←(Rd*Rr)<<1

2

0000 0011 1ddd 0rrr

Z,C

-

+

fmulsu Rd,Rr

Fractional Multiply
Signed with Unsigned

R1:R0←(Rd*Rr)<<1

2

0000 0011 1ddd 1rrr

 Z,C

-

+

Как видно из табл.1, AVR имеют всего 3 разновидности команды сложения. Инструкции add Rd,Rr (Сложение двух регистров), adc Rd,Rr (Сложение двух регистров с учётом переноса), позволяют складывать как однобайтовые числа, так числа произвольной разрядности. В последнем случае для связи байтов используется флаг переноса C в регистре SREG, который устанавливается всякий раз, когда разрядность суммы превысит 8 бит. Этот перенос должен быть добавлен к сумме старших байтов командой adc Rd,Rr:

	add  R18,R16   ; сложение двухбайтовых чисел 
	adc  R19,R17   ; R19:R18 = R19:R18 + R17:R16 

Сложение регистра с константой, к сожалению, отсутствует. И это приносит некоторые неудобства, так как приходится использовать две команды, одна из которых занесение числа во вспомогательный регистр, а уже вторая - сложение регистров:

      ldi  R17,0x30  ; заносим в R17 константу 0x30    
      add  R16,R17   ; R16 = R17 + 0x30 

Во многих случаях вышеуказанную проблему можно решить, используя команду adiw Rdl,K (Сложение константы со словом). Она позволяет прибавить 6-разрядную константу, лежащую в диапазоне 0…63, к одной из 4х регистровых пар Rdh:Rdl (R25:R24, R27:R26, R29:R28, R31:R30). С её помощью также удобно реализовать 16-разрядный счётчик событий:

   key_press:  
      adiw  R24,1     ; инкрементируем счётчик  R25:R24
      sbis  PINB,0    ; пока на линии 0 порта PORTB низкий 
      rjmp  key_press ; логический уровень

Из всех арифметических операций, вычитание в AVR - наиболее разнообразно по способам адресации.

Имеется две команды с прямой адресацией РОН:  sub Rd,Rr (Вычитание двух регистров),  sbc Rd,Rr (Вычитание двух регистров с учётом заема). При совместном использовании они позволяют получить разность чисел любой разрядности. Для связи байт, при этом, и здесь служит флаг C. Но в отличие от сложения он устанавливается, когда разность оказалась отрицательной(Rd < Rr) и имеет в этом случае смысл заема, который должен быть вычтен из разности старших байт командой sbc Rd,Rr:

      sub  R18,R16   ; вычитание двухбайтовых чисел 
      sbc  R19,R17   ; R19:R18 = R19:R18 - R17:R16 

Ещё две команды с непосредственной адресацией используются для тех же целей:  subi Rd,K (Вычитание константы из регистра) и sbсi Rd,K (Вычитание константы из регистра c учётом заёма). Эти инструкции очень универсальны. Их с одинаковым успехом можно применять как в целях вычитания, так и сложения. В последнем случае необходимо использовать представление числа K в дополнительном коде (т.е. изменить знак числа –K = 0xFF+1-K):

     subi  R16,-0x30 ; R16 = R16 + 0x30 = R16 – (-0x30)

Существует также инструкция, работающая в двухбайтовом формате, sbiw Rdl,K (Вычитание константы из слова). Подобно сложению adiw Rdl,K, с её помощью можно вычесть 6-разрядную K (0…63) из тех же самых регистровых пар (R25:R24, R27:R26, R29:R28, R31:R30). Главная область применения команды – реализация счётчика циклов:

   delay:  
      sbiw  R24,1  ; декрементируем счётчик  R25:R24 пока
      brne  delay  ; его содержимое не станет 0, формируя
      .    ; задержку времени  4*R25:R24 циклов

Группа логических инструкций представлена 6-ю командами.
Операция “НЕ” производится по команде com Rd (Дополнение до одного). При этом фактически производится действие Rd←0xFF-Rd, при котором инвертируются все биты регистра. Команды and Rd,Rr (“Логическое И” регистров), andi Rd,K (“Логическое И” регистра и константы) и or Rd,Rr (“Логическое ИЛИ” регистров), ori Rd,K (“Логическое ИЛИ” регистра и константы) производят соответствующие логические операции как с регистрами, так и регистра с константой. Операция же “Исключающее ИЛИ” возможна только между регистрами. Для этих целей служит команда eor Rd,Rr (“Исключающее ИЛИ” регистров). Если провести операцию “Исключающее ИЛИ” регистра с самим собой (eor Rd,Rd), то будет получен нулевой результат (Rd←Rd EOR Rd = 0). Это свойство часто применяется, когда необходимо отчистить регистр, а команда eor Rd,Rd может иметь при этом альтернативную форму записи clr Rd (Очистить регистр). Кроме того, с помощью последовательности всего трех команд eor Rd,Rr можно обменять содержимое двух регистров (команда обмена РОНов у AVR отсутствует) местами не используя ни одной дополнительной ячейки памяти:

   eor  R16,R17  ; R16 = R16 XOR R17  
   eor  R17,R16  ; R17 = R17 XOR (R16 XOR R17) = R16  
   eor  R16,R17  ; R16 = (R16 XOR R17) XOR R16 = R17  

Все описанные логические операции могут использоваться, например, в следующем контексте:

   in   R16,PORTB  ;заносим для изменения РВВ PORTB в РОН R16 
   ori  R16,(1«PB0)|(1«PB5)   ;устанавливаем биты 0,5 в R16
   andi R16,~((1«PB1)|(1«PB2));сбрасываем биты 1,2 в R16 
   out  PORTB,R16  ;выводим изменённое значение R16 в PORTB 
   eor  R16,R16    ;обнуляем R16
   out  PORTC,R16  ;заносим 0 в PORTC

Как во многих других случаях, у инструкции ori Rd,K существует другая форма написания sbr Rd,K (Установка бита(ов) в регистре), числящаяся, однако, как самостоятельная команда. Применяя её необходимо помнить, что, несмотря на аббревиатуру, на самом деле производится именно операция “Логическое ИЛИ” регистра и битовой маски, а не установка битов в регистре. Так, например, для установки бита n в регистре Rd правильно писать sbr Rd,1<

   in   R16,PORTB  ; заносим для изменения РВВ PORTB в РОН R16 
   sbr  R16,(1«PB0)|(1«PB5) ; устанавливаем биты 0,5 в R16
   cbr  R16,(1«PB1)|(1«PB2) ; сбрасываем биты 1,2 в R16 
   out  PORTB,R16  ; выводим изменённое значение R16 в PORTB 
   clr  R16        ; обнуляем R16
   out  PORTC,R16  ; заносим 0 в PORTC

Когда надо установить все биты регистра, то можно воспользоваться инструкцией ser Rd (Установка регистра), которая заносит константу 0xFF в регистр Rd. Она является частной формой написания команды ldi Rd,K (Загрузка константы в регистр), относящейся к группе команд пересылки. Подобное действие можно осуществить и другими способами. Например, в результате команды ori R16,0xFF все биты регистра R16 также будут установленными.

Но в отличие от ser R16 или, что тоже самое, ldi R16,0xFF - будут изменены значения флагов N и Z, что может повлиять на правильный ход выполнение программы. По той же причине в ряде случаев для обнуления регистра лучше использовать ldi R16,0 вместо clr R16 (eor R16,R16); все флаги в регистре SREG останутся неизменными. Единственное, что мешает повсеместному применению команды ldi Rd,K, это ограниченный набор РОН с которыми она работает. Только регистры R16…R31 могут использоваться с этой инструкцией. Это существенное ограничение наложено и на все арифметические и логические команды, которые используют непосредственную адресацию (действие над регистром и константой).

На практике часто необходимо осуществить проверку регистра на нуль. Проще всего это сделать если произвести операцию “Логическое И” регистра самим с собой (and Rd,Rd). При этом содержимое Rd останется неизменным, а в регистре SREG будет установлен флаг нулевого результата Z если Rd = 0. Параллельно с ним будет переопределён и флаг N, который в случае использования знаковых чисел будет свидетельствовать об отрицательном содержимом регистра. Для инструкции and Rd,Rn где Rd = Rn, может быть использована  другая форма записи в виде псевдокоманды tst Rd (Проверка на нуль и минус).

В тех случаях, когда необходимо изменить знак однобайтового числа используют команду neg Rd (Дополнение до двух). Она осуществляет действие Rd←0x00-Rd и используется только для чисел представленных дополнительном коде.

У AVR имеются также команды прямого и обратного счёта. Первая из них inc Rd (Инкремент) увеличивает на единицу содержимое регистра, а вторая dec Rd (Декремент), соответственно, уменьшает. Конечно, действия инкрементирования и декрементирования могут быть заменены, например, на прибавление 1 и вычитание 1 из регистра Rd (subi R16,-1 эквивалентно inc R16, а subi R16,1  тоже, что и dec Rd). Но, несмотря на это обе команды имеют большое самостоятельное значение. Главная их особенность в том, что они не влияют на флаг переноса C и тем самым оптимизированы для формирования циклов, в которых он может использоваться:

		ldi  R16,SIZE   ; производим сдвиг числа, 
		clc   	        ; находящегося в ОЗУ и состоящего из 
rleft:  ld   R17,X      ; SIZE байт на один разряд влево
		rol  R17         
		st   X+,R18      
		dec  R16                 
		brne rleft
		.

Дополняет группу арифметических команд умножение однобайтовых чисел. В зависимости от формата представления множителя и множимого, существует 6 вариаций данной операции. Произведение, полученное по команде умножения (2-байтовая величина) заносится в регистровую пару R1:R0. Эта интересная аппаратная особенность AVR позволяет очень быстро обработать результат, так как он размещается в РОН и может быть перемещён в любое место всего одной командой пересылки. Следует, однако, предварительно позаботится о сохранении содержимого регистров R1, R0 если они используются в программе.

Для умножения целых чисел разработаны три команды: mul Rd,Rr (Умножение беззнаковых чисел), muls Rd,Rr (Умножение знаковых чисел), mulsu Rd,Rr (Умножение знакового числа на беззнаковое).
Знаковые числами должны быть представлены в дополнительном коде. При этом для первых двух команд безразлично на месте каких операндов будут находиться множитель и множимое. К одному и тому же результату приведут, например,  mul R16,R17 и mul R17,R16 (muls R16,R17 и muls R17,R16). В случае mulsu Rd,Rr на месте Rd обязательно должно стоять знаковое число. Помимо флага Z (один из операндов 0), умножение оказывает влияние и на флаг переноса C. В него заносится старший бит регистра R1. Таким образом, в командах  muls Rd,Rr, mulsu Rd,Rr он фактически является флагом знака и устанавливается когда произведение отрицательное. Необходимо также помнить, что инструкция muls Rd, Rr может использоваться только с регистрами R16…R31. Ещё меньше поддерживает команда mulsu Rd,Rr, только R16…R23.

Существует ряд специфических приложений, в которых может понадобиться умножения дробных чисел с фиксированной запятой. Главная задача, где это может быть необходимо, - цифровая обработка сигналов. Для дробного умножения имеются команды: fmul Rd,Rr (Умножение дробных беззнаковых чисел), fmuls Rd,Rr (Умножение дробных знаковых чисел), fmulsu Rd,Rr (Умножение дробного знакового числа на беззнаковое). Все команды работают с числами в формате (1.7). Старший бит регистра является целой частью числа, а  младшие 7 битов отведены под дробную. Произведение приводится к формату (2.14). Для этого производится сдвиг результата на один разряд влево так, что старший разряд оказывается во флаге C. Все инструкции дробного умножения работают только с регистрами R16…R23.

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

Теги:

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

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

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

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

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

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

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Конструктор для сборки: предусилитель на лампе 6N3 МиниПК MK809V - 4 ядра, Android 4.4.2
вверх