Мікроконтролерів AVR мають дуже широкий набір команд. Це дозволяє більш просто провести розробку компіляторів, що також означає, що AVR може бути легко запрограмований з використанням різноманітних команд, що спрощують рішення задачі.
Слід звернути увагу на такі тонкощі. Багато команди можуть звертатися тільки до 16-старшим РОН і не мають доступу до 16-молодшим. Значення зсувів і констант можуть бути обмежені і виявитися не в тому діапазоні, який ви очікували.
Існує різниця між «повноцінними» старшими моделями серії 8515 і молодшими моделями серії 1200. Молодші моделі МХ реалізують частина повного набору команд, у яких доступний тільки один індексний регістр Z. Хоча при перенесенні програм з молодших моделей на старші навряд чи виникнуть проблеми, вони вірогідні при зворотному напрямку перенесення. Навіть з урахуванням усіх цих застережень AVR - це МК дуже простий для програмування завдяки багатству набору команд і особливостей його структури.
Для наочності, в даному розділі наведемо лише деякі приклади команд. Але перш ніж приступити до вивчення команд, доцільно розглянути різні способи адресації даних.
Способи адресації даних
Пряма адресація до Регістрів Загального Призначення
Основним способом доступу до даних є пряме (безпосереднє звернення до РОН. На рис. 2.12 операнд команди міститься в реєстрі Rd, а КОП позначає частину слова команди, відповідну оду ОПерации, Зазвичай у форматі команди відводитися п'ять біт, які дозволяють направлятися до будь-якого регістру.
Команди, діючі з двома регістрами, діють, в основному, аналогічним чином. У цих командах регістр-приймач Rd (destination) вказується перед регістром-джерелом Rr (resource), тобто є першим параметром (див. мал. 2.13). Таким чином, команда:
ADD R0, R1
преально виконується так: R0 R0 = + R1.
Рис. 2.12. Пряма адресація одного регістру.
Результат зберігається у регістрі Rd.
Рис. 2.13. Пряма адресація до двох РОН.
Пряма адресація до регістрів введення/виводу.
На рис. 2.14 адреса операнда міститься в 6 біт слова команди (комірка Р).
Rd - визначає адреса регістра джерела або регістра приймача. Наприклад, цей тип адресації можуть використовувати команди IN або OUT:
IN R0, SREG ;зберегти регістр стану в регістрі R0
OUT PORTB, R1 ;записати дані з реєстру R1 в PORTB
Рис. 2.14. Пряма адресація регістрів введення/виводу.
Пряма адресація даних.
Рис.2.15. Пряма адресація даних.
Єдиний адресний простір є простором даних, включаючи РОН, регістри введення/виводу, внутрішня пам'ять і зовнішня пам'ять (якщо є). 16-розрядний адреса даних міститься в 16 молодших розрядах 32-х розрядної команди. Rd/Rr визначає адреса регістра джерела або регістра приймача. Такий тип адресації, приміром, можуть використовувати команди LDS і STS:
LDS PORTB, R1 ;записати дані з реєстру R1 в PORTB
STS PORTB, R1 ;записати дані з реєстру R1 в PORTB
Непряма адресація даних
Існує чотири типи непрямої адресації даних: проста, з постинкрементом, з преддекрементом, зі зміщенням. Для перших трьох типів непрямої адресації даних адреса операнда міститься в реєстрі X, Y або Z. Для останнього типу (зі зсувом) адреса операнда обчислюється складанням вмісту регістрів Y або Z з шістьма бітами адреси, що містяться в слові команди. Самі ж регістри залишаються незмінними.
Сенс непрямої адресації з постинкрементом (з преддекрементом) полягає в наступному. Після (до) виконання операції регістр X, Y і Z інкрементіруется (декрементіруется).
Розглянемо деякі приклади:
1) ST X, Rn ;помістити дані з Rn за адресою, вказаною в регістрі Х;
2) ST X+, Rn ;теж саме що і в 1), але згодом X інкрементіруется;
3) ST-X, Rn ;попередньо X декрементіруется;
В попередніх трьох прикладах замість Х можуть бути Y або Z.
4) STD Y+c, Rn ; до значення Y додається константа зміщення ’c’ і за цією адресою записуються дані з Rn. Y при цьому залишається незмінним. Замість Y може бути тільки Z.
Команди пересилання даних.
Пересилання даних з одного місця в інше є для AVR дуже простою операцією, оскільки є дуже велика кількість команд, призначених для виконання цього завдання. Жодна команда пересилання даних не впливає на біти регістра стану.
Команда LPM - завантаження даних з таблиць, що зберігаються в пам'яті програм. У цій команді молодший біт індексного регістра Z використовується для вказівки байти, який буде читатися, якщо 0 - читається молодший байт, 1 - старший. Решта 14 байт використовуються для вказування адреси слова.
Команда MOV - копіює вміст одного РОН в інший. LDI - завантажує в один з старших 16 РОН байт, що міститься в команді. IN, OUT - доступ до регістрів введення/виводу, починаючи з нульового адреси. Повний список усіх команд пересилання даних можна знайти в ДОДАТКУ 1, Таблиця А.3.
На рис.2.16 наочно показано схематичне виконання команди LPM.
Рис. 2.16. Команда LPM.
Команди арифметичних і логічних операцій.
Основними арифметичними операціями є додавання і віднімання двох чисел. Ці команди здебільшого очевидні. Додавання і віднімання вмісту двох регістрів здійснюватися за допомогою команд ADD та SUB. Модифікації цих команд, які враховують значення прапора перенесення, дозволяють виконати операції над 8-, 16-, 24 - і навіть 32-розрядними числами зі знаком, що зберігаються в регістрах.
Пояснимо функції прапорів негативного результату N (negative), переповнення V (overflow) і знака S (sign), так як вони мають деякі особливості і складними для розуміння при першому знайомстві.
Прапор негативного результату N просто копіює значення біт 7 результату, який показує, є результат позитивним або негативним числом.
Прапор переповнення V в регістрі SREG вказує на переповнення під час додавання або віднімання чисел зі знаком. Розглянемо приклад:
ADD R1, R2
Прапор V буде встановлений в 1, якщо в регістрах R1 і R2 міститися позитивні числа, а результат їх складання виявиться більше 127, або обидва числа негативні, а результат буде менше-128. Розглянемо приклад з конкретними значеннями:
LDI R1, 100 ;100 = 0b01100100
LDI R2, 100 ;Занести 0b01100100 R1 і R2
ADD R1, R2 ;R1 = R1 + R2 = 200 = 0b11001000
Десяткове число 200 в двійковій запису має значення біт 7 рівне 1, що вказує на отримання негативного результату. Отже, після виконання операції додавання прапор N буде встановлений в 1. Але в даному випадку разом з прапором N буде так само встановлений в 1 прапор V, вказуючи, що переповнення при обробці чисел зі знаком.
Якщо вміст R1 = R2 = - 100, то результатом складання цих чисел буде 0b00111000 в двійковій системі числення, що є позитивним числом. При цьому прапор N буде скинуто до 0,показуючи, що результату позитивний, проте буде встановлений прапор V означає, що насправді це не так.
Використання прапора S = N ^ V дозволяє розглядати як результат 9-розрядне числа зі знаком, де старшим (знаковим) розрядом як раз і є прапор S. Як було відзначено при описі прапора V, він встановлюється в 1, коли біт 7 результату має неправильне значення, тобто результат не представлений правильним числом зі знаком в додатковому коді. Виконавши операцію «ВИКЛЮЧНЕ АБО» над значенням прапора V і біта 7 результату, який зберігатися в біті N, ви отримаєте реальний знак результату. У першому прикладі (100 + 100) відбувається встановлення у 1 прапорів V і N, в результаті прапор S буде дорівнювати нулю (1 ^ 1 = 0). У другому прикладі (- 100 - 100) прапор N скидається в 0, а прапор V встановлюється в 1, тому прапор S буде дорівнювати одиниці, вказуючи на те, що результат негативний.
Прапор S повинен використовуватись зі старшим байтом числа. При операціях з 16-, 24 і 32-розрядними числами значення прапора S треба перевіряти тільки після завершення останньої операції зі старшим байтом числа. При операціях з молодшими байтами використовується прапор переносу З, як зазвичай при виконанні додавання і віднімання.
Команди розгалуження
Команди відносного переходу RJMP і виклику підпрограми RCALL є основними для зміни послідовності виконання команд у МК. При цьому вміст програмного лічильника змінюється на величину зміщення, що задається в молодших 12 біт коду команди.
МК може виконувати команди розгалуження за значенням певних бітів у регістрі стану SREG. Оскільки номер біта і його значення повинні бути вказані в коді команди, то діапазон можливих адрес переходу складає +/- 63 щодо поточного адреси. Це означає, що застосування команд умовних розгалужень досить обмежена, але цю проблему можна вирішити за допомогою розгалуження до команді, яка потім виконає необхідний безумовний перехід.
Ще один клас команд розгалуження - це команди пропуску. Після перевірки зазначеного умови, дані команди або виконують наступну команду, або пропускають її.
Бітові команди і команди тестування бітів.
Команди скидання (очищення) і установки бітів призначені для модифікації регістрів введення/виводу. Але деякі з них можуть працювати тільки з частиною регістрів введення/виводу. Це означає, що для деякої частини регістрів введення/виводу ви повинні спочатку переписати їх вміст в РОН, модифікувати, а потім знову зберегти в регістрі введення/виводу. Для виконання цієї процедури можна написати спеціальну макрос (макрос).
Часто необхідно переслати біт з одного регістр або змінної в інший. Це можна зробити наступним чином:
BST B,5 ;помістити біт 5 змінно У біт Т регістра SREG
BLD A,2 ;зберегти біт Т регістра SREG як біта А.2
Команда SWAP міняє місцями старший і молодший полубайт регістра. Це корисно, коли ви зберігаєте в регістрі дві цифри, а не одне восьмибитовое число.
Команди зрушень і циклічних зрушень LSL, LSR, ROL, ROR і ASR корисні як для виконання зрушень даних у процесі їх уведення висновку, так і для перевірки значення певного біта в РОН без необхідності 8 виконання окремих операцій тестування бітів. За допомогою циклічного зміни можна зробити індивідуальну перевірку будь-якого біта в заданому місці байта.