Laboratorium Podstaw Systemów Mikroprocesorowych
Nazwisko i imię wykonawców: Wiesław Rycerz |
Symbol grupy ED. 5.4 |
||||||
Data wyk. Ćwiczenia 1997-11-17 |
Symbol ćwiczenia 3 |
Temat zadania Pamięć wewnętrzna RAM. Organizacja i wykorzystanie stosu. |
|||||
|
ZALICZENIE |
|
|
Ocena |
Data |
Podpis |
|
Mikrokontroler 8051 posiada wbudowaną do wnętrza pamięć RAM. Tak jak w przypadku pamięci programu, w celu wybrania określonej komórki pamięci należy podać jej adres. Do adresowania pamięci wewnętrznej RAM używany jest adres 8-bitowy pozwala rozróżnić maksymalnie s8 = 256 komórek pamięci. W rzeczywistości w mikrokontrolerze 8051 umieszczono 128 bajtów pamięci RAM (adresy: 00..7F). Natomiast w obszarze adresów 80..FF umieszczono rejestry specjalne (SFR), które sterują różnymi funkcjami mikrokontrolera. W obszarze tym znajdują się między innymi rejestry odpowiedzialne za stan portów. Wartość wpisana do takiego rejestru jest jednocześnie wystawiona na odpowiadający mu port, tzn. Odpowiednie linie ustawiane są w stan niski lub wysoki, zgodnie z wartościami odpowiednich bitów w rejestrze. Rejestrom poszczególnym portów przyporządkowano następujące adresy
Port Adres
P0 80H
P1 90H
P2 A0H
P3 B0H
Chcąc wpisać wartość do odpowiedniego rejestru należy w odpowiednim rozkazie (na przykład MOV) podać adres rejestru. Ten sposób adresowania , w którym w kodzie rozkazu jest umieszczony adres odpowiedniego rejestru, nazywany jest adresowanie bezpośrednim.
Pisząc program w asemblerze nie trzeba umieszczać adresu rejestru w rozkazie (na przykład szesnastkowo), wystarczy podać jego symboliczna nazwę. Wszystkie nazwy rejestrów specjalnych mikrokontrolera 8051 są znane asemblerowi i odpowiadające im adresy zostaną wstawione do kodu programu w trakcie asemblacji.
Możliwe jest również adresowanie bezpośrednie w odniesieniu do poszczególnych bitów. W obszarze rejestrów specjalnych przyjęto zasadę, że bity we wszystkich rejestrach, których adres jest podzielny przez 8, tzn. 80H, 88H, 90H, 98H,.., F8H, można indywidualnie adresować. Adresy w poszczególnych bitach tworzone są następująco:
w rejestrze 80H:
bit 7 6 5 4 3 2 1 0
adres 87H 86H 85H 84H 83H 82H 81H 80H
w rejestrze 88H:
bit 7 6 5 4 3 2 1 0
adres 8FH 8EH 8DH 8CH 8BH 8AH 89H 88H
Poszczególne bity w rejestrach mogą mieć takie same adresy, jak adresy rejestrów, gdyż adresy bitów są wykorzystywane w innych rozkazach niż adresy rejestrów. To rozkaz „wie”, czy podana liczba jest adresem bitu czy rejestru.
Tak jak rejestry, również część bitów posiada swoje nazwy znane asemblerowi. Do pozostałych można odwoływać się poprzez podanie nazwy rejestru i numeru bitu. Na przykład port P1 o adresie 90H oraz bity P1.7 i P1.5 o adresach odpowiednio 97H i 95H.
W obszarze rejestrów specjalnych znajduje się podstawowy rejestr mikroprocesora, tj. akumulator. Jest on umieszczony pod adresem 0E0H. Wiele rozkazów wykonywanych przez mikrokontroler (m.in. arytmetyczne), może zrealizować swoje operacje tylko na tym rejestrze. Umieszczanie adresu akumulatora w kodzie tych rozkazów, byłoby niepotrzebną stratą pamięci. Dlatego też większość rozkazów odnoszących się do akumulatora, nie zawiera w swoim kodzie jego adresu. Ten typ adresowania (w którym nie ma wyspecyfikowanego adresu) nazywany jest adresowaniem rejestrowym. W tego typu rozkazach akumulator oznaczany jest literą A.
Jako, że akumulator leży w obszarze rejestrów specjalnych, może być on adresowany tak, jak każdy inny rejestr, tzn. Bezpośrednio, czyli z umieszczeniem adresu w kodzie rozkazu. W takich przypadkach akumulator oznaczany jest jako ACC. Zawsze jednak rozkazy zostaną wykonane na tym samym rejestrze.
Przykładowo:
MOV A,#10
można zapisać jako
MOV ACC,#10
W pierwszym przypadku zostanie on przetłumaczony jako: 74 0A, natomiast w drugim jako: 75 E0 0A. Skutek działania obu tych rozkazów jest taki sam, ale długość kodu drugiego jest, jak widać, 1.5 razy dłuższa, natomiast czas wykonywania aż 2 razy dłuższy.
Drugim podstawowym rejestrem mikrokontrolera 8051 jest rejestr stanu (PSW- Program Status Word), który znajduje się pod adresem 0D0H. Rejestr ten jest w zasadzie zbiorem niezależnych flag (wskaźników), które są przeważnie wykorzystywane za pośrednictwem ich adresów. Flagi te mogą być ustawiane odpowiednimi rozkazami umieszczonymi w programie, na przykład SETB, CLR itp., ale są one również automatycznie ustawiane w wyniku działania innych rejestrów, na przykład arytmetycznych. Mogą one również wpływać na sposób wykonywania poszczególnych rozkazów.
Rejestr PSW
Flagi operacji arytmetycznych
CY - przeniesienie (oznaczana w rozkazach przez C),
AC - przeniesienie pomocnicze (dla operacji BCD),
OV - przepełnienie
Flagi stanu akumulatora
P - (parity) parzystość
Flagi użytkownika
F0 - flaga ogólnego zastosowania (Flaga 0)
PSW.1 - flaga definiowana przez użytkownika
Flagi wyboru banku rejestrów
RS0 - młodszy bit numeru banku,
RS1 - starszy bit numeru banku.
W mikrokontrolerze 8051 umieszczono, oprócz rejestrów specjalnych, 128 komórek pamięci RAM pod adresami 00..7FH. W przeciwieństwie do obszaru rejestrów specjalnych obszar ten jest ciągły, tzn. Pod wszystkimi adresami od 00 do 7FH istnieją kolejne komórki pamięci. Pamięć ta może być wykorzystywana dowolnie, zależnie od potrzeb programu.
W pamięci tej zostały wyróżnione pewne obszary, które mogą (ale nie muszą) być wykorzystywane w sposób szczególny.
Początkowe 32 bajty stanowią 4 banki rejestrów. Każdy bank zawiera 8 rejestrów: R0, ..., R7. Do tego obszaru można odwoływać się podając adres odpowiedniej komórki, ale prościej jest posługiwać się nazwą rejestru R0, ...,R7.
Na przykład rozkaz MOV A,R0 powoduje przesłanie zawartości rejestru R0 do akumulatora. W kodzie tego rozkazu nie występuje 8-bitowy adres rejestru R0, a jedynie 3 bity kodu przeznaczone są do rozróżnienia odpowiedniego rejestru R0, ..., R7 (000...111). Dzięki temu rozkaz może zmieścić się na 8 bitach i zajmować jedynie 1 bajt pamięci programu. Użycie nazwy R0 nie określa jednoznacznie adresu rejestru, na którym będzie wykonywana operacja, ponieważ istnieją 4 banki rejestrów. Nazwa R0 może odnosić się do komórki pamięci pod adresem 0, 8, 10H i 18H. To która z tych komórek będzie w rzeczywistości użyta przez mikrokontroler w trakcie wykonywania rozkazu, zależy od aktywnego banku rejestrów. Odpowiedni bank rejestrów wybierany jest przez bity umieszczone w rejestrze stanu - RS0, RS1. Wybór banku następuje zgodnie z poniższą tabelą:
RS1 RS0 Bank Adresy
0 0 0 00H..07H
0 1 1 08H..0FH
1 0 2 10H..17H
1 1 3 18H..1FH
Posługiwanie się rejestrami R0..R7 (zamiast innymi komórkami pamięci) jest w programowaniu bardzo wygodne i efektywne.
Rejestry R0 i R1 mają jeszcze inną ważną cechę. Za ich pomocą można adresować jeszcze inne komórki pamięci RAM. Jest to tzw. Adresowanie pośrednie. Aby wpisać do komórki o adresie 55H wartość 0AAH, należy umieścić adres w rejestrze R0, a następnie wartość 0AAH wpisać do komórki o adresie zawartym w rejestrze R0.
MOV R0,#55H
MOV @R0,#0AAH
Symbol @ oznacza, że wartość 0AAH nie może być wpisana do rejestru R0, lecz do komórki, której adres jest w rejestrze R0.
LJMP START
ORG 100H
START:
MOV R0,#30
PETLA:
MOV @R0,#EE
INC R0
DJNZ @R0,#38H,PETLA
LJMP $
Zadanie 1.
Adres |
Program |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
LCD |
|
|
CY |
AC |
FD |
RS1 |
RS0 |
OV |
- |
P |
|
0000
0100 0103 0105 0108 010B 010E |
LJMP START ORG 100H START: LCALL LCD_CLR MOV A,#10H LCALL WRITE_HEX MOV ACC,#20H LCALL WRITE_HEX LJMP $ |
0
0 0 0 0 1 1 1 |
0
0 0 0 0 0 0 0 |
0
0 0 0 1 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 1 1 1 0 0 |
10 10 1020 1020 |
Zadanie 2.
Adres |
Program |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
LCD |
|
|
CY |
AC |
FD |
RS1 |
RS0 |
OV |
- |
P |
|
0000
0100 0103 0105 0108 010B 010E |
LJMP START ORG 100H START: LCALL LCD_CLR MOV ACC,#10H LCALL WRITE_HEX MOV ACC,#20H LCALL WRITE_HEX LJMP $ |
0
0 0 0 0 1 1 1 |
0
0 0 0 0 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 0 0 0 0 0 |
0
0 0 1 0 1 0 0 |
10 10 1020 1020 |
Zadanie 4.
Program |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
LCD |
A |
|
CY |
AC |
FD |
RS1 |
RS0 |
OV |
- |
P |
|
|
B0R7 EQU 7 B1R7 EQU 8+7 B2R7 EQU 10H+7 B3R7 EQU 18H+7 LJMP START ORG 100H START: MOV B0R7,#0 MOV B1R7,#1 MOV B2R7,#2 MOV B3R7,#3 LCALL LCD_CLR MOV A,R7 LCALL WRITE_HEX SETB RS0 MOV A,R7 LCALL WRITE_HEX SETB RS1 MOV A,R7 LCALL WRITE_HEX CLR RS0 MOV A,R7 LCALL WRITE_HEX LJMP $ |
0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 |
00 00 00 0001 0001 0001 000103 000103 000103 0001032 0001032 |
00H 00H 00H 00H 00H 00H 00H 00H 00H 00H 00H 00H 27H 00H 21H 21H 01H 19H 19H 03H F7H F7H 02H FFH |
Zawartość rejestrów R7 w poszczególnych bankach:
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Bank 0 Bank 1 Bank 2 Bank 3 |
0 0 0 0 |
0 0 0 0 |
0 0 0 0 |
0 0 0 0 |
0 0 0 0 |
0 0 0 0 |
0 0 1 1 |
0 1 0 1 |
Zadanie 5.
Modyfikując przykład 4 wykorzystując adresowanie pośrednie zapełnić zawartością EEH wybraną przestrzeń adresową.
LJMP START
ORG 100H
START:
MOV R0,#30
PETLA:
MOV @R0,#EE
INC R0
CJNE @R0,#38H,PETLA
LJMP $