В семействе AVR система команд у микроконтроллеров разных типов содержат от 89 до 130 команд
Базовая система команд содержит: 33 команды регистровых операций, при выполнении которых используются только регистры общего назначения; 26 команд с обращением по адресу в адресном пространстве SRAM; 2 команды с обращением к регистрам ввода-вывода; 1 команда с обращением к Flash; 22 команды операций с битами в разрядах регистров общего назначения и регистров ввода-вывода; 34 команды управления ходом программы.
В систему команд поздних версий микроконтроллеров входят дополнительные команды. Появление некоторых из них связано с увеличенным объемом Flash и/или наличием дополнительных модулей, например, наличием аппаратного умножителя.
Ниже приведены примеры использования команд, а в приложении 2 - полный перечень команд для микроконтроллера Atmega 128 (мнемокоды команд, описание, операции, флаги и количество машинных циклов на выполнение команды).
Примеры использования арифметических и логических команд
| ;сложить r1: r0 c r3:r2 | |
| Add r2,r0 | ;сложить младший байт |
| Adc r3,r1 | ;сложить старший байт с переносом |
| Add r1,r2 | ;сложить r2 с r1 (r1=r1+r2) |
| Adc r28,r28 | ;сложить r28 с самими собой (r28=r28+r28) |
| Adiw r24,1 | ;сложить 1 c r25:r24 |
| Adiw r30,63 | ;сложить 63 c Z указателем (r31:r30) |
| And r2,r3 | ;поразрядная логическая операция И над содержимым ;регистров r2 и r3, результат поместить в r2 |
| Ldi r16,1 | ;установить маску 0000 0001 в r16 |
| And r2,r16 | ;выделить бит 0 в r2 |
| Andi r17 $0F | ;очистить 4-7 разряды регистра r17 |
| Andi r18 $10 | ;выделить бит 4 в r18 |
| Andi r19 $AA | ;очистить нечетные биты r19 |
Примеры использования команд ветвления
| Cpi r20,5 | ;сравнить r20 со значением 5 | |
| Brbc 1,noteq | ;перейти, если флаг нуля очищен | |
| ……… | ||
| Noteq: | Nop | ;Перейти, по значению (пустая операция) |
| Bst r0,3 | ;загрузить Т битом 3 регистра r0 | |
| Brbs 6,Битыet | ; перейти, если бит T установлен | |
| …… | ||
| Битыet: | Nop | ;перейти по назначению (пустая операция) |
| Add r22,r23 | ;сложить r23 c r22 | |
| Brcc nocarry | ;перейти, если перенос очищен | |
| ……… | ||
| Nocarry: | Nop | ;перейти по назначению (пустая операция) |
| Cpi r26,$56 | ;сравнить r26 c $56 | |
| Brcs carry | ;перейти, если перенос установлен | |
| …… | ; | |
| Carry: | nop | ;перейти по назначению (пустая операция) |
| Сp r1,r0 | ;сравнить регистры r1 и r0 | |
| Breq equal | ;перейти, если содержимое регистров совпадает | |
| ……. | ; | |
| Equal: | Nop | ;перейти по назначению (пустая операция) |
| Cp r11, r12 | ;сравнить регистры r11и r12 | |
| Brge greateq | ;перейти, если r11>=r12 (со знаком ) | |
| ….. | ; | |
| Greateq: | Nop | ;перейти по назначению (пустая операция) |
| Brhc hclear | ;перейти, если флаг переноса очищен | |
| …… | ; | |
| Hclear: | Nop | ;перейти по назначению (пустая операция) |
| Mov r16,r0 | ;Копировать r0 в r16 | |
| Call check | ;Вызвать подпрограмму | |
| …… | ; | |
| Nop | ;Пустая операция | |
| Check: | Cpi r16,$42 | ;Проверить, содержит ли r16 заданное значение |
| Breq error | ;Перейти, если содержит | |
| Ret | ;Возврат из подпрограммы | |
| Error: | Rjmp error | ;Бесконечный цикл |
| Mov r16,r0 | ;Копировать r0 в r16 | |
| Call check | ;Вызвать подпрограмму check | |
| …… | ; | |
| Nop | ;Пустая операция | |
| Check: | Cpi r16,$42 | ;Проверить, содержит ли r16 заданное значение |
| Breq error | ;Перейти по метке error, если содержит | |
| Ret | ;Возврат из подпрограммы |
Примеры использования команд передачи данных
| Clr r27 | ;очистить старший байт X |
| Ldi r26,$20 | ;установить $20 в младший байт X |
| Ld r0,X+ | ;загрузить в r0 содержимое SRAM по адресу $20 (X постинкрементируется) |
| Ld r1,X | ;загрузить r1содержимое SRAM по адресу $21 |
| Ldi r26,$23 | ;установить $23 в младший байт X |
| Ld r2,X | ;загрузить в r2 содержимое SRAM по адресу $23 |
| Ld r3,-X | ;загрузить в r3 содержимое SRAM по адресу $22 (X преддекрементируется) |
| Clr r31 | ;очистить старший байт Z |
| Ldi r30, $f0 | ;установить $F0 в младший байт Z |
| Lpm | ;загрузить константу из памяти программ в регистр r0 . Память отмечена в Z |
| Lds r2,$ff00 | ;загрузить r2 содержимым SRAM по адресу $ff00 |
| Add r2, r1 | ;сложить r1 с r2 |
| Sts $ff00,r2 | ;записать обратно |
| Clr r31 | ;очистить старший байт Z |
| Ldi r30,$ff | ;установить младший байт Z |
| lpm | ;загрузить константу в регистр r0 из памяти программ отмеченную Z (r31:r30) |
| Mul r6,r5 | ;перемножить r6 и r5 |
| Mov r6,r1 | ;вернуть результат обратно в r6:r5 |
| Mov r5,r0 |
| Clr r16 | ;очистить r16 |
| Out $18, r16 или Out portb, r16 | ;записать нули в Порт В (где $18 адрес порта В) |
| Nop | ;ожидать (пустая операция) |
| Ser r17 | ;установить r17 |
| Out portb,r17 | ;записать единицы в Порт В |
| Call routine | ;вызвать программу routine | |
| …… | ; | |
| Routine: | Push r14 | ;сохранить r14 в стеке |
| Push r13 | ;сохранить r13 в стеке | |
| …… | ; | |
| Pop r13 | ;восстановить r13 | |
| Pop r14 | ;восстановить r14 | |
| Ret | ;вернуться из подпрограммы |
| e2wait: | Sbic $1c,1 | ;пропустить следующую команду, если EEWE очищен (где $1c –адрес регистра управления EEPROM – EECR) |
| Rjmp e2wait | ;запись EEPROM не завершена | |
| nop | ;продолжать (пустая операция) |
| ;вычесть r1:r0 из r3:r2 | |
| Sub r2,r0 | ;вычесть младший байт |
| Sbc r3,r1 | ;вычесть старший байт с переносом |
| Out $1E,r0 | ;записать адрес EEPROM |
| Sbi $1c,0 | ;установить бит чтения в EECR |
| In r1,$1d | ;считать данные EEPROM |
| Cli | ;запретить прерывания |
| In r13, $16 | ;считать Порт В |
| sei | ;разрешить прерывания |
| Clr r27 | ;очистить старший байт X |
| Ldi r26,$20 | ;установить $20 в младший байт X |
| St X+,r0 | ;сохранить в r0 содержимое SRAM по адресу $20 (X посткрементируется) |
| St X, r1 | ;сохранить в r1 содержимое SRAM по адресу $21 |
| Ldi r26,$23 | ;установить $23 в младший байт X |
| St r2, X | ;сохранить в r2 содержимое SRAM по адресу $23 |
| St r3, -X | ;сохранить в r3 cодержимое SRAM по адресу $22 (X преддекрементируется) |
| Lds r2, $ff00 | ;загрузить в r2 содержимое SRAM по адресу $ff00 |
| Add r2,r1 | ;сложить r1 c r2 |
| Sts $ff00,r2 | ;записать обратно |
| Ldi r16, $10 | ;загрузить десятичное значение 16 в r16 |
| Asr r16 | ;содержимое регистра R16 разделить на 2, т.е. r16=r16/2 |
| Ldi r17, $fc | ;загрузить –4 в r17 |
| Asr r17 | ;r17=r17/2 |