Technika mikroprocesorowa Prowadzący: konsultacje: tel. wew.:
dr inż. Maciej Dzieniakowski 306 GE 7880
Treść wykładów: by Mirosław Szczepaniak
Wykład 1
2.10.2007
Przelicznik: DATA IN
DATA OUT
ALU
Procesor: PROGRAM DATA IN
DATA OUT
ALU
DATA BUS
8b pamięć programowa
Układ sterowania zegar
ADDRESS BUS
16b
Podstawowy system mikroprocesorowy
DATA BUS
OUT
DATA
DATA
mikroprocesor
ROM
RAM
I/O
Cykl maszynowy: Cykl maszynowy to cykl, podczas którego następuje wymiana danych między procesorem a pamięcią lub układem wejścia wyjścia (odczyt albo zapis). Fazy:
pobrania
PC → ADDRESS BUS PC → PC + 1 RR → DATA BUS
rozpoznania
rozpoznanie rozkazu, ustawianie sekwencji zdarzeń
wykonania
wykonywanie czynności
Każdy cykl maszynowy trwa tyle samo!!! 1c = N · Tosc c - cykl maszynowy N = 1, 2, 3, 4 .... Tosc - okres oscylatora
PC - Program Counter RR - Rejestr Rozkazu
Wykład 2
9.10.2007
Podstawowe parametry ROM 1. Czas dostępu
tacc - czas dostępu - czas odpowiedzi pamięci od momentu żądania danych do momentu ich otrzymania 2. Pojemność 2n+1
ADDRESS BUS
N ... ... ... ... ... ... 0 0000
POJ = 2n+1 · ORG
[bit] ORG - szerokość komórki [bit]
Pamięć stała: 1. ● ROM - programowane przez producenta pamięci w czasie produkcji, czasami określana jako MROM (Mask programmable ROM). ● PROM (ang. Programmable ROM) - pamięć która może zostać zaprogramowana. Pierwsze pamięci tego typu były programowane przez przepalenie cieniutkich drucików wbudowanych w strukturę (tzw "przepalanie połączeń") ● EPROM (ang. Erasable Programmable ROM) - pamięć, do której zaprogramowania potrzebne jest specjalne urządzenie, zwane programatorem PROM (PROM Programmer albo PROM Burner) kasowana przez naświetlanie ultrafioletem 2 ● E PROM (ang. Electrically Erasable Programmable ROM) - pamięć kasowalna i programowalna elektrycznie.
2. ●
FLASH - pamięć kasowalna i programowalna elektrycznie
Pamięć o dostępie swobodnym RAM ● z podtrzymywaniem ○ wewnętrznym ○ zewnętrznym ● bez podtrzymywania Podtrzymywanie pozwala na zachowanie danych w pamięci mimo odłączenia napięcia zewnętrznego. Mikrokontroler → mikroprocesor + urządzenia I/O ASEMBLER Asembler jest to: ● język programowania niskopoziomowego, ● przetwarzanie tekstu na dane wynikowe w programowaniu niskopoziomowym (asemblacja - odpowiednik kompilacji w językach wysokiego poziomu) Język asembler mnemonic (lub mnemonik) - podstawowy rozkaz zbiór mnemoników - język danego procesora Liczba mnemoników jest ograniczona. mnemonic + adresowanie → język asembler danego procesora mnemonic ● instrukcje transferu ○ mov _,_ (w procesorach 51 po prawej stronie przecinka źródło, po lewej komórka ← docelowa), ○ movc _,_ ○ movx _,_ ○ push ○ pop ● instrukcje arytmetyczne ○ add _,_ (suma) ○ subb _,_ (różnica) ○ mul _,_ (iloczyn) ○ inc _ (inkrementacja) ● instrukcje logiczne ○ anl _,_ (iloczyn logiczny) ○ orl _,_ (suma logiczna) ○ RR _,_ (rotacja w prawo) ● instrukcje sterujące ○ bezwarunkowe ■ ljmp _ (long jump - skok do etykiety _) ■ RET
warunkowe ■ jb _,_ (jump if direct bit is set - skok warunkowy, jeśli docelowy bit jest 1) instrukcje bitowe ○ setb _ (ustaw dany bit na 1) ○ cpl _ (dopełnienie danego bitu, negacja) (więcej instrukcji na końcu) ○
●
Adresowanie Wyróżniamy dwie architektury procesorów: ● von Neumanna (najczęściej komputery RISC, choć nie wszystkie); ● harwardzka (najczęściej komputery CISC); architektura von Neumana ● ●
prostszy asembler (jedna przestrzeń adresowa) możliwość mieszania się pamięci ROM i RAM
architektura harwardzka ● ●
trudniejszy asembler (wiele przestrzeni adresowych) brak możliwości mieszania się pamięci
Obszary pamięci i rejestrów w mikrokontrolerze typu 51 (CISC - architektura harwardzka)
SFR - special function registers - spis rejestrów specjalnych A(ACC) - Podstawowy rejestr procesora typu harwardzkiego (w przeciwieństwie do RISC, gdzie nie ma wyróżnionych rejestrów specjalnych) Adresowanie bezpośrednie mov adr„t”,adr„s” przejście z komórki o adresie s (source) do o adresie t (target) ← W adresowaniu bezpośrednim obsługiwane są tylko LOW RAM i SFR. np. 1. mov 86h,C8h 2. mov 43h,C8h
Adresowanie pośrednie(dotyczy HIGH RAM i LOW RAM)
Adresowanie pośrednie jest wygodne gdy pamięć jest zalokowana jako tablica. W procesorach typu 51 do adresowania pośredniego używa się rejestrów R0-R1, np.: mov R0,#07h mov @R0,a w adresowaniu bezpośrednim odpowiadałoby to instrukcji: mov 07h,a # - oznacza, że za nim stoi wartość ← adresowanie natychmiastowe @ - nakazuje wzięcie zawartości danego rejestru Jeśli użyto rejestrów R (tylko w procesorach 51) to mamy doczynienia z adresowaniem rejestrowym. W procesorach rodziny 51 wyróżniamy 4 banki rejestrów jak poniżej: ... R2
1
R1 R0 R7 R6 R5 R4 R3 R2 R1 00h
R0
0
Wykład 3
16.10.2007
Asembler → mnemoniki + operanty + adresowanie + dyrektywy mnemoniki - proste rozkazy dla procesora; dyrektywy - informacje dla programu tłumaczącego Niektóre zasady w programowaniu w języku asembler: ● etykiety powinny rozpoczynać się w pierwszej kolumnie tekstu, ● etykiety kończą się dwukropkiem → 'etykieta:' , ● należy zachować odstęp jednej spacji: ○ pomiędzy etykietą i mnemonikiem, ○ pomiędzy mnemonikiem a operantem. Program 1 Program ma za zadanie wysyłać z portu P4 na zmianę same 0 albo same 1.
P4
μC piny wyjściowe
01. 02. 03. 04.
petla:
ORG 0000h mov P4,#FFh mov P4,#00h ljmp petla
1. Dyrektywa 'ORG _' wskazuje adres w pamięci, gdzie ma zacząć się program. Podobne działanie ma dyrektywa 'CODE AT _'. 2. Mnemoniki 'mov P4,#FFh' i 'mov P4,#00h' nakazują przekazanie do portu P4 najpierw samych jedynek, a później samych zer. 3. 'ljmp petla' nakazuje skok bezwarunkowy do etykiety 'petla'. Użycie tej instrukcji z etykietą symboliczną jest możliwe tylko po ustaleniu adresu, gdzie zaczyna się program.
Powyższy przykład jest poprawny, aczkolwiek należy zwrócić uwagę, że na tak banalne zadanie zużywana jest cała moc obliczeniowa procesora. Program 2 Program ma przesyłać informacje z portu P5 do portu P4 zgodnie z wykresem: OUT FFh
P5
80h
μC
80h 01. 02. 03. 04. 05. 06. 07.
petla: high: dalej:
FFh
P4
IN
ORG 0000h mov a,P5 jb acc.7, high mov P4, a ljmp dalej mov P4, #80h ljmp petla
Rejestr akumulatora 7 128
0 64
32
MSB
16
8
4
2
1
LSB
Pamiętając, że rejestr akumulatora jest 8-bitowy, należy tylko sprawdzić, czy na ostatnim bicie jest jedynka. Jeśli tak, mamy wartości z zakresu 80h-FFh, więc na wyjściu musi być 80h. Jeśli jest 0, na wyjście przekazujemy sygnał wejściowy. Skok warunkowy 'jb acc.7, high' - sprawdza czy siódmy bit rejestru akumulatora jest jedynką, jeśli tak następuje skok do etykiety high, jeśli nie, program działa dalej. Podobnie jak w poprzednim programie, tutaj także na bardzo proste zadanie jest zużywane 100% mocy obliczeniowej procesora. PORTY Porty - to urządzenia do przesyłania dwustanowych informacji. Mogą być: ● równoległe - służą do równoległego przesyłania bitów, ● szeregowe - służą do szeregowego przesyłania bitów, Z każdego portu równoległego programista ma możliwość zrobienia kilku portów szeregowych (np. z równoległego portu 8-bitowego może zrobić 8 portów szeregowych) Porty mogą być: ● wejściowe ● wyjściowe
dwukierunkowe ● quasi dwukierunkowe Bramki trzystanowe Do szyny danych jednocześnie podłączone są pamięci, urządzenia I/O. Gdyby do tego połączenia używano zwykłych bramek logicznych, które są dwustanowe, przy jednoczesnym nadawaniu danych dochodziłoby do uszkodzeń elementów. ●
Bramki dwustanowe: W takim wypadku następuje zwarcie źródła z górnej bramki do masy w dolnej RAM
IN
Aby uniknąć powyższych przypadków stosuje się bramki trzystanowe. Oprócz stanów logicznych 0 i 1, występuję także trzeci stan - stan wysokiej impedancji (HZ). Bramka jest wtedy wyłączona, a wyłączone tranzystory MOS dają impedancję rzędu MΩ.
Logika sterująca CS - Chip Select
Port wejściowy 7 0
mov a,@DPTR
...........
I7
CL
.................
I0
Dekoder adresowy
ADDRESS BUS
Data Pointer (DPTR) - jedyny 16-bitowy rejestr w procesorach 5, wskazuje na adres w pamięci zewnętrznej, który przekazywany jest przez 16-bitową szynę danych. Służy do adresowania indeksowego. Zatem powyższy mnemonik nakazuje przekazanie zawartości DPTR do akumulatora. Port wyjściowy
CL
D
................
D
O7
...............
O0
Przerzutniki zatrzaskowe typu D
CL (clock) - zegar
Dekoder adresowy
ADDRESS BUS
Wykład 4
23.10.2007
Port dwukierunkowy DATA BUS
μC
OUT
IN
M ULTIPLEKSER
D0 - D7
R/W
CS
Porty quasi dwukierunkowe (quasibidirectional)
bramka 3-stanowa
+Vcc
rezystor pull-up
INTERNAL DATA BUS
Q D Q'
bramka 3-stanowa
OUTPUT (PIN)
Rezystor pull-up/pull-down (podciągający) - rezystory, których jeden koniec podłączony jest albo do źródła napięcia (rezystor pull-up) albo do masy (rezystor pull-down). Zastosowania: ● „czyszczenie” szyny danych z szumów powstałych, gdy podłączone do niej urządzenia znajdują się w stanie wysokiej impedancji, ● likwidowanie rezonansu w liniach długich Linią długą jest każde urządzenie (pierwotnie linie przewodowe), w którym wymiar długości, porównywalny jest z długością fali przebiegu elektrycznego rozchodzącego się w urządzeniu. Przykładem linii długich są m.in. kable koncentryczne Każdy przewód ma własną pojemność, indukcyjność i rezystancję, co może doprowadzić do powstawania rezonansu. Rozwiązaniem jest dołączenia rezystora pull-down.
Działanie portu quasi dwukierunkowego ● jako wejściowy - sygnał '1' na wejściu → przerzutnik D zapamiętuje stan → na wyjściu Q' mamy '0' → tranzystor odcięty → na wyjściu '1' z rezystora pull-up podłączonego do drena. Obie bramki trzystanowe pozostają w stanie wysokiej impedancji. ● jako wyjściowy - ma dwie możliwości: ○ odczytanie stanu z pina, ○ odczytanie stanu z latcha, W zależności od wyboru, sygnał przekazywany jest na szynę danych przez jedną z bramek trzystanowych. Program 3 Program ma spowodować świecenie się kolejnych diod. P4.0
....
....
P4.7
μC
Wersja 1 01. 02. 03. 04. 05. 06. 07.
BEGIN:
ORG 0000h LJMP 1000h ORG 1000h mov a,#FEh mov P4,a rl a, ljmp BEGIN
Program wpisuje do rejestru akumulatora liczbę FEh (254d). W wierszu 6. następuje rotacja bitów w lewo, co przedstawia poniższy rysunek
1
1
1
1
1
1
F
1
0
ACC
E
Program jest napisany teoretycznie dobrze, ale: ● zmiana świecenia diod zmieni się w ciągu kilku cykli maszynowych, czyli niemal niezauważalnie, będziemy widzieli tylko żarzące się wszystkie diody jednocześnie, ● program zużywa 100% mocy obliczeniowej procesora Wersja 2 Wprowadza pętlę opóźniającą, aby efekt działania programu był widoczny 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. djnz
BEGIN:
DELAY: LOOP:
_,_
ORG 0000h LJMP 1000h ORG 1000h mov a,#FEh mov P4,a rl a, lcall DELAY ljmp BEGIN ORG 2000h mov R1, #250d mov R2, #200d djnz R1, loop mov R1, #250d djnz R2, loop RET
- (decrease and jump if bit is not 0) - odejmuje 1 i sprawdza czy bit jest zerem, jeśli nie idzie do podanej etykiety
Zatem w wierszach 11.-12. przypisujemy pewne liczby do rejestrów R1 i R2. W wierszu 13. mamy pętlę, w której każdym obiegu następuje pomniejszenie wartości w R1. Gdy dojdzie do 0, pętla idzie dalej. Zauważmy, że dla zanim zostanie wykonana instrukcja w wierszu 15., pętla z wiersza 13. obiegnie 250 razy. Wiedząc, że wykonanie instrukcji 'djnz' trwa 2 cykle maszynowe (1 cykl to ok. 1μs),a - 'mov' 1 cykl z łatwych obliczeń wynika, że pętla DELAY opóźnia działanie programu o ok. 100 ms.
Mapa pamięci Przykład - obsługa wyświetlacza 8x8. Mamy dwa wyjścia, jedno obsługuje kolumny, drugie wiersze.
D001h D000h
DISPLAY (OUT)
C000h
IN
7FFFh
Program (ROM) movx @DTPR,a #D001h lub #D000h
DATA BUS ADDRESS BUS
dekoder adresowy urządzenie 1
..... urządzenie n
n - liczba podłączonych urządzeń
Wykład 5
30.10.2007
FFFFh A11
8FFFh 8000h 7FFFh
0FFFh 0000h
D7
....
RAM
....
A0
CS
D0
RAM
A11
ROM
D7
....
ROM
....
A0
CS
D0
DEKODER
ADDRESS BUS
DATA BUS
Zaprojektować dekoder, który będzie rozróżniał do którego urządzenia będą wysyłane dane.
FFFFh 1
1
...
1
1
1
1
...
1
1
1
1
...
1
1
1
1
...
1
1
...
8FFFh
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
1
8000h
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
7FFFh
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0 15 M SB
... 0FFFh
... 1
1
... 0000h 0 LSB 0
... 1
1
1
1
... 0
... 1
1
1
1
... 0
0 0 3 4
0
... 1
1
0
0
... 0
0 0 7 8
0
... 0
0 0 11 12
0
Patrząc na najstarszy bit (15) widzimy, że pokazuje on wartość 0 dla pierwszej połowy przestrzeni adresowej (gdzie znajduje się pamięć ROM), natomiast 1 dla drugiej (pamięć RAM), zatem nasz układ mógłby wyglądać następująco:
A0
A11A15
A11
D7
....
RAM
....
A0
CS
D0
A11
D7
....
ROM
....
A0
CS
D0
Jeśli na A15 jest: - 0 → 0 na ROM → ROM aktywny 1 na RAM → RAM nieaktywny - 1 → 0 na RAM → RAM aktywny 1 na ROM → ROM nieaktywny Rozwiązanie spełnia warunki zadania, jednak powoduje, że pamięć ROM i RAM zajmują po połowie przestrzeni adresowej, a nie tyle, ile było początkowo zarezerwowane (dekoder niepełny).
ADDRESS BUS DATA BUS
DEKODER
Dekoder niepełny - dekoder, który rezerwuje całą przestrzeń adresową, uniemożliwiając dalszą rozbudowę systemu. Dekoder pełny - dekoder, który odzwierciedla w przestrzeni adresowej w skali 1:1 przestrzeń adresową urządzeń, którymi steruje. Jest możliwa dalsza rozbudowa systemu Projektując dekoder pełny, jeszcze raz należy spojrzeć na tabele z poprzedniej strony. Zwróćmy uwagę, że 4 najstarsze bity (12-15) jednoznacznie wskazują miejsca pamięci, gdzie znajdują się pamięci ROM i RAM. Zatem nasz dekoder mógłby wyglądać tak:
A15
CS (RAM)
A14 A13 A12
CS (ROM)
Dekodowane są 4 najstarsze bity - dla ROM pokazują 0000, dla RAM → 0001. Reszta przestrzeni adresowej jest wolna.
Przerwania Procesor Maska centralna
Maski indywidualne
M
Flagi
F
Urządzenie
Maska centralna
Rejestr flag
Przerwanie maskowalne
Urządzenie
μP
Maski indywidualne
Urządzenie
Przerwanie niemaskowalne
Wykład 6
06.11.2007
Jak procesor przyjmuje przerwania? Main ... ... ... ... [ instrukcja [ przerwanie [ AP ... ...
Nie ma zależności czasowej pomiędzy przerwaniem, a wykonywanym fragmentem programu głównego LJMP vector vector:
← procesor ustawia wewnętrzny wskaźnik poziomu przerwania
Body
RETI PC ← STOS SP ← SP -(2) LJMP AP
1. Przerwanie nie powoduje zaprzestania wykonywania bieżącej instrukcji, zostanie ona zawsze dokończona. 2. STOS ← AP (na stos dokładany jest adres powrotny - adres następnej instrukcji po tej, w której nastąpiło przerwanie) 3. SP ← (2) (wskaźnik stosu - stack pointer - zostaje zwiększony) 4. Ustawienie flagi poziomu przerwania - jest to wewnętrzna flaga, ustala hierarchię przerwań (tworzona przez producentów, bez dostępu dla programistów). Następnie nie przyjmuje następnych przerwań o takiej samej lub niższej hierarchii. 5. PC ← STOS (AP na szczycie) 6. SP ← SP - (2) 7. LJMP AP
8. Następuje kasowanie wskaźnika poziomu przerwania. Na powyższe czynności programista nie ma najczęściej wpływu. RETI - Return from interupt - używa się tylko do obsługi RET - Return PUSH _ - wstawia na szczyt stosu, SP + 1 POP _ - przekazuje szczyt stosu do rejestru, SP - 1
przerwań,
Należy pamiętać, że podczas wykonywania obsługi przerwania (część BODY na powyższym schemacie) może nastąpić zmiana zawartości rejestrów używanych także w programie głównym, co spowoduje, że po powrocie do programu głównego zawartość rejestrów będzie inna niż przed nastąpieniem przerwania. Dlatego zawartości wspólnych rejestrów należy chronić, np. przechowując ich wartości na stosie. vector: wstawianie wartości rejestrów na stos
odzyskiwanie danych do rejestrów
PUSH A, PUSH B, BODY POP B, POP A, RETI
B A APL APH
...
Ochrona komórki z wewnętrznej pamięci RAM PUSH A mov A, 24h PUSH A POP A mov 24h, A POP A
Przerwanie w trakcie drugiego przerwania ●
Drugie przerwanie znajduje się w hierarchii wyżej niż przerwanie pierwsze. Następuje dokończenie bieżącej instrukcji w Body1, następnie Body1 zostaje uznane za program główny i dalej postępowanie wygląda przy poprzednim przerwaniu.
Main ... ... ... ... [ instrukcja [ przerwanie 1 [ AP1 ... ...
vector1: przerwanie 2 AP2
... Body1 ... [ [ ... RETI ...
... vector2:
Body2 ... [ [ ... RETI ...
Stos wygląda wtedy następująco:
APL2 APH2 APL1 APH1 ...
●
Drugie przerwanie znajduje się w hierarchii niżej lub na tym samym poziomie Procesor ignoruje flagę, wykonuje Body1, wraca do programu głównego. Żądanie przerwania przyjmuje dopiero podczas wykonywania następnej instrukcji.
Main ... ... ... ... [ instrukcja [ przerwanie 1 [ AP1 [ ...
... vector1: przerwanie 2
Body1 ... [ [ ... RETI ...
AP2
... vector2:
Body2 RETI ...
Na podobnej zasadzie działa wywołanie procedury (call, lcall, ...), z taką różnicą, że obsługę przerwania kończy instrukcja RETI, a procedurę kończy RET. Podczas wykonywania procedury nie ma także żadnej wewnętrznej flagi określającej hierarchię (jak flaga poziomu przerwania w przypadku przerwań)
Wykład 7
20.11.2007
Rejestry adresowalne bitowo - znajdują się tam rejestry bitów, do których można odwołać się bezpośrednio rejestr.bit (np. rejestry portów) Rejestry nieadresowalne bitowo - nie można odwoływać się do pojedynczych bitów tych rejestrów, należy „wyciągnąć” całą zawartość rejestru. Spis rejestrów adresowalnych i nieadresowalnych bitowo podaje producent. Program 4 Napisać program, który po naciśnięciu przycisku, będzie powodował zmianę stanu diody.
5V 5V
P5.0
AAA
P3.2
CPL P 5.0
BBB
P3.2 P5.0
AAA CPL P 5.0
Wersja bez wykorzystania przerwań 01. 02. 03. 04. 05. 06. 07.
AAA: BBB:
ORG 0000h LJMP 1000h ORG 1000h JB P3.2,AAA CPL P5.0 JNB P3.2,BBB LJMP AAA
Program wykorzystuje 100% mocy obliczeniowej procesora. Wersja z wykorzystaniem przerwań maska indywidualna ''1''
priority IED EX0
''0'' IT0
flaga przerwania
bit konfiguracyjny CPU (sprawdzanie flag w każdym cyklu maszynowym) EAL
maska centralna (Enable All)
1 → zbocze opadające ustawia flagę przerwania 0 → stan niski (statyczny) ustawia flagę przerwania Flagi przerwań są ustawiane zawsze, programista nie ma na to wpływu. Może jedynie przesłonić (lub nie) flagę maską. Podczas używania przerwań w programach należy pamiętać o: 1. Inicjalizacji hardware'owego generatora przerwań 2. Ustaleniu hierarchii (hierarchii się nie ustawia dla obsługi jednego przerwania) 3. Zezwoleniu na przerwania (zdjęcie/założenie maski) 1 → maska zdjęta (zezwolenie na przerwania) 0 → maska założona (brak zezwolenia)
01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. ● ● ● ●
ORG 0000h LJMP 1000h ORG 1000h SETB SETB SETB MAIN: LJMP
IT0 EX0 EAL MAIN
ORG 0003h LJMP 2000h ORG 2000h CPL P5.0 RETI
wiersz 05. → inicjalizacja generatora przerwań, wiersz 06. → zezwolenie na przerwanie (zdjęcie maski indywidualnej) wiersz 07. → zezwolenie na przerwanie (zdjęcie maski centralnej) na niebiesko zaznaczono implementację obsługi przerwania: ○ 0003h - wektor przerwania zewnętrznego ○ RETI - wyjście i powrót do pętli MAIN
Zakładając, że przycisk będzie wciskany co 100ms, a na procesor wykona program po 11μs (6 CM na operacje automatyczne, 1 CM na instrukcję CPL i 2 CM na instrukcje LJMP i RETI; 1 CM ≈ 1μs), to procesor zajmie się zapalaniem diody raz na 10 000 μs. Czyli na wykonanie tego zadania zużywa się ok. 0,01% procesora. Z punktu widzenia jednostki centralnej wszystkie przerwania są zewnętrzne. Spotykany jest jeszcze inny podział: na przerwania wewnętrzne (pochodzące z hardware'u mikrokontrolera) i zewnętrzne (pochodzące ze świata zewnętrznego)
Wykład 8
27.11.2007
TIMER/COUNTER
dwa 8-bitowe rejestry liczące flaga przerwania
CM
C/T
TLX
Tx
THX
TFX
PIN TRx
GATE
PIN
≥
&
- bity w rejestrach konfiguracyjnych przełącznik włączony, gdy na wyjściu bramki AND jest 1
TRx - bit startowy
Może zliczać 216 cykli maszynowych (timer) lub 216 sygnałów pojawiających się na pinie (counter). Gdy rejestry zostaną przepełnione (FFFFh) następuje wyzerowanie liczników i flaga przerwania ustawiana jest na 1. Jednak, ponieważ możemy zmieniać zawartości rejestrów liczących, zatem możemy skrócić cykle:
zawartość TLX i TLH
zawartość TLX i TLH
FFFFh
FFFFh TFX
TFX
Rejestry konfiguracyjne 0
7
GATE
C/T
M1
M0
GATE
C/T
M1
← TMOD rejestr nieadresowalny bitowo
M0
bity 0-3 ← Timer 0 bity 4-7 ← Timer 1 0
7
TF1
TR1
TF0
TR0
x
x
x
M1
M0
0
0
Licznik 8-bitowy
0
1
Licznik 16-bitowy
1
0
Licznik 8-bitowy z automatycznym przeładowaniem
1
1
x
← TCON rejestr adresowalny bitowo
Ustawiając flagi TF0 i TF1 można software'owo zainicjalizować przerwanie! Program 5 Program ma spowodować świecenie się kolejnych diod. P4.0
.... P4.7
μC
....
Wersja napisana wcześniej (patrz Program 3) zajmowała 100% mocy obliczeniowej procesora. Użycie timera rozwiązuje ten problem.
01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
ORG 0000h LJMP 1000h ORG 1000h
MAIN:
MOV a,#FEh MOV TMOD,#01h SETB TR0 SETB ET0 SETB EAL LJMP MAIN ORG 000Bh LJMP 2000h ORG 2000h MOV P4,a RL a MOV THO,#WARTOSC1 MOV TL0,#WARTOSC2 RETI
● ●
● ●
wiersz 05. - ustawienie warunków początkowych - zapisanie do akumulatora liczby FEh wiersze 06-07 - inicjalizacja hardware'u wiersz 06 → ustawia każdy bit w rejestrze TMOD na 0, z wyjątkiem bitu LSB, który jest 1, czyli ustawiony jest 16-bitowy tryb pracy timera 0 (bit M1 - 0, bit M0 -1) wiersze 08-09 - inicjalizacja przerwań (08. → zdjęcie maski timera 0, 09. → zdjęcie maski głównej) na niebiesko zaznaczono implementację obsługi przerwania, ○ 000Bh → wektor obsługi przerwania timera ○ wiersze 18.-19. wyznaczają wartości początkowe, Zauważmy, że kod zaznaczony na niebiesko zajmie procesorowi ok. 10 cykli. Zatem, jeśli zadamy takie wartości początkowe żeby zmiana zapalenia diody następowała co 50 ms, to zużycie procesora będzie rzędu 2%.
Wykład 9
4.12.2007
Program 6 5V
P5.1 P3.2 P3.2
P5.1
Na P5.0 ma być generowany sygnał prostokątny o półokresie 1s tak jak przedstawia wykres.
01. 02. 03. 04. 05. 06.
ORG 0000h LJMP 1000h ORG 1000h D50L EQH B0h D50H EQH 3Ch
07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.
MOV TMOD,#01h SETB TR0 MOV TLO,#D50L MOV TH0,#D50H SETB ET0 SETB EAL MOV R0,#14h MAIN: LJMP MAIN
BBB: CCC: ● ●
● ●
●
ORG 000Bh LJMP 2000h ORG 2000h JNB P3.2, BBB CLR P5.1 RETI DJNZ R0,CCC MOV R0,#14h CPL P5.1 RETI
wiersze 05.-06. → przypisanie zmiennym wartości, wiersze 08.-11. → inicjalizacja timera, wartości zapisane do rejestrów liczących TL0 i TH0 określają ile cykli ma zliczyć timer (w tym wypadku zapełnienie timera będzie trwać 50ms) wiersze 12.-13. → inicjalizacja przerwań, wiersz 14. i 25. → zapisanie do rejestru R0 ile razy timer ma się przepełnić, aby program nie przeszedł od razu do wykonywania pętli CCC, tylko zmienił sygnał na P5.1 (w tym wypadku po 20 razach, czyli sygnał będzie się zmieniał co 20 x 50ms = 1s), wiersze 18.-27. → obsługa przerwania. Program 7 5V
5V P5.6
P3.0
01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15.
ORG 0000h LJMP 1000h ORG 1000h WARTOSC_L EQH ... WARTOSC_H EQH ... MOV TMOD,#01h SETB TR0 MOV TLO,#WARTOSC_L MOV TH0,#WARTOSC_H SETB ET0 SETB EAL
Dioda ma się palić, tylko gdy przycisk jest wciśnięty.
16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
MAIN: LJMP MAIN
AAA: BBB: ● ● ● ●
ORG 000Bh LJMP 2000h ORG 2000h JB P3.0, AAA CLR P5.6 LJMP BBB SETB P5.6 RETI
wiersze 05.-06. → przypisanie zmiennym wartości, wiersze 08.-11. → inicjalizacja timera, wiersze 12.-13. → inicjalizacja przerwań, wiersze 18.-25. → obsługa przerwania. ○ wiersz 21. → sprawdza czy przycisk jest włączony, jeśli tak to ustawia 0 w P5.6 i dioda się świeci, jeśli nie, skacze do pętli AAA i ustawia 1 na P5.6 i dioda się nie świeci.
Wykład 10
11.12.2007
Rejestry stanu procesora i znaczniki Rejestry stanu przechowują bity stanu mówiące np. o przepełnieniu rejestrów procesora: 0
7
CY
AC
F0
RS1
RS0
OV
F1
← PSW
P
PSW - Program Status Word Bity charakterystyczne dla wszystkich procesorów: ● CY (lub C) - carry/borrow - przeniesienie/pożyczka ● AC - auxillary carry - pomocniczy bit przeniesienia ● P - pairity bit - bit parzystości ● OV - Overflow - przpełnienie Dla procesorów rodziny 51: ● RS1 i RS0 - bity określające bank rejestrów wg tabeli poniżej: RS1 RS0
bank
0
0
0
0
1
1
1
0
2
1
1
3
rejestr R0 R1 R2 ... R7 R0 ... R7 R0 ... R7 ... R7
bank 0 0 0
adres pamięci 00h 01h 02h
0 1
07h 08h
1 2
0Fh 10h
2
17h
3
1Fh
Przykład ORG 0000h LJMP 1000h ORG 1000h MOV R7,#43h SETB RS1 MOV a,R7
← zapisuje do rejestru R7 w banku 0 wartość 43h ← ustawia bit RS1 na 1 → bank 2 ← przeniesienie zawartości rejestru R7 banku 3 do akumulatora
... ●
F0, F1 - flagi ogólnodostępne
Bit CY - jako znacznik przeniesienia, wykorzystywany jest przy wykonywaniu operacji dodawania. Ustawiany: ● na 1: ○ jeśli wynik dodawania przekracza zakres słowa obsługiwanego przez procesor (w 51 - 8 bitów), ● na 0: ○ jeśli wynik dodawania mieści się w zakresie słowa obsługiwanego przez procesor. Bit CY - jako znacznik pożyczki, wykorzystywany jest przy wykonywaniu operacji odejmowania (procesor wykonuje operacje dodawania/odejmowania bez znaków!) . Ustawiany: ● na 1: ○ jeśli odjemna jest mniejsza niż odjemnik, ● na 0: ○ jeśli odjemna jest większa niż odjemnik. Bit AC - pomocniczy bit przeniesienia - spełnia podobną rolę co bit CY, tylko stosowany jest do operacji w kodzie BCD, natomiast znacznik C - dla kodu naturalnego binarnego. Znacznik OV (overflow) - bit przepełnienia. Używany do operacji ze znakiem. Ustawiony na 1: ● jeśli jest przeniesienie z pozycji 7. na wyższą i jednocześnie nie z 6. na 7. ● jeśli jest przeniesienie z pozycji 6. na 7. i jednocześnie nie z 7. na 8. P - bit parzystości. Ustawiany na 1 jeśli w wyniku jest parzysta liczba „jedynek”. Należy pamiętać, że znaczniki nie są ustawiane po wykonaniu każdej operacji. Na znaczniki wpływają najczęściej instrukcje logiczne i arytmetyczne.
Wykład 11
18.12.2007
Program 8 Napisać program dodający dwie 8-bitowe liczby jak na schemacie:
→ P3
P5 → low
→ P4
P6 → high
Wersja 1 01. 02. 03.
ORG 0000h LJMP 1000h ORG 0000H
04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14.
MOV P5, #00h MOV P6, #00h BBB:
AAA:
● ●
MOV a,P3 ADD a,P4 MOV P5,a JC AAA CLR P6.0 LJMP BBB SETB P6.0 LJMP BBB
samo dodawanie P3 do P4 odbywa się w wierszach 07.-08. (w procesorach rodziny 51 dodawanie musi się odbyć w akumulatorze) JC _ - jeśli znacznik przeniesienia jest równy jeden następuje skok do etykiety/ adresu _
Wersja 2 01. 02. 03.
ORG 0000h LJMP 1000h ORG 0000h
04. 05. 06. 07. 08. 09. 10. 11.
MOV P5, #00h MOV P6, #00h BBB:
MOV a,P3 ADD a,P4 MOV P5,a MOV P6.0,C LJMP BBB
Obie wersje zajmują 100% mocy obliczeniowej procesora.
Program 9 Napisać program dodający liczbę 8-bitową i 16-bitową jak na schemacie: R1 + R4 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18.
R5
R0
liczba 16-bitowa
R2
liczba 8-bitowa
R6
ORG 0000h LJMP 1000h ORG 0000h MAIN: LCALL DOD16P8 LJMP MAIN
AAA: BBB: ● ●
MOV a,R0 ADD a,R2 MOV R4,a MOV a, R1 ADDC a,#00h MOV R5,a JC AAA MOV R6,#00h LJMP BBB MOV R6,#01h RET
dodaj do akumulatora z przeniesieniem (patrz na końcu skryptu) program zużywa 100% mocy obliczeniowej procesora ADDC a,__ -
Wykład 12
8.01.2008
Przetwornik analogowo/cyfrowy pin
MUX
S&H
Rejestr wyjściowy
ADC
(w 51 - ADDAT)
VREF+
VREF-
MUX - multiplekser S&H - Sample And Hold ADC - Analog Digital Converter - przetwornik z kompensacją wagową, najczęściej 12-14 bitowy VREF - wartości referencyjne napięcia określające zakres przetwarzania przetwornika
Rejestr konfiguracyjny ADCON (rodzina 515) 7
0 x
x
x
BSY ADM MX2
MX1
MX0
ADCON jest rejestrem adresowalnym bitowo. BSY - flaga zajętości (busy) Ustawiana jest na 1 przez hardware przetwornika gdy przetwornik pracuje ADM - tryb konwersji Ustawiona na 1 → po starcie następuje stałe przetwarzanie Ustawiona na 0 → konwersja jednokrotna start → konwersja → stop MX2 MX1 - sterowanie multipleksera (wybór kanału wejściowego) MX0 Rejestr DAPR - służy do ustawiania wartości referencyjnych, wpisanie dowolnej wartości spowoduje start przetwornika np.: mov DAPR,#00h
spowoduje ustawienie górnej wartości na wartość napięcia zas. = 5V, natomiast dolna wartość = 0V. Program 10 Zmierzyć wartość analogową napięcia na M6 i przesłanie na P4 wartości w kodzie BCD. Wersja 1 00. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12.
ORG 0000h LJMP 1000h ORG 1000h CLR ADM SETB MX2 SETB MX1 CLR MX0 BBB: AAA:
● ● ● ● ● ●
MOV DAPR,#00h JB BSY,AAA MOV P4,ADDAT LJMP BBB
wiersz 04. → inicjalizacja hardware'u, wiersze 05. - 07. → ustawienie wejścia M6 multipleksera wiersz 09. → ustawienie VREF 0-5V, start przetwornika wiersz 10. → pętla czekająca na koniec pracy przetwornika wiersz 11. → transfer na P4 program zużywa 100% mocy obliczeniowej procesora
Wersja 2 00. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35.
ORG 0000h LJMP 1000h ORG 1000h MOV TL0,#wartoscL MOV TH0,#wartoscH MOV TMOD, #01h SETB TR0 CLR ADM SETB MX2 SETB MX1 CLR MX0 SETB ET0 SETB EADC SETB EAL MAIN: LJMP MAIN ORG 000Bh LJMP 2000h ORG 2000h MOV TL0,#wartoscL MOV TH0,#wartoscH MOC DAPR,#00h RETI ORG 00H3h LJMP 3000h ORG 3000h MOV P4,ADDAT CLR IADC RETI
●
●
działanie tego programu opiera się na wykorzystaniu przerwań timera i przetwornika: co pewien czas (określony przez programistę) timer startuje przetwornik, który po skończeniu pracy wywołuje własne przerwanie, podczas którego następuje przekazanie wartości na P4, należy pamiętać, że flagę przerwania przetwornika IADC należy zdjąć software'owo
Wersja 3 00. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12.
ORG 0000h LJMP 1000h ORG 1000h MOV TL0,#wartoscL MOV TH0,#wartoscH MOV TMOD, #01h SETB TR0 CLR ADM SETB MX2 SETB MX1 CLR MX0
13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27.
SETB ET0 SETB EAL MAIN: LJMP MAIN ORG 000Bh LJMP 2000h ORG 2000h MOV P4,ADDAT MOV TL0,#wartoscL MOV TH0,#wartoscH MOC DAPR,#00h RETI ●
w tej wersji następuje przekazanie wartości na P4 z opóźnieniem - przerwanie timera najpierw przekazuje wartość na P4 (za pierwszym razem będzie to 0) a dopiero później startuje przetwornik. Zatem otrzymujemy wartość z opóźnieniem o jeden okres timera.
Wykład 13 Połączenie typu point-to-point
Magistrala (bus)
15.01.2008
Magistrale: ● wewnętrzne: ○ równoległe: ■ ISA, ■ PCI, ■ AGP, ○ szeregowe: ■ 1-wire, 2 ■ IC ● zewnętrzne: ○ równoległe: ■ HPIB, ■ PCMCIA, ■ Centronics, ○ szeregowe: ■ RS485, ■ USB, ■ CAN. Żeby wejść na magistrale potrzebny jest interfejs - hardware i software Magistrala równoległa:
Połączenie asynchroniczne
W zasadzie jest to połączenie point-to-point Interfejs szeregowy rejestr przesuwny zegar
B0
OUT
B7 D0
D7
INTERNAL DATA BUS
zegar
D0
D7
IN
Zazwyczaj transfer jest 8 bitowy lub 9 bitowy (8 bitów + bit parzystości, jak na powyższym schemacie). Podczas trwania transmisji każdy bit jest 3 razy próbkowany. Jeśli 2 kolejne próbki nie są takie same, to transmisja jest wstrzymywana. Ramka transmisji - 10 bitów Bond rate [Hz] - częstotliwość przekazywania bitów ramki (nie danych)
Master nadaje - wszystkie slave'y odbierają, po przekazaniu adresu dane odbiera tylko slave docelowy, reszta przechodzi w stan uśpienia. Jeśli na 9 bicie paczki jest 1 → jest nadawany adres, jeśli 0 → są nadawane dane.
MASTER 1
SLAVE 1
SDA
SLAVE N
MASTER N
SLAVE 2
SCL
SDA
SCL
SDA
SCL
SDA
SCL
22.01.2008
SDA
SCL
Wykład 14
I2C (Inter-Integrated Circuit bus) –opracowano w firmie Philips, pozwala na komunikację pomiędzy różnymi układami za pomocą dwuprzewodowej magistrali. Układami tymi mogą być np: pamięci (EEPROM, RAM), multipleksery, porty I/O, sterowniki wyświetlaczy LED, przetworniki A/C, układy zegarów i inne. Magistrala składa się z dwóch dwukierunkowych linii: SDA – linia służąca do transmisji danych, SCL – linia impulsów zegarowych. Układy są dołączane do tych linii bezpośrednio Układy pracują w jednym z dwóch trybów: Master – układ może przejąć kontrolę nad magistralą i przebiegiem transmisji danych, jego zadaniem jest wysyłanie sekwencji start i stop; wytwarza sygn. zegarowy. Slave – układ jest dopuszczany do transmisji danych przez urządzenie master.
VDD
Rp
Master
Slave 1
Slave 2
Slave 3 SDA
SCL
SDA
SCL
SDA
SCL
SDA
SCL
Rp
SCL SDA Do innych układów Master i/lub Slave
Do innych układów Master i/lub Slave
Każdy z układów posiadających interfejs I2C ma własny adres, który jest sprzętowo ustalony przez producenta, jakkolwiek użytkownik może wpływać na część nastawy tego adresu (np. za pomocą DIP-switch; ustawia się zazwyczaj 3 najmłodsze bity). Urządzenia podłączane mogą też być wykonane w różnych technologiach (np. NMOS, CMOS, TTL, ...). I2C jest interfejsem multi-master, tzn. że możliwe jest zastosowanie wielu układów typu master podłączonych do jednej magistrali. Transmisja może się odbywać bardzo wolno, można ją także wstrzymać bez żadnych konsekwencji. Górna granica szybkości transmisji: - 100 kb/s – w trybie standard, - 400 kb/s – w trybie fast, - 3,4 Mb/s – w trybie high speed. W specyfikacji interfejsu nie jest określona maksymalna liczba urządzeń,które można podłączyć do magistrali. Ograniczeniem jest tylko suma pojemności pasożytniczych i wejściowych układów, która nie powinna przekraczać 400pF dla każdej linii sygnałowej. Standard określa również takie parametry jak np: - max. i min. częstotliwość sygnału SCL, - min. czas pomiędzy sygn. START i STOP, - min. czas trwania wysokiego i niskiego stanu sygnału SCL, - czas narastania i opadania zboczy sygnałów SDA i SCL, - czas oczekiwania po wysłaniu sygnału START, - czas ustalenia po powtórnym wysłaniu sygn. START. Budowa portów ● Linie SDA i SCL są dwukierunkowymi liniami podłączonymi do dodatniego napięcia zasilania przez rezystory podciągające (pull-up). ● Kiedy magistrala jest wolna obie linie są w stanie wysokim. ● Porty – typu otwarty dren (lub otwarty kolektor), tak aby można było wykonać operację iloczynu logicznego na drucie (wired-AND).
Transmija danych ● Dane przesyłane sformatowane są w ramki o długości 8 bitów. ● Liczba przesyłanych bajtów jest zmienna i zależy od układów zastosowanych w systemie. ● Zwykle po każdym bajcie następuje jego potwierdzenie (ACK–acknowledge). ● Gdy przesyłamy słowa dłuższe niż jednobajtowe, to jako pierwszy przesyłany jest zawsze bajt bardziej znaczący (MSB). ● Transmisja może być wstrzymana (np. gdy posiada niższy priorytet) poprzez wymuszenie na linii SCL stanu niskiego. Sekwencje START i STOP
Sygnał stopu (końca transmisji)
Sygnał startu (początku transmisji)
SDA
SDA
SCL
SCL
Układ master synchronizuje przesył za pomocą sygnału na linii SCL. Stan na linii SDA musi być ustalony przed pojawieniem się „1” na linii SCL i powinien trwać stabilnie przy opadającym zboczu SCL. Sekwencja przesyłania jednego bitu
SDA
SCL
obszar stabilnego stanu linii danych
obszar zmian stanu linii danych
Typowa ramka danych wraz z niezbędnymi sekwencjami sterującymi
Po sygnale START układ master najczęściej wysyła adres docelowego układu slave i oczekuje potwierdzenia gotowości z jego strony za pomocą sygnału ACK. W praktyce odbiór ACK odbywa się w taki sposób, że master ustawia linię SDA na „1” i generuje 9-ty impuls zegarowy. Układ slave odbierając ten impuls wymusza stan niski na SDA. Ta zmiana jest traktowana jako potwierdzenie gotowości do nadawania lub odebranie bajtu danych. Jeśli po wysłaniu adresu slave nie generuje sygnału ACK, linia SDA musi być ustawiona przez niego na „1”. W takim przypadku master powinien wygenerować STOP, zwalniając magistralę. Jeśli dane są wysyłane przez slave’a a odbierane przez master’a,to wysłanie przez ten układ bitu braku potwierdzenia jest informacją dla slave’a (nadającego dane), że zakończono właśnie transmisję ostatniego bajtu danych. Wtedy slave zwalnia linię danych SDA, by umożliwić układowi master wysłanie sygnału STOP. Formanty ramek danych: Dane mogą być przesyłane następująco: Sposób przesyłania danych z układu master do slave.
Odczyt danych z układu slave przez master bezpośrednio po przesłaniu bajtu adresu.
R/W - bit kierunku przesyłania danych (0 = zapis; 1 = odczyt) ACK - potwierdzenie przesłane przez układ slave – „0” – SDA w stanie niskim NACK - potwierdzenie przesłane przez układ slave – „1” – SDA w stanie wysokim Arbitraż – konfiguracje multi-master W większości przypadków arbitraż nie jest potrzebny ponieważ transmisja danych może być zainicjowana przez master’a tylko wtedy, gdy magistrala jest wolna. Jednak, gdy dwa urządzenia master jednocześnie wygenerują sygnał START, wówczas arbitraż jest niezbędny.
Arbitraż przeprowadzony dla dwóch układów master: master_1 przegrywa podczas transmisji trzeciego bitu. Dzieje się tak, ponieważ stan wewnętrznej linii danych (DANE_1) nie jest zgodny ze stanem lini SDA. Arbitaraż przegrywa ten master, który pierwszy nada 0.
Lista rozkazów mikrokontrolerów rodziny MCS-51 Instrukcje arytmetyczne Mnemonik Argumenty ADD
Wykonywane operacje
Cykle Rozmiar maszynowe [bajty]
Opis
''Add to acummulator'' – dodaj do akumulatora. Do wartości przechowywanej w akumulatorze dodawany jest wskazany argument, a wynik zostaje wpisany do akumulatora.
ADD
A,Rn
(A)←(A)+(Rn)
1
1
Do akumulatora dodawana jest zawartość rejestru Rn.
ADD
A,addr8
(A)←(A)+(addr8)
1
2
Do akumulatora dodawana jest zawartość komórki w wewnętrznym RAM.
ADD
A,@Ri
(A)←(A)+((Ri))
1
1
Do akumulatora dodawana jest zawartość komórki w wewn. RAM o adresie wskazywanym przez rejestr Ri (R0 lub R1).
ADD
A,#data8
(A)←(A)+data8
1
2
Do akumulatora dodawany jest argument stały.
ADDC
''Add to acummulator with carry'' – dodaj do akumulatora z przeniesieniem. Do wartości przechowywanej w akumulatorze dodawany jest wskazany argument oraz zawartość znacznika przeniesienia C, a wynik zostaje wpisany do akumulatora.
ADDC
A,Rn
(A)←(A)+(Rn)+(C)
1
1
Do akumulatora dodawana jest zawartość rejestru Rn oraz C.
ADDC
A,addr8
(A)←(A)+(addr8)+(C)
1
2
Do akumulatora dodawana jest zawartość komórki w wewnętrznym RAM oraz znacznik C.
ADDC
A,@Ri
(A)←(A)+((Ri))+(C)
1
1
Do akumulatora dodawana jest zawartość komórki w wewnętrznym RAM o adresie wskazywanym przez rejestr Ri (R0 lub R1) oraz znacznik C.
ADDC
A,#data8
(A)←(A)+data8+(C)
1
2
Do akumulatora i znacznik C.
SUBB
'' Substract from acummulator with borrow” – odejmij od akumulatora z pożyczką. Od wartości przechowywanej w akumulatorze odejmowany jest wskazany argument oraz zawartość znacznika przeniesienia C,a wynik zostaje wpisany do akumulatora.
dodawany
jest
argument
stały
SUBB
A,Rn
(A)←(A)-(Rn)-(C)
1
1
Od akumulatora odejmowana jest zawartość rejestru Rn oraz C.
SUBB
A,addr8
(A)←(A)-(addr8)-(C)
1
2
Od akumulatora odejmowana jest zawartość komórki w wewnętrznym. RAM oraz znacznik C.
SUBB
A,@Ri
(A)←(A)-((Ri))-(C)
1
1
od akumulatora odejmowana jest zawartość komórki w wewnętrznym R A M o adresie wskazywanym przez rejestr Ri oraz znacznik C.
SUBB
A,#data8
(A)←(A)-data8-(C)
1
2
od akumulatora odejmowany jest (8−bitowa liczba) oraz znacznik C .
INC
''Increment'' – zwiększenie o 1, inkrementacja. Do wskazanego argumentu jest dodawana jedynka
argument
stały
INC
A
(A)←(A)+1
1
1
Do akumulatora dodawana jest jedynka.
INC
Rn
(Rn)←(Rn)+1
1
1
Do zawartości rejestru Rn dodawana jest jedynka.
INC
addr8
(addr8)←(addr8)+1
1
2
Do zawartości komórki o podanym adresie dodawana jest jedynka.
INC
@Ri
((Ri))←((Ri))+1
1
1
Do zawartości komórki o adresie wskazywanym przez Ri dodawana jest jedynka.
INC
DPTR
(DPTR)←(DPTR)+1
2
1
Do 16−bitowego wskaźnika danych DPTR złożonego z rejestrów SFR: DPH (bardziej znaczący bajt) i DPL (mniej znaczący bajt) dodawana jest jedynka.
DEC
''Decrement'' – zmniejszenie o 1, dekrementacja. Od wskazanego argumentu odejmowana jest jedynka.
DEC
A
(A)←(A)-1
1
1
Od akumulatora odejmowana jest jedynka.
DEC
Rn
(Rn)←(Rn)-1
1
1
Od zawartości rejestru Rn odejmowana jest jedynka.
DEC
addr8
(addr8)←(addr8)-1
1
2
Od zawartości komórki o podanym adresie odejmowana jest jedynka.
DEC
@Ri
((Ri))←((Ri))-1
1
1
Od zawartości komórki o adresie wskazywanym przez Ri odejmowana jest jedynka.
MUL
DIV
DA
A,B
A,B
A
(BA)15..0← (A)·(B)
całości:(A)← int(A/B) reszta:(B)← mod(A/B)
Jeśli [[(A)3..0 > 9] lub [AC = 1]] to (A)3..0 ← (A)3..0 + 6 Jeśli [[(A)7..4 > 9] lub [C = 1]] to (A)7..4 ← (A)7..4 + 6
4
4
1
1
„Multiply” – pomnóż. 8−bitowa liczba bez znaku znajdująca się w akumulatorze jest mnożona przez 8−bitową liczbę bez znaku z rejestru B. 16−bitowy wynik wpisywany jest do rejestrów B i A (bardziej znaczący bajt do B, mniej znaczący bajt do A.
1
„Divide” – podziel. 8−bitowa liczba bez znaku, znajdująca się w akumulatorze jest dzielona przez 8−bitową liczbę z rejestru B. Cześć całkowita ilorazu wpisywana jest do akumulatora, a reszta z dzielenia do rejestru B. W przypadku, gdy dzielnik jest równy 0 (B=0) to po wykonaniu operacji zawartość akumulatorze i rejestru B jest nieokreślona oraz dodatkowo ustawiony zostaje znacznik OV.
1
„Decimal adjust” – korekcja dziesiętna. Wykonywana jest korekcja dziesiętna wyniku dodawania. Operacja ta sprowadza wynik do postaci dwóch cyfr dziesiętnych w kodzie BCD, jeżeli argumenty były w kodzie BCD. Rozkaz ten powinien być używany jedynie w połączeniu z rozkazem dodawania (ADD, ADDC). Także inkrementacja powinna odbywać się poprzez instrukcję ADD A, #1, a nie INC A, bowiem w tym drugim przypadku nie są ustawianie znaczniki C i AC, tak więc nie może być wykonana korekcja dziesiętna. Korekcja polega na tym że w przypadku kiedy po wykonanej na akumulatorze operacji dodawania (ADD, ADDC) zawartość jego bitów 3...0 jest większa od 9 lub jest ustawiony znacznik AC, to do wartości akumulatora doda wana jest liczba 6. Po tym jeżeli okaże się że zawartość bitów 7...4 jest większa od 9 lub jest ustawiony znacznik C to do tych bitów dodawana jest także liczba 6. Jeżeli podczas tej ostatniej operacji wystąpiło przeniesienie to do znacznika wpisywana jest 1, w przeciwnym wypadku stan znacznika C nie zmienia się.
Instrukcje logiczne Mnemonik Argumenty Wykonywane operacje ANL
Cykle Rozmiar maszynowe [bajty]
Opis
''Logical AND'' – iloczyn logiczny. Wykonywany jest iloczyn logiczny AND (mnożenie bitów „bit po bicie”) wskazanych w instrukcji dwóch argumentów. Wynik operacji jest wpisywany do argumentu pierwszego instrukcji
ANL
A,Rn
(A)←(A) and (Rn)
1
1
Wymnożona logicznie zostaje zawartość akumulatora i rejestru Rn, wynik w akumulatorze.
ANL
A,addr8
(A)←(A) and (addr8)
1
2
Wymnożona logicznie zostaje zawartość akumulatora i komórki o podanym adresie, wynik zostaje umieszczony w akumulatorze.
ANL
A,@Ri
(A)←(A) and ((Ri))
1
1
Wymnożona logicznie zostaje zawartość akumulatora komórki w wewnętrznym RAM o adresie wskazywanym przez rejestr Ri, wynik zostaje umieszczony w akumulatorze.
ANL
A,#data8
(A)←(A) and data8
1
2
Wymnożona logicznie zostaje zawartość akumulatora przez argument stały, wynik zostaje umieszczony w akumulatorze.
ANL
addr8,A
(addr8)←(addr8) and (A)
1
2
Wymnożona logicznie zostaje zawartość komórki o podanym adresie i zawartość akumulatora, wynik zostaje umieszczony w komórce pamięci o podanym adresie.
ANL
addr8,#data8
(addr8)←(addr8) and data8
2
3
wymnożona logicznie zostaje zawartość komórki o adresie „adres” przez argument stały, wynik zostaje umieszczony w komórce pamięci o podanym adresie.
ORL
''Logical OR'' – suma logiczna. Wykonywana jest suma logiczna OR (dodawanie bitów „bit po bicie”) wskazanych w instrukcji dwóch argumentów. Wynik operacji jest wpisywany do argumentu pierwszego instrukcji.
ORL
A,Rn
(A)←(A) or (Rn)
1
1
Dodana logicznie zostaje zawartość akumulatora i rejestru Rn, wynik w akumulatorze.
ORL
A,addr8
(A)←(A) or (addr8)
1
2
Dodana logicznie zostaje zawartość akumulatora i komórki o podanym adresie, wynik zostaje umieszczony w akumulatorze.
ORL
A,@Ri
(A)←(A) or ((Ri))
1
1
Dodana logicznie zostaje zawartość akumulatora komórki w wewnętrznym RAM o adresie wskazywanym przez rejestr Ri, wynik w akumulatorze.
ORL
A,#data8
(A)←(A) or data8
1
2
Dodana logicznie zostaje zawartość akumulatora przez argument stały, wynik w akumulatorze.
ORL
addr8,A
(addr8)←(addr8) or (A)
1
2
Dodana logicznie zostaje zawartość akumulatora i komórki o podanym adresie, wynik zostaje umieszczony w komórce pamięci o adresie.
ORL
addr8,#data8
(addr8)←(addr8) or data8
2
3
Dodana logicznie zostaje zawartość komórki o adresie oraz argument stały, wynik zostaje umieszczony w komórce pamięci o adresie.
XRL
''Logical XOR'' – zsumuj mod 2 (różnica symetryczna). Wykonywana jest różnica symetryczna wskazanych w instrukcji dwóch argumentów. Wynik operacji jest wpisywany do argumentu pierwszego instrukcji.
XRL
A,Rn
(A)←(A) xor (Rn)
1
1
Zsumowana (mod 2) zostaje zawartość akumulatora i rejestru Rn, wynik w akumulatorze.
XRL
A,addr8
(A)←(A) xor (addr8)
1
2
Zsumowana (mod 2) logicznie zostaje zawartość akumulatora i komórki o podanym adresie, wynik zostaje umieszczony w akumulatorze.
XRL
A,@Ri
(A)←(A) xor ((Ri))
1
1
Zsumowana (mod 2) logicznie zostaje zawartość akumulatora komórki w wewnętrznym RAM o adresie wskazywanym przez rejestr Ri, wynik zostaje umieszczony w akumulatorze.
XRL
A,#data8
(A)←(A) xor data8
1
2
Zsumowana (mod 2) logicznie zostaje zawartość akumulatora przez argument stały, wynik zostaje umieszczony w akumulatorze.
XRL
addr8,A
(addr8)←(addr8) xor (A)
1
2
Zsumowana (mod 2) logicznie zostaje zawartość akumulatora i komórki o podanym adresie „adres”, wynik zostaje umieszczony w komórce pamięci o adresie.
XRL
addr8,#data8
(addr8)←(addr8) xor data8
2
3
Zsumowana (mod 2) logicznie zostaje zawartość komórki o adresie „adres” oraz argument stały, wynik zostaje umieszczony w komórce pamięci o adresie.
CLR
A
(A) ← 0
1
1
''Clear accumulator'' – zeruj akumulator. akumulatora zostaje wpisana wartość 0.
CPL
A
(A) ← not(A)
1
1
''Complement accumulator'' – zaneguj akumulator. Wartość akumulatora zostaje zanegowana, wynik wpisany zostaje do akumulatora.
RL
A
(A) ← rotacja w lewo (A)
1
1
''Rotate left” – przesuń w lewo. Zawartość akumulatora zostaje przesunięta w lewo o 1 pozycję (o 1 bit).
Do
RLC
A
(A) ← rotacja w lewo (A) zC
1
1
''Rotate left through carry” – przesuń cyklicznie w lewo ze znacznikiem C. Zawartość akumulatora zostaje przesunięta w lewo o 1 pozycję (o 1 bit) z uwzględnieniem znacznika C, to znaczy że: znacznik C przyjmuje wartość bitu 7 bit 1 przyjmuje wartość bitu 0 bit 2 przyjmuje wartość bitu 1 (...) bit 7 przyjmuje wartość bitu 6 bit 0 przyjmuje wartość znacznika C.
RR
A
(A) ← rotacja w prawo (A)
1
1
''Rotate right” – przesuń w prawo. Zawartość akumulatora zostaje przesunięta w prawo o 1 pozycję (o 1 bit).
RRC
SWAP
A
A
(A) ← rotacja w prawo (A) z C
1
(A3...0) ↔ (A7...4)
1
1
'' Rotate right through carry'' – przesuń cyklicznie w prawo ze znacznikiem C. Zawartość akumulatora zostaje przesunięta w prawo o 1 pozycję (o 1 bit) z uwzględnieniem znacznika C, to znaczy że: znacznik C przyjmuje wartość bitu 0) bit 0 przyjmuje wartość bitu 1 bit 1 przyjmuje wartość bitu 2 (...) bit 6 przyjmuje wartość bitu 7 bit 7 przyjmuje wartość znacznika C.
1
''Swap nibbles within accumulator'' – wymień półbajty w akumulatorze. W wyniku tej instrukcji wymieniona zostaje zawartość bitów 3...0 (mniej znaczący półbajt) i bitów 7...4 (bardziej znaczący półbajt) akumulatora. Operacja ta jest równoważna 4−krotnemu przesunięciu zawartości akumulatora
Instrukcje transferu Mnemonik Argumenty Wykonywane operacje
MOV
Cykle Rozmiar maszynowe [bajty]
Opis
''Move'' – przesuń, przenieś. Ogólne instrukcję MOV można zapisać jako: MOV <s>, gdzie: jest miejscem przeznaczenia (''destination''), a <s> źródłem pobrania danej (''source''). W wyniku wykonania instrukcji MOV zawartość źródła <s> zostaje skopiowana do obiektu przeznaczenia . We wszystkich przypadkach (oprócz jednego) argumentami instrukcji MOV są wyrażenia 8–bitowe: rejestry, dane adresy pośrednie itp. Jedynie załadowanie 16–bitowego wskaźnika adresu DPTR wymaga odpowiedniego 16–bitowego (stałej) argumentu.
MOV
A,Rn
(A) ← (Rn)
1
1
Do akumulatora zostaje załadowana zawartość rejestru Rn.
MOV
A,addr8
(A) ← (addr8)
1
2
Do akumulatora zostaje załadowana zawartość komórki wewnętrznej pamięci RAM o podanym adresie.
MOV
A,@Ri
(A) ← ((Ri))
1
1
Do akumulatora zostaje załadowana zawartość komórki wewn. R A M, której adres znajduje się w rejestrze Ri.
MOV
A,#data8
(A) ← data8
1
2
Instrukcja załadowania akumulatora
MOV
Rn, A
(Rn) ← (A)
1
1
Do rejestru akumulatora.
MOV
Rn,addr8
(Rn) ← (addr8)
1
2
Do rejestru Rn zostaje załadowana zawartość komórki o podanym adresie.
MOV
Rn,#data8
(Rn) ← data8
1
2
Do rejestru Rn zostaje wpisana 8–bitowa liczba.
MOV
addr8, A
(addr8) ← (A)
1
2
Do komórki o podanym adresie zostaje wpisana zawartość akumulatora
MOV
addr8,Rn
(addr8) ← (Rn)
2
2
Do komórki o podanym adresie zostaje wpisana zawartość rejestru Rn.
MOV
addr81, addr82
(addr81) ← (addr82)
2
3
Przepisanie zawartości komórki o adresie (addr82), do komórki o adresie (addr81).
MOV
addr8,@Ri
(addr8) ← ((Ri))
2
2
Do komórki o podanym adresie zostaje wpisana zawartość komórki której adres znajduje się w rejestrze Ri.
MOV
addr8, #data8
(addr8) ← data8
2
3
Do komórki o podanym adresie zostaje wpisana wartość stała.
MOV
@Ri,A
((Ri)) ← (A)
1
1
Do komórki o adresie znajdującym się w rejestrze Ri zostaje wpisana zawartość akumulatora
MOV
@Ri,addr8
((Ri)) ← (addr8)
2
2
Do komórki o adresie znajdującym się w rejestrze Ri zostaje wpisana zawartość komórki o podanym adresie.
MOV
@Ri, #data8
((Ri)) ← data8
1
2
Do komórki o adresie znajdującym się w rejestrze Ri zostaje wpisana wartość stała
MOV
DPTR, #data16
D PTR ← data16
2
3
Instrukcja załadowania 16–bitowego, bezwzględnego adresu do wskaźnika danych DPTR (data16 → liczba 16-bitowa)
Rn
zostaje
8–bitowej załadowana
liczby
do
zawartość
MOVC
Instrukcje sterujące bezwarunkowe warunkowe Instrukcje bitowe
Korzystałem z „MCS(R) 51 Microcontroller Family User's Manual”
Legenda: ● ● ● ● ● ● ● ●
● ● ● ● ● ●
Rn - jeden z rejestrów R0 do R7 aktywnego banku rejestrów, addr8 - 8-bitowy adres w wewnętrznej pamięci danych adresowanej bezpośrednio, @Ri - 8-bitowy adres umieszczony w jednym z dwóch rejestrów R0 lub R1 aktywnego
banku rejestrów. #data8 - 8-bitowa stała kodowana wewnątrz instrukcji. #data16 - 16-bitowa stała kodowana wewnątrz instrukcji. addr16 - 16-bitowy adres używany w instrukcjach LJMP i LCALL (praktycznie zastępowany przez etykietę). addr11 - 11-bitowy adres używany w instrukcjach AJMP oraz ACALL (praktycznie zastępowany przez etykietę). rel - 8-bitowe przesuniecie traktowane jako liczba ze znakiem w kodzie U2 i używane w instrukcji SJMP oraz wszystkich instrukcjach skoków warunkowych (praktycznie zastępowane przez etykietę). bit - adres bitu z wewnętrznej pamięci danych adresowanego bitowo lub obszaru SFR. (x) - w opisie operacji oznacza zawartość komórki w wewnętrznej pamięci danych o adresie bezpośrednim x. ((x)) - w opisie operacji oznacza zawartość komórki wewnętrznej pamięci danych o adresie zapisanym w rejestrze x. (y)XDATA - w opisie operacji oznacza zawartość komórki w zewnętrznej pamięci danych o adresie y. (z)CODE - w opisie operacji oznacza zawartość komórki w pamięci kodu o adresie z. Xy..z - W opisie operacji oznacza bity od y do z rejestru X.