Stos jest umieszczony w wewnętrznej pamięci SRAM, a jego efektywny rozmiar zależy od liczby odłożonych na stosbajtów. Bajty są podejmowane ze stosu w kolejności odwrotnej do składania (ten, który ostatni wchodzi, pierwszy wychodzi).
Podczas skoku do podprogramów i przerwań adres powrotu do programu głównego jest automatycznie odkładany przez
mikrokontroler na stos i pobierany przy powrocie do programu głównego.
Na stos można złożyć daną zagrożoną nadpisaniem. Stos jest powszechnie używany do przechowywania rejestrów, które
mogą zostać nadpisane w trakcie obsługi przerwania, ponieważ program główny i przerwanie przeważnie używają tych samych rejestrów.
Po reset-ie stos musi być inicjalizowany (musi zostać wskazany jego początkowy adres).
Przykładowa procedura inicjalizacji stosu wygląda
następująco:
ldi r16, high(RAMEND)
out SPH, r16
ldi r16, low(RAMEND)
out SPL, r16
;złożenie zawartości rejestru r16 na stosie
push r16
;skopiowanie rejestru flagowego SREG do r16 i złożenie na stosie
in r16, SREG
push r16
;podjęcie zawartości rejestru r16 ze stosu
pop r16
;podjęcie zawartości rejestru flagowego SREG ze stosu
out SREG, r16
pop r16
Deklaracja bufora 20 bitowego dla komorki $095 w pamieci RAM
.dseg
Bufor1:.byte20
.org$095
Pętle czasowe - czas można odliczać w pętlach czasowych lub w dedykowanym module liczącym zwanym Timer-em. Odliczanie czasu w pętlach polega na wielokrotnej dekrementacji zawartości rejestru i liczeniu upływającego przy tym czasu.
Przykład petli czasowej
Załadowanie wartości 0 do rejestru 16
ldi r16, 0
Każda etykieta posiada swój adres w kodzie programu i jest wykorzystywana w skokach
etykieta1:
Dekrementacja zawartości rejestru (1-sze wykonanie tego rozkazu daje wyniku wartość 255, ponieważ operacje matematyczne wykonywane są modulo 256)
dec r16
Porównanie zawartości rejestru ze wskazaną liczbą (tu:z zerem)
cpi r16, 0
Skok warunkowy, jeśli w wyniku dekrementacji nie osiągnięto zera, to program skacze do etykiety1, w przeciwnym razie przechodzi do następnej instrukcji (tu: etykieta koniec)
brne etykieta1
koniec:
Liczby - binarne-hexadecymalnie
255 -> 1111111->000000FF
28-> 0011100-> 1C
Konwersja liczb pomiędzy systemami dwójkowym i szesnastkowym jest względnie prosta, stąd nie trzeba nawet kartki papieru aby dokonać obliczeń nawet długich liczb. Zanim jednak zaczniemy zamieniać liczby przyda się mała sciąga, jeżeli nie znasz dobrze obu systemów. Liczby od 0 do 15 w każdym z tych systemów reprezentowane są następująco:
Deklaracja pętli opóźnienia
Ldi r16,0
Ldi r17,0
Ldi r19,20
Petla:
Decr16
Brne petla
Decr17
Brne petla
Decr19
Brne petla
Timer - jego funkcją jest zliczanie impulsów wewnętrznego zegara mikrokontrolera
Timer0 może zliczać impulsy zegarowe CK, impulsy zegarowe podzielone przez N w dzielniku wstępnym CK/N, zbocza narastające lub opadające na linii 0 portu B, jak wyspecyfikowano w rejestrze kontrolnym TCCR0 timera0.
Istnieją trzy sposoby monitorowania zdarzeń timera:
- ciągła obserwacja flagi zdarzenia i wykonanie
związanych z nim procedur w programie głównym
- przerwanie wykonania programu i automatyczny skok
do procedur obsługi przerwania
- automatyczna zmiana stanu na określonej linii wyjściowe
Procesor AT90S8515 posiada timery 8- (timer 0 i 2)i 16-bitowe (timer 1).
Timer 8-bitowy liczy do maksymalnej wartości
28-1=255.
Timer 16-bitowy liczy do maksymalnej wartości
216-1=65535.
Przepełnienie rejestru liczącego
Po przepełnieniu rejestr timera załadowuje się
zerami i wystawiana jest flaga przepełnienia TOVx
(x=0, 1 lub 2) w rejestrze TIFR
Prescaler timera dokonuje wstępnego podziału częstotliwości kwarcu, czyli ustala krok timera. Wartość wstępnego podziału dla timera0 jest ustawiana bitami CS02, CS01, CS00 w rejestrze TCCR0 (patrz kolejny slajd)
Przykład ustawienia prescalera timera 0 do liczenia
nie podzielonych impulsów zegarowych
ldi r16, (1<<CS00)
out TCCR0, r16
Przykład ustawienia prescalera timera 0 do liczenia
impulsów zegarowych podzielonych przez 1024
ldi r16, (1<<CS02) | (1<<CS00)
out TCCR0, r16
Przerwania
1 Najwyższy priorytet ma przerwania RESET,
2 Przerwania zewnętrzne INT0 i INT1 są wywoływane przez stan niski, zbocze narastające lub zbocze opadające na określonych liniach zewnętrznych mikrokontrolera
3 Timer
4 UART
Co to jest UART? (ang. Universal Asynchronous Receiver Transmitter) - układ realizujący dwukierunkową, asynchroniczną transmisję szeregową.transmisję danych między procesorem a urządzeniem zewnętrznym.
Dane są nadawane (i odbierane) w formacie start-stopowym tzn., każdy znak składa się z:
1 bitu startu: logiczne „0”
8 lub 9 bitów danych
1 bitu stopu: logiczna „1”.
9-ty bit danych może zostać wykorzystany jako bit parzystości lub jako dodatkowy bit stopu.
GIMSK, w którym znajdują się maski przerwań zewnętrznych i TIMSK, w którym znajdują się maski przerwań timerów.
Porty mikrokontrolera
Mikrokontroler AT90S8515 posiada 4-ry uniwersalne porty dwukierunkowe (Input/Output): A, B, C, D, z których każdy ma 8 linii. Wyjścia każdej linii portu mogą być obciążone prądem 20mA.
Do obsługi każdego portu zostały przydzielone trzy rejestry: Rejestr kierunkowy o nazwie DDRA (dla portu A) i odpowiednio DDRB dla portu B, DDRC dla portu C, DDRD dla portu D. Rejestr danych PORTA (dla portu A) i odpowiednio PORTB dla portu B, PORTC dla portu C, PORTD dla portu D. Rejestr wejściowy PINA (dla portu A) i odpowiednio PINB dla portu B, PINC dla portu C, PIND dla portu D.
Ldi r16, 0b00000000
Out DDRB, r16
Ldi r16, 0b00001111
Out PORTB, r16
Uaktywnienie przerwania następuje w drodze przez ustawienia odpowiedniego bitu maski w rejestrze TIMSK.
Przykład pokazuje sposób uaktywnienia przerwania timera0 pracującego w trybie zliczania do przepełnienia
Ldi r16, 1<<TOIE0
out TIMSK, r16
sei
sei - set global interrupt flag
cli clear global interupt flag
Flaga globalnego uaktywnienia/zabronienia
przerwań znajduje się w rejestrze SREG (przestrzeńI/O)
Przykład ciągłej obserwacji flagi przepełnienia
timera0 w programie głównym
Loop:
in r16, TIFR
;załaduj zawartość rejestru TIFR do rejestru
roboczego
sbrs r16, TOV0
;przeskocz jedną instrukcję, jeśli bit TOV0 w
rejestrze jest ustawiony („1”)
rjmp loop
;dalsze rozkazy
Przydatne instrukcje:
ROL Rotacja w lewo przez bit przeniesienia C
Przesuwa wszystkie bity w rejestrze Rd o jedną pozycję w lewo. Flaga C jest przesuwana na bit 0. Bit 7 jest przesuwany na flagę C.
Kod rozkazu: ROL Rd gdzie 0 ≤ d ≤ 31
Cykle zegarowe: 1
ROR Rotacja w prawo przez bit przeniesienia C
Przesuwa wszystkie bity w rejestrze Rd o jedną pozycję w prawo. Flaga C jest przesuwana na bit7. Bit 0 jest przesuwany na flagę C.
Kod rozkazu: ROL Rd gdzie 0 ≤ d ≤ 31
Cykle zegarowe: 1
sbrc (skip, if bit in register is cleared) omiń kolejną instrukcję, gdy wskazany bit w rejestrze jest wyzerowany. sbrc Rr, b 0<=r<=31, 0<=b<=7
np.
sbrc r16, 3 ; rozkaz ominięty, jeśli bit 3 w rejestrze r16 jest równy 0
; rozkaz następny
sbrs (skip, if bit in register is set) omiń kolejną
instrukcję, gdy wskazany bit w rejestrze jest
ustawiony sbrs Rr, b 0<=r<=31, 0<=b<=7
np.
sbrs r16, 3
; rozkaz ominięty, jeśli bit 3 w rejestrze r16 jest ustawiony
;rozkaz następny
sbi (set bit in I/O register), ustaw bit w rejestrze w przestrzeni Input/outputsbi A, b 0<=A<=31, 0<=b<=7
np.
sbi portb, 3 ;ustaw linię 3 portu b
cbi (clear bit in I/O register), wyzeruj bit w
rejestrze w przestrzeni Input/output
cbi A, b 0<=A<=31, 0<=b<=7
np. cbi portb, 3 ;wyzeruj linię 3 portu b
ori (logical OR between the contents of a register and a constant) suma logiczna między zawartością rejestru i stałą ori Rd, K 16<=d<=31, 0<=K<=255
np.
jeśli w rejestrze r16 znajdowała się liczba 01010101, to po wykonaniu operacji
ori r16, 0x0F w rejestrze r16 znajduje się liczba 01011111.
Wskutek operacji sumy logicznej młodszy półbajt rejestru r16 został ustawiony, a starszy nie uległ zmianie.
cpi (performs a compare between register Rd and a constant) dokonuje porównania zawartości rejestru Rd ze stałą, instrukcja operuje na fladze Z:
jeśli Rd = K => Z=1, jeśli Rd <>K => Z=0
cpi Rd, K
Po instrukcji cpi można użyć wszystkich instrukcji
warunkowych np. brne lub breq
brne (branch if not equal), skocz, jeśli nierówne
Jeśli rozkaz ten zostanie wykonany bezpośrednio po instrukcji cpi, to program skoczy do wskazanej etykiety wtedy i tylko wtedy, gdy wartość w rejestrze Rd nie jest równa stałej K (flaga Z=0)
np.
cpi r16, 0x03
brne etyk1
;program skoczy do etyk1, jeśli Rd<>K
Przerwania zewnętrzne INT0 i INT1 są powodowane określonym stanem lub zboczem na liniach wejściowych mikrokontrolera PD2 oraz PD3. Bity ISCX1 i ISCX0 w rejestrze MCUCR definiują sposób wywołania przerwania.
Uaktywnienie przerwania zewnętrznego INT0 (lub
INT1) następuje w drodze ustawienia bitu INT0 (lub INT1) w rejestrze GIMSK Konieczne jest również globalne uaktywnienie przerwań w drodze
ustawienia bitu I w rejestrze SREG.
Np..
Ldi r16, 1<<INT0
out GIMSK, r16
RAM wewnętrzny Pamięć RAM jest ulotna, traci zawartość po wyłączeniu napięcia zasilania.
Komórki pamięci RAM są adresowane w trybie 16-bitowym. W tym trybie procesor może zaadresować 216 komórek pamięci. Należy pamiętać o tym, że dane umieszczane w komórkach pamięci mikrokontrolera AT90S8515 są liczbami 8-mio bitowymi.
Adresowanie pamieci RAM
Pamięć RAM może być adresowana bezpośrednio przez podanie adresu w postaci 16-bitowej liczby lub pośrednio z wykorzystaniem 16-bitowych rejestrów X, Y lub Z.
Do czego słuzą rejestry X,Y,Z
X Y Z - symbole rejestrów do adresowania pośredniego.
X = R27 R26 Y = R29 R28 Z = R31 R30
Jako operandy mogą być też użyte symbole X+ Y+ Z+ oznaczające inkrementaję rejestru indeksowego po operacji przesłania lub symbole -X -Y -Z oznaczające dekrementaję rejestru indeksowego przed operacją przesłania
Adresowanie pośrednie odbywa się z udziałem rejestrów X, Y, Z.
Rejestr X składa się z rejestrów r27 (starszy bajt rejestru X) i r26 (młodszy bajt rejestru X).
Rejestr Y składa się z rejestrów r29 (starszy bajt rejestru Y) i r28 (młodszy bajt rejestru Y).
Rejestr Z składa się z rejestrów r31 (starszy bajt rejestru Z) i r30 (młodszy bajt rejestru Z).
Sposoby adresowania RAM
-bezpośrednie przez podanie adresu w postaci 16-bitowej liczby
-pośrednie z wykorzystaniem 16-bitowych rejestrów X, Y lub Z
Adresowanie pośrednie z wykorzystaniem rejestru X -wpis do pamięci
Przed wykonaniem operacji liczba przeznaczona do zapisu
powinna znajdować się w rejestrze roboczym Rr 0<=r<=31,
a adres wpisu w rejestrze X.
ST X, Rr przepisuje zawartość rejestru Rr pod adres
znajdujący się w rejestrze X.
ST X+, Rr przepisuje zawartość rejestru Rr pod adres
znajdujący się w rejestrze X, po operacji
zawartość rejestru X jest zwiększana o 1 (postinkrementacja)
ST -X, Rr przed operacją zawartość rejestru X jest
zmniejszana o 1 (pre-dekrementacja), po czym
zawartość rejestru Rr jest przepisywana pod adres
znajdujący się w rejestrze X.
Adresowanie pośrednie z wykorzystaniem rejestru X -odczyt z pamięci
Przed wykonaniem operacji adres odczytu powinien
znajdować się w rejestrze X.
LD Rr, X przepisuje zawartość komórki pamięci, której
adres znajduje si e w rejestrze X do rejestru Rr
LD Rr, X+ przepisuje zawartość komórki pamięci, której
adres znajduje si e w rejestrze X do rejestru Rr,
po operacji zawartość rejestru X jest zwiększana o 1(post-inkrementacja)
LD Rr, - X przed operacją zawartość rejestru X jest zmniejszana o 1 (pre-dekrementacja), po czym zawartość komórki pamięci, której adres znajduje się w rejestrze X jest przepisywana do rejestru Rr
Adresowanie pośrednie z wykorzystaniem rejestru Y -wpis do pamięci
ST Y, Rr przepisuje zawartość rejestru Rr pod adres znajdujący się w rejestrze Y.
ST Y+, Rr przepisuje zawartość rejestru Rr pod adres
znajdujący się w rejestrze Y, po operacji
zawartość rejestru Y jest zwiększana o 1 (postinkrementacja)
ST -Y, Rr przed operacją zawartość rejestru Y jest zmniejszana o 1 (pre-dekrementacja), po czym
zawartość rejestru Rr jest przepisywana pod adres znajdujący się w rejestrze Y
STD Y+q, Rr przepisuje zawartość rejestru Rr pod adres znajdujący się w rejestrze Y, zwiększony o q, w wyniku operacji zawartość Y nie ulega zmianie
Adresowanie pośrednie z wykorzystaniem rejestru Y -odczyt z pamięci
LD Rr, Y przepisuje zawartość komórki pamięci, której adres znajduje si e w rejestrze Y do rejestru Rr LD Rr, Y+ przepisuje zawartość komórki pamięci, której adres znajduje si e w rejestrze Y do rejestru Rr,
po operacji zawartość rejestru Y jest zwiększana o 1(post-inkrementacja)
LD Rr, - Y przed operacją zawartość rejestru Y jest zmniejszana o 1 (pre-dekrementacja), po czym zawartość komórki pamięci, której adres znajduje się w rejestrze Y jest przepisywana do rejestru Rr LDD Rr, Y+q przepisuje zawartość komórki o adresie znajdującym się w rejestrze Y, zwiększonym o q, do rejestru Rr, w wyniku operacji zawartość Y
nie ulega zmianie
Wewnętrzna nie ulotna pamięć EEPROM
Wewnętrzna pamięć EEPROM procesora AT90S8515 ma 512 bajtów adresowanych od 0 do 512. Rejestry EEARL oraz EEARH (wykorzystywany jest tylko najmłodszy bajt) przechowują adres zapisu/odczytu pamięci EEPROM. W procesie zapisu rejestr EEDR musi zawierać daną do zapisania pod adres zawarty w EEAR (EEARH+EEARL) Zapisanie jednego bajtu w pamięci EEPROM trwa od 2.5 - 4ms (w zależności od napięcia zasilania). W procesie odczytu dana spod adresu umieszczonego w rejestrze EEAR jest przepisywana do rejestru EEDR.
Odczytanie jednego bajtu trwa 4 cykle zegarowe
Proces zapisu:
1.Czekaj na zakończenie poprzedniego zapisu,
sygnalizowane zerowaniem hardware-owym flagi
EEWE.
2. Podaj adres zapisu
3. Podaj liczbę do zapisu
4. Ustaw bit EEMWE
5. Ustaw bit EEWE
Przykład zapisu:
EEPROM-write:
sbic EECR, EEWE
rjmp EEPROM_write
ldi r18, 0
ldi r17, 2
out EERH, r18
out EERL, r17
ldi r18, 0x55
out EEDR, r18
sbi EECR, EEMWE
sbi EECR, EEWE
Wyświetlacz LCD
W układzie uruchomieniowym EVB-503 wyświetlacz LCD nie jest podłączony do mikrokontrolera bezpośrednio, lecz przez dekoder adresów. Mikrokontroler widzi wyświetlacz LCD w przestrzeni adresowej, pod konkretnym adresem ustalonym sprzętowo. Impulsy niezbędne do sterowania wyświetlaczem są generowane sprzętowo przez układy RC, nie są zatem podawane programowo.
Inicjalizacja dekodera adresów polega na ustawieniu najstarszego(7-mego) bitu w rejestrze mcucr. Ponadto ustawia się również bit 6 w rejestrze mcucr, który spowalnia (o 1 impuls zegarowy) obsługę pamięci RAM, dostosowując prędkość obsługi do możliwości pamięci.
Sterownik HD4480 posiada 128-mio znakowy bufor danych DDRAM, przystosowany do obsługi dwóch linii wyświetlacza po 64 znaki w każdej linii (druga linia zaczyna się od adresu DDRAM-u = 64). Wyświetlacz zastosowany w zestawie EVB-503 ma 2 linie po 16-cie znaków w każdej.
Komendy wyświetlacza LCD
Sterownik wyświetlacz LCD obsługuje komendy w następującym formacie (* oznacza dowolny stan):
0 0 1 D/L N F * *
D/L liczba bitów danych interfejsu sterującego: D/L=1 interfejs 8-bitowy, D/L=0 interfejs
4-bitowy,
N liczba wyświetlanych linii: N=1 dwie linie, N=0 jedna linia
F format znaku: F=1 znak 5*10 punktów, F=0 znak 5*7 punktów
(czas wykonania 5ms)
0 0 0 1 S/C R/L * *
S/C S/C=1 przesuwanie napisu bez zmiany zawartości DDRAM-u (pamięci danych
sterownika LCD), S/C=0 przesuwanie kursora bez zmiany zawartości DDAM-u
(pamięci danych sterownika LCD),
R/L R/L=1 przesuwanie w prawo, R/L=0 przesuwanie w lewo
(czas wykonania120 us)
0 0 0 0 1 D C B
D włącza/wyłącza wyświetlacz)
C włącza/wyłącza kursor
B włącza/wyłącza funkcję mrugania kursora
(czas wykonania120 us)
0 0 0 0 0 1 I/D S
I/D ustala kierunek przesuwu kursora: I/D=1w prawo, I/D=0 w lewo
S włącza (S=1) i wyłącza (S=0) funkcję przesuwu napisu podczas zapisu do DDRAM-u (tj. podczas wyświetlania)
(czas wykonania120 us)
0 0 0 0 0 0 1 * ustawia kursor na pozycji początkowej (adres=0).Jeśli napis był przesunięty, ustawia go w pozycji oryginalnej. DDRAM nie ulega zmianie
(czas wykonania 5ms)
0 0 0 0 0 0 0 1
czyści wyświetlacz i ustawia kursor na początku (adres=0)
(czas wykonania 5ms)
1 DD DD DD DD DD DD DD
ustawia adres DDRAMu
(czas wykonania120 us)