Microcontrollerul AVR este un MCU tip RISC cu arhitectura Haward fapt ce permite execuţia a majorităţii operaţiilor într-un singur tact. Această performanţă se datoreaz faptului că sunt excluse cheltuielele de timp pentru transferul de date din memoria de program. Excepţii de la regula "execuţia intr-un singur tact" comenzi care operează cu date pe 16 biţi, salturi, transfer a controlului, etc.
O comandă Assembler presupune o acţiune pe care o poate efectua un MC. Comanda deţine un nume şi operanzii de lucru, stîng şi drept. Există comenzi comenzi cu un singur operand sau fără nici un operand.
Operandul stîng serveşte drept destinaţie a rezultatului operaţiei presupusă de comanda respectivă. În calitate de operand poate fi un registru de uz general (R), o constantă (k), oadresă a memoriei sau un registru periferic (P)
Comanda ASM are urmatorul format:
<mnemonica> <operand stang>, <operand drept>
- mnemonica - denumirea comenzii care este o prescurtare de la operaţia pe care o execută.
- operand - adresa de aces la un resurs a Microcontrollerului sau o constantă pentru operaţiile cu constante.
Limbajul ASM presupune că fiecare comandă este direct transferată în cod-maşină. Mnemonica comenzii este de fapt o reprezentare a codului maşina intr-o formă uşor înţeleasă de programator
Pentru operaţiile de transfer operandul drept serveşte ca sursă, iar cel stâng ca destinaţie.
Pentru cele de prelucrare aritmetică sau logică, de regulă se execută operaţia între operanzi, iar rezultatul este stocat in operandul stâng, numit operand destinaţie.
Acesarea prin adrese a operanzilor este de cele mai dese ori incomodă, deaceea ele sunt înlocuite cu nume de constante ce indică adresa resursului pe care îl reprezintă. De exemplu pentru Regiştrii de uz General vom avea constanter cu nume R0, R1, R2... R31. Exemplu de regiştri periferici pot fi PORTA, PINA, DDRA, etc.
De obicei aceste adrese sunt descrise în fişiere speciale care pot fi incluse cu directiva de preprocesare
Aceste fişiere sunt puse la dispoziţie de către compania producător, sau de către producătorul de compilator sau mediu de dezvoltare a programelor.
.include "<tip_mcu>def.inc"
ex: .include "m16def.inc" - include constantele pentru resuresele microcontrollerului ATmega16
Vom evidenţia mai multe moduri de adresare către resursele microcontrollerului:
- Adresarea directă – presupune modificarea datelor direct în registru (COM), în cazul operaţiilor cu un singur operand(LDI,TST)
- Adresare directă cu doi regiştri – presupune adresarea datelor ce se găsesc în doi regiştri concomotent.
- Acces direct la memorie – situaţia cînd un operand este un registru, iar celălalt este o adresă la memorie (LDS, STS).
- Acces direct la periferici – (IN, OUT)
- Adresare indirectă către memorie – modul de adresare presupune situaţia cînd adresa se află în unul din regiştri x, y, şi z.
- Accesul la memoria de date cu predecrementare
- Adresare indirectă cu deplasare
- Adresare directă la constantele din program
- Acces indirect la memoria din program.
Orice operaţie de transfer de date sau prelucrare a datelor presupune participarea a unui registru de uz general. În utilizarea Regiştrilor de uz general vom evidenţia anumite restricţii impuse de arhitectură.
- R0 .. R15 - nu sunt disponibili pentru operaţiile cu constante
- R1:R0 - întotdeauna servesc ca destinaţie a rezultatului a operaţiei MUL, indiferent de operanzi.
- R26 .. R30 - formează 3 perechi de regiştri pentru comenzile ce presupun acces indirect la resursele Microcontrollerului
- R27:R26 - X - XH:XL
- R29:R28 - Y - YH:YL
- R31:R30 - Z - ZH:ZL
Microcontrollerul AVR posedă un set de 90-120 comenzi, care pot fi grupate în următoarele categorii:
- Comenzi pentru operaţii logice;
- Comenzi pentru operaţii aritmetice si de deplasare;
- Comenzi pentru operaţii cu biţii;
- Comenzi pentru operaţii de transfer de date;
- Comenzi pentru operaţii de transfer de control; (salt)
- Comenzi pentru operaţii de control al sistemului;
- Operaţiile logice permit evaluarea operaţiilor logice de tip AND, OR XOR, etc. tot în acest grup intră şi comenzile de calcul a valorilor inverse cum ar fi NEG şi COM. Tot aici va intra comenzile de curăţare şi setare a regiştrilor şi de schimb a adoua tetrade intr-un registru de uz general. toate comenzile din acest set se vor executa intr-un sigur tact de execuţie.
- Operaţiile aritmetice permit evaluarea operaţiilor de aritmetice bază cum ar fi adunarea, scăderea, deplasare stânga şi dreapta, încementare şi decrementare. Toate operaţiile aritmetice se aplică doar la regiştrii de uz general. Evaluarea operaţiilor aritmetice este posibilă pentru operaţii cu valori cu semn şi fără. Toate comenzile din aces set se execută intr-un singur tact cu excepţia celor care operează cu date pe 16 biţi ( 2 baiti), care se vor executa în 2 tacturi maşină.
- Operaţiile cu biţi permit executarea operaţiilor cu biţi pentru Regiştrii de Uz General şi Regiştrii Periferici, precum şi comenzi de modificare a registrului de stare SREG ca un subset suplimentar ceea ce se datorează faptului că lucrul cu aceşti biţi este des utilizat. De menţionat că operarea cu biţii pentru comenzile pentru Regiştrii de uz general şi cele cu perifericile este diferită. Pentru Periferice operandul drept va prezenta numărul bitului pentru modificare, iar pentru Regiştrii de uz general - masca. Toate comenzile din acest set se execută intr-un sigur tact.
- Operaţiile de transfer permit transferul valorii de la operandul drept către operandul stâng. Operanzii vor conţine adrese ce se referă la memoria de Date. Aici vor intra Registrii de uz general, Regiştri Periferici şi memoria RAM. Operaţiile de transfer sunt posibile doar în anumite moduri, după cum urmează:
- Registru Uz General <=> Registru Uz General
- Registru Uz General <=> Registru Periferic
- Registru Uz General <=> Memoria RAM
Tot în acest set de comenzi intră şi comenzile de lucru cu stiva PUSH şi POP. Pentru execuţia acestor comenzi vor fi necesare de la 1 pana 3 tacturi de execuţie, în dependenţă de comandă.
- Operaţiile de transfer de control permit realizarea salturilor conditionate şi necondiţionate. Tot în acest set intră şi comenzile pentru lucrul cu subrutinele de chemare a subrutinelor şi returnare din ele. Comenzile de salt conditionat vor fi de două tipuri salt la o adresa dacă se satisface condiţia şi salt condiţionat peste o comandă numit şi comandă de ignorare a următoarei comenzi. tot în acest set vor intra şi comenzile de comparaţie a operanzilor ce va permite setarea biţilor din registrul de stare SREG, şi este utilizată ca o pre-comandă pentru salturile condiţionate.
- Operaţiile de control al sistemului sunt 3 la număr:
- NOP - Comanda nulă (1 tact)
- SLEEP - transferă Microcontrollerul în regim de consum redus (4 tacturi)
- WDR - resetasrea contorulul Watchdog (1 tact)
În tabelul mai jos vor fi prezetate seturile de comenzi pentru Microcontrollerul seriei AVR Clasic. Comenzile vor fi grupate după tipul de operaţii pe care îl execută. Se va evidenţia mnemonica operaţiei, explicaţie scurtă despre funcţionalitate în varianta engleză şi română, parametrii, numărul de tacturi de execuţie şi flagurile pe care le afectează sau care se ia în consideraţie la evaluarea rezultatului.
Nota: Pentru o versiune mai completă, explicaţii în detaliu şi exemple de utilizare pentru fiecare comandă din setul de comenzi accesaţi site-ul producatorului : http://www.atmel.com/images/doc0856.pdf
- Comenzile aritmetice şi logice
Nr | Comanda | Operanzii | Descrierea | Traducerea | Operaţia | Flags |
1 | ADD | Rd, Rr | Add without carry | Adunarea aritmetică fără transport | Rd->Rd+Rr | Z,C,N,V,H |
2 | ADC | Rd, Rr | Add eith carry | Adunare cu transport | Rd>Rd+Rr+C | Z,C,N,V,H |
3 | ADIW | Rd, k | Add immediate to work | Adunarea constantei la un cuvînt | Rdh:Rdl Rdh:Rdl+K | Z,C,N,V |
4 | SUB | Rd, Rr | Substract without carry | Scaderea fără transport | RdRd-Rr | Z,C,N,V,H |
5 | SUBI | Rd, k | Substract immediate | Diferenţă cu o constantă | RdRd-k | Z,C,N,V,H |
6 | SBC | Rd, Rr | Substract with carry | Scădere cu transport | RdRd-Rr-C | Z,C,N,V,H |
7 | SBCI | Rd, k | Substract immediate with carry | Diferenţă cu constantă şi transport | RdRd-K-C | Z,C,N,V,H |
8 | SBIW | Rd, k | Substract immediate from word | Diferenţa constantei de la cuvînt | Rdh:Rdl Rdh:Rdl-K | Z,C,N,V |
9 | AND | Rd, Rr | Logical And | SI logic | RdRd*Rr | Z,N,V |
10 | ANDI | Rd, k | Logical And with Immediate | SI Logic cu o constantă | RdRd*k | Z,N,V |
11 | OR | Rd, Rr | Logical Or | SAU logic | RdRdRr | Z,N,V |
12 | ORI | Rd, k | Logical Or with Immediate | SAU logic cu constantă | RdRdk | Z,N,V |
13 | EOR | Rd, Rr | Exclusive OR | SAU exclusiv | RdRdRr | Z,N,V |
14 | COM | Rd | One’s complement | Complement faţă de 1 | Rd$FF-Rd | Z,C,N,V |
15 | NEG | Rd | Two’s complement | Negarea complementului binar | Rd$00-Rd | Z,C,N,V,H |
16 | SBR | Rd, k | Set Bits in Register | Setarea bitului K în registru | RdRdk | Z,N,V |
17 | CBR | Rd, k | Clear Bits in Register | Ştergerea bitului K în registru | RdRd*($FF-k) | Z,N,V |
18 | INC | Rd | Increment | Incrementarea | RdRd+1 | Z,N,V |
19 | DEC | Rd | Decrement | Decrementarea | RdRd-1 | Z,N,V |
20 | TST | Rd | Test for zero or minus | Testarea la 0 sau la „-” | RdRd*Rr | Z,N,V |
21 | CLR | Rd | Clear Register | Curăţirea registrului | RdRdRr | Z,N,V |
22 | SER | Rd | Set all bits in register | Setarea biţilor în registru | Rd$FF | None |
- 3. Comenzi pe biti
Nr | Comanda | Operanzi | Descrierea | Traducerea | Operaţia | Flags |
1 | LSL | Rd | Logical Shift Left | Shiftare logică la stinga | Rd(n+1)Rd(n), Rd(0) 0 CRd(7) | Z,C,N,V,H |
2 | LSR | Rd | Logical Shift Righ | Shiftare Logică la dreapta |
Rd(n)Rd(n+1),
Rd(7) 0,
CRd(0) |
Z,C,N,V |
3 | ROL | Rotate left trough carry | Rotare la stinga peste bitul de transport |
Rd(0)C,
Rd(n+1) Rd, CRd(7) |
Z,C,N,V,H | |
4 | ROR | Rd | Rotate right trough carry | Rotare la dreapta peste bitul de transport |
CRd(7)
Rd(n+1) Rd,
C Rd(0) |
Z,C,N,V |
5 | ASR | Rd | Arithmetic Shift Right | Shiftare logică la dreapta |
Rd(n) Rd(n+1)
n=0..6 |
Z,C,N,V |
6 | SWAP | Rd | Swap Nibbles | Inversarea jumătăţilor | Rd(0..3) Rd(4..7) | None |
7 | BSET | s | Flag Set | Setarea flagului | SREG(s) 1 | SREG(s) |
8 | BCLR | s | Flag Cleared | Ştergerea flagului | SREG(s) 0 | SREG(s) |
9 | SBI | P, b | Set bit to I/O | Setarea bitului în registrul I/O | I/O (P,b) 1 | None |
10 | CBI | P,b | Clear bit in I/O Register | Ştergerea bitului din registru I/O | I/O (P,b) 0 | None |
11 | BST | Rd, b | Bit Store from Register to T | Stocarea bitului din registru în flagul T | T | |
12 | BLD | Rd, b | Bit load from T to Register | Încărcarea flagului T in bitul registrului | Rd(b) T | None |
13 | SEC | Set carry Flag | Setarea transportul flagului | C1 | C | |
14 | CLC | Clear carry flag | Stergerea transportul flagului | C0 | C | |
15 | SEN | Set negative flag | Setarea flagului negativ | N1 | N | |
16 | CLN | Cleared Negative flag | Ştergerea flagului negativ | N0 | N | |
17 | SEZ | Set zero flag | Setarea flagului 0 | Z1 | Z | |
18 | CLZ | Clear zero flag | Ştergerea flagului 0 | Z0 | Z | |
19 | SEI | Set global Interrupt flag | Setarea flagului intreruperii globale | I1 | I | |
20 | CLI | Clear global interrupt flag | Ştergerea flagului intreruperii globale | I0 | I | |
21 | SES | Set Signed Flag | Setarea flagului de semn | S1 |
S | |
22 | CLS | Clear Signed Flag | Ştergerea flagului de semn | S0 | S | |
23 | SEV | Set overflow flag | Setarea flagului fluxului de date | V1 | V | |
24 | CLV | Clear overflow | Stergerea flagului fluxului de date | V0 | V | |
25 | SET | Set T flag | Setarea flagului T | T1 | T | |
26 | CLT | Clear T flag | Stergerea flagului T | T0 | T | |
27 | SEH | Set half carry flag | Setarea flagului a jumătăţii bitului de transport | H1 | H | |
28 | CLH | Clear half carry flag | Ştergerea flagului a jumăţăţii bitului de transport | H0 | H | |
- Comenzile de transfer
Nr | Comanda | Operanzi | Descrierea | Traducerea | Operaţia | Flags |
1 | ELPM | Extend Load Program Memory | Extinderea încărcării memoriei de program | Ro=(Z+ELPM) | None | |
2 | MOV | Rd, Rr | Copy Register | Copierea registrului | RdRr | None |
3 | LDI | Rd, K | Load Immediate | Incărcarea constantei | RdK | None |
4 | LDS | Rd, X | Load direct from RAM | Încarcă din RAM | Rd(k) | None |
4 | LD | Rd, x | Load direct | Încărcare directă | Rd(x) | None |
5 | LD | Rd, x+ | Load indirect and post increment | Încarcare indirectă apoi post incrementare |
Rd(x)
x x+1 | None |
6 | LD | Rd, -x | Load Indirect and pre decrement | Încărcare indirectă apoi pre decrementare |
Rd(x)
x x-1 | None |
7 | LD | Rd, Y | Load Indirect | Încărcare indirectă | Rd(Y) | None |
8 | LD | Rd, Y+ | Load Indirect and post increment | Încărcare indirectă apoi post incrementare |
Rd(Y)
Y Y+1 | None |
9 | LD | Rd, -Y | Load Indirect and pre decrement | Încărcare indirectă apoi pre decrementare |
Rd(Y)
YY-1 | None |
10 | LDD | Rd, Y+q | Load indirect with displacement | Încarcare indirectă cu deplasament | Rd(Y+q) | None |
11 | LD | Rd, Z | Load indirect | Încarcă indirect | Rd(Z) | None |
12 | LD | Rd, Z+ | Load indirect and post increment | Încarcă indirect apoi post incrementare |
Rd(Z)
ZZ+1 | None |
13 | LD | Rd, -Z | Load indirect and pre decrement | Încarcă indirect apoi pre decrementare |
Rd(Z)
ZZ-1 | None |
14 | LDD | Rd, Z+q | Load indirect with deplacement | Incarcă indirect cu deplasament | Rd(Z+q) | None |
15 | STS | k, Rr | Store Direct to RAM | Stochează direct in RAM | (k) Rr | None |
16 | ST | X, Rr | Store Indiret | Stochează indirect | (X) Rr | None |
17 | ST | X+, Rr | Store Indirect and post increment | Stocează indirect apoi post incrementare |
Rr(X)
X X+1 | None |
18 | ST | X-, Rr | Store Indirect and pre decrement | Stochează indirect apoi pre decrementează |
Rr(X)
XX-1 | None |
19 | STD | X+q, Rr | Store indirect with deplacement | Stocează indirect cu deplasament | Rr(X+q) | None |
20 | ST | Y, Rr | Store indirect | Stochează indirect | (Y) Rr | None |
21 | ST | Y+, Rr | Store indirect and post increment | Stocheză indirect si post incrementează |
Rd(Y)
Y Y+1 | None |
22 | ST | Y-, Rr | Store indirect and pre decrement | Stochează indirect şi pre decrementează |
Rd(Y)
YY-1 | None |
23 | ST | Rd, Y+q | Store indirect with displacement | Stochează indirectă cu deplasament | Rd(Y+q) | None |
24 | ST | Rd, Z | Store Indiret | Stochează indirect | Rd(Z) | None |
25 | ST | Rd, Z+ | Store indirect and post increment | Stochează indirect apoi pre decrementare |
Rd(Z)
ZZ+1 | None |
26 | ST | Z-, Rr | Store indirect and pre decrement | Stochează indirect apoi pre decrementează |
Rd(Z)
ZZ-1 | None |
27 | ST | Rd, Z+q | Store indirect with deplacement | Stocează indirect cu deplasament | Rr(Z+q) | None |
28 | LPM | Load program memory | Încărcarea memoriei de program | R0(Z) | None | |
29 | IN | Rd, P | Load on I/O Port to Register | Încarcă datele din portul I/O în registru | RdP | None |
30 | OUT | P, Pr | Store Register to I/O port | Stochează datele din registru în Portul I/O | PRd | None |
31 | PUSH | Rr | Push Register on Stack | Pune registrul în stivă | STACKRd | None |
32 | POP | Rd | Pop Register from Stack | Scoate registrul din stivă | RdSTACK | None |
- Comenzile de transfer a controlului executiei
Nr | Comanda | Operanzii | Descrierea | Traducerea | Operaţia | Flags |
23 | CP | Rd, Rk | Compare | Comparare | Rd-Rk | Z,C,N,V,H |
24 | CPC | Rd, Rk | Compare with carry | Compară cu bitul de transport | Rd-Rk-C | Z,C,N,V,H |
25 | CPI | Rd, k | Compare with Immediate | Compară cu o constantă | Rd-K | Z,C,N,V,H |
26 | RJMP | k | Relative Jump | Salt relativ la k | PCPC+K+1 | None |
27 | IJMP | k | Indirect Jump | Salt indirect la k | PCZ | None |
28 | JUMP | k | Jump | Salt necondiţionat | PC K | None |
29 | RCALL | k | Relative Call | Salt relativ la subrutină | PCPC+K+1 | None |
30 | ICALL | k | Indirect Call | Salt indirect la subrutină | PCZ | None |
31 | CALL | k | Call | Apelare rutină | PC K | None |
32 | RET | k | Return from subrutine | Returnare din subrutină | PCstack | None |
33 | RETI | k | Return from Intrerrupt | Returnare din întrerupere | PCstack | I |
34 | CPSE | Rd, Rk | Compare skip if equal | Compară skip daca e egal | If Rd=Rk then PCPC+2 (or 3) | None |
35 | SBRC | Rr, b | Skip if Bit in Register is Clear | Sare dacă bitul din registru este 0 | If Rr (b)=0 then PCPC + 2 (or 3) | None |
36 | SBRS | Rr, b | Skip if Bit in Register is Set | Sare dacă bitul din registru este setat | If Rr (b)=1 then PCPC + 2 (or 3) | None |
37 | SBIC | P,b | Skip if Bit I/O is clear | Sare dacă bitul din registrul I/O este şters | If I/O (P,b)=0 then PCPC + 2 (or 3) | None |
38 | SBIS | P, b | Skip if Bit I/O is set | Sare dacă bitul din registrul I/O este setat | If I/O (P,b)=1 then PCPC + 2 (or 3) | None |
39 | BRBS | s, k | Branch If Bit in SREG is Set | Sare dacă bitul din registrul SREG este setat |
If SREG=1 then
PCPC+k+1 | None |
40 | BRBC | s, k | Branch If Bit in SREG in Cleared | Sare dacă bitul din registrul SREG este şters |
If SREG=0 then
PCPC+k+1 | None |
41 | BREQ | k | Branch if Equal | Salt la egalitate | If Rd=Rr(z=1) then PCPC+k+1 | None |
42 | BRNE | k | Branch if Not Equal | Salt dacă nu este egalitate | If RdRr(z=0) then PCPC+k+1 | None |
44 | BRCS | k | Branch if carry set | Sare dacă transportul este setat |
If C=1 then
PCPC+k+1 | None |
45 | BRCC | k | Branch if carry cleard | Sare dacă transportul este şters |
If C=0 then
PCPC+k+1 | None |
46 | BRSH | k | Branch if Same or Higher | Sare dacă este egal sau mai mare |
If RdRr(C=0) then
PCPC+k+1 | None |
47 | BRLO | k | Branch if Lower | Sare dacă este mai mic |
If Rd<Rr(C=1) then
PCPC+k+1 | None |
48 | BRMI | k | Branch if Minus | Sare dacă este minus |
If N=1 then
PCPC+k+1 | None |
49 | BRPL | k | Branch if Plus | Sare dacă este + |
If N=0 then
PCPC+k+1 | None |
50 | BRGE | k | Branch if Greater or Equal | Sare dacă este mai mare sau egal cu bitul transportului | F RdRr (NV=0)then PCPC+k+1 | None |
51 | BRLT | k | Branch if Less then (Signed) | Sare dacă este mai mic decât , (cu semn) | F Rd<Rr (N1=0)then PCPC+k+1 | None |
52 | BRHS | k | Branch if Half Carry flag is set | Sare dacă jumătate din constanta flagului este setată |
If H=1 then
PCPC+k+1 | None |
53 | BRHC | k | Branch is Half Carry flag is cleared | Sare dacă jumătate dn constanta flagului este ştears |
If H=0 then
PCPC+k+1 | None |
54 | BRTS | k | Branch if T flag is set | Sare dacă flagul T este setat |
If T=1 then
PCPC+k+1 | None |
55 | BRTC | k | Branch if T flag is cleared | Sare dacă flagul T este şters |
If T=0 then
PCPC+k+1 | None |
55 | BRVS | k | Branch if Overflow is set | Sare dacă fluxul de date este setat |
If V=1 then
PCPC+k+1 | None |
56 | BRVC | k | Brach if Overflow is cleared | Sare dacă fluxul de date este şters |
If V=0 then
PCPC+k+1 | None |
57 | BRIE | k | Branch if Intrerrupt is set | Sare dacă întreruperea este setată |
If I=1 then
PCPC+k+1 | None |
58 | BRIC | k | Branch if Intrerrupt is cleared | Sare dacă întreruperea este ştearsă |
If V=0 then
PCPC+k+1 | None |
- 4. Comenzi de control al sistemului
29 | NOP | No operation | Nici o operaţie | None | ||
30 | SLEEP | Sleep | Regimul adormire | None | ||
31 | WDR | Wathdog Reset | Setare regimului wathdog | None |
Niciun comentariu:
Trimiteți un comentariu