Kurs Asemblera na AVR.doc

(202 KB) Pobierz

Przykład 1 - Przerzutnik RS
Najprostszym przykładem wkorzystania portów wejścia/wyjścia jest układ, który pełniłby funkcję przerzutnika RS. Naciskając przycisk S1 zapalamy kropkę dziesiętną wyświetlacza, a naciskając S2 gasimy ją. Algorytm działania programu jest przedstawiony na poniższym rysunku :

Kod Ľrdłowy programu przedstawiony jest poniżej :

; Kurs asemblera mikrokontrolerów AVR
;
; Przykład 1 - przerzutnik RS

.include "2313def.inc"
.def acc = r16 ; nadanie rejestrowi r16 nazwy symbolicznej
.cseg
.org 0x00

ldi acc, 0b11111111 ; załaduj do acc liczbę 255 (0xff)
out DDRB, acc ; wpisanie do DDRB samych jedynek
; powoduje ustawienie pinów jako wyjść
out PORTB, acc

ldi acc, 0b1111100 ;
out DDRD, acc ; piny D0 i D1 są ustawione jako wejścia
; pozostałe jako wyjścia
ldi acc, 0b1110111
out PORTD, acc ; włączony pierwszy wyświetlacz, wejścia
; podciągnięte do zasilania

sprawdz_klawisze:
sbis PIND, 0 ; jeśli pin D0 = 1, to pomiń następną instrukcję
cbi PORTB, 7
sbis PIND, 1 ; jeśli pin D1 = 1, to pomiń następną instrukcję
sbi PORTB, 7
rjmp sprawdz_klawisze ; skocz do początku sprawdzania klawiszy

 


Instrukcja LDI (Load Immediate) powoduje załadowanie do rejestru roboczego (r16-r31) ośmiobitowej stałej.

Składnia:

Operandy:

Licznik rozkazów:

(i) LDI Rd

16 <= d <=31, 0 <= K <= 255

PC <- PC + 1

Kod instrukcji:
1110 KKKK dddd KKKK


Komentarz:
W naszym przypadku ładujemy do rejestru r16 liczbę 255 (wpisujemy same jedynki).

Instrukcja OUT (Store Register to I/O Location) powoduje zapamiętanie zawartości rejestru roboczego (r0-r31) w rejestrze z obszaru rejestrów wejścia-wyjścia.

Składnia

Operandy

Licznik rozkazów

(i) OUT A,Rr

0 <= r<= 31 0 <= A<= 63

PC = PC + 1

Kod instrukcji:
1011 1Aar rrrr AAAA


Komentarz:
Liczbę uprzednio wpisaną do rejestru r16 wpisujemy do rejestru DDRB, w celu określenia funkcji, jaką mają pełnić poszczególne piny portu B. Niestety nie można bezpośrednio załadować liczby do rejestrów wejścia-wyjścia. Następnie wpisujemy tą samą liczbę do rejestru PORTB, co spowoduje ustawienie na wszystkich pinach stanu wysokiego. Wszystkie segmenty wyświetlacza będą zgaszone.

Instrukcja SBIS (Skip if Bit in I/O Register is Set) powoduje pominięcie następnej instrukcji, jeżeli bit w rejestrze wejścia-wyjścia jest ustawiony.

Składnia

Operandy

Licznik rozkazów

(i)SBIS A,b

0 <=A <= 31, 0 <= b <= 7

PC = PC + 1, Warunek nie spełniony
PC = PC + 2, Pominięcie instrukcji jednosłowowej
PC = PC + 3, Pominięcie instrukcji dwusłowowej


Kod instrukcji:
1001 1011 AAAA Abbb


Komentarz:
Piny D0 i D1 są skonfigurowane jako wejścia i podciągnięte do plusa zasilania przez wewnętrzne rezystory. Uaktywnienie wejścia jest interpretowane jako zwarcie go do masy, tak więc stan niski na danej końcówce wejściowej oznacza naciśnięcie przycisku. Jeżeli pin wejściowy jest w stanie wysokim, oznacza to, że przycisk nie został naciśnięty. Tak więc nie powinna zostać podjęta żadna akcja, czyli mikrokontroler pomija kolejną instrukcję. W naszym przypadku reakcja na naciśnięcie przycisku jest obsłużona przez jedną instrukcję. W przypadku, gdy konieczne jest zastosowanie większej liczby instrukcji, należy zorganizować fragment obsługi w trochę inny sposób. Mianowicie za instrukcją SBIS należy umieścić instrukcję wywołującą procedurę, np. RCALL, i cały fragment kodu obsługujący sposób reakcji na naciśnięcie przycisku należy umiescić w tej procedurze.

Instrukcja CBI (Clear Bit in I/O Register) powoduje wyzerowanie bitu w rejestrze wejścia-wyjścia.

Składnia

Operandy

Licznik rozkazów

CBI A, b

0 <= A <= 31, 0 <= b <= 7

PC <= PC + 1


Kod instrukcji:
1001 1000 AAAA Abbb

Komentarz:
Chcemy, aby po naciśnięciu przycisku S1 zapalona została kropka dziesiętna na wyświetlaczu. Aby to osiągnąć należy ustawić na pinie B7 stan niski.

Instrukcja SBI (Set Bit in I/O Register) powoduje ustawienie bitu w rejestrze wejścia-wyjścia.

Składnia

Operandy

Licznik rozkazów

SBI A, b

0 <= A <= 31, 0 <= b <= 7

PC <= PC + 1

Kod instrukcji:
1001 1010 AAAA Abbb

Komentarz:
Po naciśnięciu przycisku S2 należy zgasić wcześniej zapaloną kropkę. Realizujemy to poprzez ustawienie pinu B7 w stan wysoki.

Instrukcja RJMP (Relative Jump) jest instrukcją bezwarunkowego skoku względnego pod adres z zakresu od PC - 2K + 1 do PC + 2K.

Składnia

Operand

Licznik rozkazów

Stos

(i) RJMP k

2K <=k < 2K

PC =PC + k + 1

Niezmieniony

Kod instrukcji:
1100 kkkk kkkk kkkk

Czas wykonania tej instrukcji - 2 cykle zegarowe.

Program zajmuje 24 bajty w pamięci programu. Dla porównania program realizujący identyczną funkcję napisany w Bascomie zajmuje 138 bajtów, czyli prawie sześciokrotnie więcej! Ukazuje to ogromną przewagę asemblera nad Bascomem, czy w ogóle nad językami wyższego poziomu. Poza tym progam napisany w asemblerze wykonuje się szybciej, a już na pewno mamy pełną kontrolę nad czasem wykonania poszczególnych fragmentów programu, czego nie można powiedzieć o Bascomie.

Przykład 2 - Układ czasowy
Po naciśnięciu przycisku S1 kropka wyświetlacza zapala się na ok. 1 sekundę. Algorytm działania programu przedstawiono na poniższym rysunku :

Kod źródłowy zamieszczony jest poniżej :

; Kurs asemblera mikrokontrolerów AVR
;
; Przykład 2 - Układ czasowy

.include "2313def.inc"
.def acc = r16 ; nadanie rejestrowi r16 nazwy symbolicznej
.cseg
.org 0x00

ldi acc, 0b11111111 ; załaduj do acc liczbę 255 (0xff)
out DDRB, acc ; wpisanie do DDRB samych jedynek
; powoduje ustawienie pinów jako wyjście
out PORTB, acc

ldi acc, 0b1111100 ;
out DDRD, acc ; piny D0 i D1 są ustawione jako wejścia
; pozostałe jako wyjścia
ldi r16, 0b1110111
out PORTD, acc

ldi acc, 127 ;
out SPL, acc ; ustawienie wskaˇnika stosu na 127

sprawdz_klawisze:
sbis PIND, 0 ; jeśli przycisk S1 nie jest wciśnięty
; to pomiń następną instrukcję
rcall led ; w przeciwnym wypadku wywołaj procedurę
; zapalającą diodę
rjmp sprawdz_klawisze ; powróć na początek sprawdzania klawiszy

led:
cbi PORTB, 7 ; zapal kropkę wyświetlacza
ldi acc, 250 ; załaduj do acc czas opóˇnienia
rcall waitms ; i wywołaj procedurę opóˇniającą
rcall waitms ; czterokrotne wywołanie opóˇnienia
rcall waitms ; 250ms da w sumie opóˇnienie ok 1s
rcall waitms ;
sbi PORTB, 7
ret

; Przybliżone czasy opóźnień są podane dla
; rezonatora 4MHz
.def licz1 = r20
.def licz2 = r21
.def licz3 = r22
waitms:
mov licz3, acc ; ustaw czas opóĽnienia
; powtórz n razy pętlę L,
; co da opóˇnienie ok. n * 1 ms
L:
; powtórz 10 razy pętlę L0,
; co da opóĽnienie ok 1ms
ldi licz2, 10
L0:
; powtórz 100 razy pętlę L1,
; co da opóĽnienie ok. 100 us
ldi licz1, 100
L1:
nop ; 1 cykl
dec licz1 ; 1 cykl
brne l1 ; 2 cykle
; koniec pętli L1
dec licz2
brne l0
; koniec pętli L0
dec licz3
brne L
; koniec pętli L
ret

Pierwsza część programu składa się z instrukcji poznanych w przykładzie wcześniejszym, więc nie będę ich tutaj ponownie opisywał.

Instrukcja MOV (Copy registers) kopiuje zawartość jednego rejestru do drugiego. Zawartość rejestru ˇródłowego nie ulega zmianie.

Składnia rozkazu

Operandy

Licznik rozkazów:

(i) MOV Rd,Rr

0 <= d <=31, 0 <= r <= 31

PC <- PC + 1

Kod operacji :

0010 11rd dddd rrrr

Komentarz:
Wartość opóˇnienia przekazujemy przez rejestr r16 i kopiujemy jego zawartość do r22, czyli do licznika pętli. Takie rozwiązanie zostało zastosowane, w celu zachowania zawartości rejestru r16. Pozwoli to na kilkukrotne wywołąnie procedury opóˇniającej o tą samą wartość opóˇnienia bez konieczności każdorazowego ładowania czasu opóˇnienia.

Instrukcja NOP (No operation) nie wykonuję żadnych czynności poza zwiększeniem zawartości licznika rozkazów o 1. Instrukcja jest wykorzystywana do generowania opóˇnień czasowych.

Składnia rozkazu

Operandy

Licznik rozkazów:

(i) NOP

brak

PC <- PC + 1

Kod operacji :

0000 0000 0000 0000

Komentarz:
Pętla L1 ma wnosić opóˇnienie 100us. Ponieważ cykl rozkazowy przy częstotliwości taktowania mikrokontrolera równej 4MHz wynosi 250ns jeden przebieg pętli musi wnieść opóˇnienie 1us, czyli 4 cykli. Ponieważ instrukcje DEC r20 i BRNE L1 razem trwają 3 cykle (przy niespełnieniu waruknu instrukcji BRNE) to za pomocą intrukcji NOP wstawiamy ten jeden brakujący cykl.

Instrukcja BRNE (Branch if not equal) wykonuje skok warunkowy, jeśli flaga zera (Z) jest wyzerowana.

Składnia rozkazu

Operandy

Licznik rozkazów:

BRNE k

-64 <= k <= +63

...
Zgłoś jeśli naruszono regulamin