MCS-51
Architektura

Organizacja pamięci

Mikrokontrolery rodziny MCS-51 posiadają trzy odrębne obszary pamięci, tj:

  • wewnętrzną pamięć danych,
  • zewnętrzną pamięć danych,
  • pamięć programu.

W poniższej tabeli przedstawiono klasyczne oznaczenia stosowane przez firmę Intel dla mikrokontrolerów omawianej rodziny. Oznaczenia te pierwotnie wskazywały m.in. na wielkość wewnetrznej pamięci danych (RAM) i kodu (ROM). Niniejsze opracowanie omawia właśnie taką klasyczną wersji mikrokontrolera rodziny MCS-51, stąd w jego dalszej części będą występowały odniesienia do tych oznaczeń.

Oznaczenie Pamięć wewnętrzna
RAM ROM
8031 128B -
8032 256B -
8051 128B 4kB
8751 128B 4kB EPROM (OTP)
8052 256B 8kB
8752 256B 8kB EPROM (OTP)

Obecnie producenci klonów tych mikrokontrolerów wprowadzają własne oznaczenia, które nie do końca są powiązane z przedstawionymi oznaczeniemi stosowanymi przez firmę Intel.

Wewnętrzna pamięć danych

Każdy z mikrokontrolerów omawianej rodziny posiada wewnętrzną pamięć danych (ang. internal data memory) zawartą w układzie mikrokontrolera, potocznie zwaną pamięcią RAM. W zależności od wersji układu, jej wielkość wynosi 128B (8xx1) lub 256B (8xx2). Jest to pamięć praktycznie w całości do wykorzystania przez użytkownika. Dostęp do niej jest bardzo szybki, dlatego powinny być w niej składowane najczęściej używane dane. Z drugiej strony rozmiar tego obszaru pamięci nie jest zbyt duży, dlatego należy wykorzystywać go rozsądnie. Na poniższym rysunku pokazano organizację tej pamięci dla przypadku 128B.

Wewnętrzna pamięć danych (wersja 8xx1)

W obszarze wewnętrznej pamięci danych o adresach od 00h do 1Fh znajdują się 4 banki uniwersalnych rejestrów roboczych (ang. working registers), po 8 rejestrów w każdym. Rejestry te są adresowane przez nazwę (R0, R1, R2, R3, R4, R5 R6 oraz R7).

Banki rejestrów w wewnętrznej pamięci danych
Uwaga Chociaż istnieje możliwość dostępu do komórek pamięci zajmowanych przez rejestry uniwersalne poprzez operowanie bezpośrednio ich adresami, to nie zaleca się takiego postępowania ze względu na spójność i przejrzystość kodu, jak również krótszą długość rozkazów przy operowaniu adresowaniem rejestrowym, a nie bezpośrednim. Jedynym dopuszczalnym odstepstwem od tej zasady jest konieczność przesłania zawartości jednego rejestru do drugiego, ze względu na brak takiego rozkazu.

W danej chwili dostępne są tylko rejestry jednego banku wybieranego przez odpowiednią kombinację bitów RS0 i RS1 zawartych w rejestrze PSW. Oznacza to, że w przypadku wyboru banku 0 rejestrów, nazwy R0 do R7 odpowiadają adresom 00h do 07h. Jeśli natomiast wybrany jest bank 2, to nazwy R0 do R7 odpowiadają adresom 10h do 17h.

Przeważnie w programach wykorzystuje się tylko bank 0 rejestrów. Dalsze banki rejestrów są wykorzystywane głównie w podprogramach lub przy obsłudze przerwań, kiedy istnieje konieczność zachowania zawartości rejestrów banku 0, używanych w części głównej programu. Jest to działanie szybsze od odkładania wszystkich rejestów na stos, gdyż wymaga zapamiętania na stosie tylko zawartości rejestru PSW, a nastepnie odpowiedniej zmiany bitów RS0 i RS1 w tym rejestrze. Oczywiście przed powrotem podprogramu, czy też z programu obsługi przerwania należy przeładować rejestr PSW starą wartością poprzez zdjęcie jej ze stosu. Przywracany jest w ten sposób wcześniej wykorzystywany bank rejestrów wraz z ich stara zawartością.

W obszarze adresów od 20h do 2Fh wewnętrznej pamięci danych możliwe jest adresowanie pojedynczych bitów. Jest to tzw. obszar adresowany bitowo (ang. bit addressable memory), gdyż zawartość informacyjna tych 16 bajtów może być zapisywana i odczytywana nie tylko całymi bajtami, lecz również poprzez ich poszczególne bity. W takim przypadku adresy kolejnych bitów są takie, jak na poniższym rysunku.

Obszar adresowany bitowo w wewnętrznej pamięci danych

Dalszy obszar pamięci, od adresu 30h do 7Fh, może służyć dowolnym celom, jakie stawia tworzone oprogramowanie.

Cały obszar użytkowy wewnętrznej pamięci danych (włącznie z obszarem rejestrów roboczych i obszarem adresowanym bitowo) podlega zarówno adresowaniu bezpośredniemu, jak i pośredniemu zawartością rejestrów R0 lub R1.

W przypadku mikrokontrolerów 8xx2 obszar wewnętrznej pamięci danych jest zwiększony do 256B, przy czym dodany obszar znajduje się w przestrzeni adresowej obszaru rejestrów specjalnych (adresy od 80h do FFh). Aby nie występowała niejednoznaczność w dostepie do tych dwóch obszarów, dostęp do tego dodanego obszaru pamięci może być realizowany tylko przez adresowanie pośrednie z wykorzystaniem rejestrów R0 i R1, natomiast do obszaru SFR - tylko przez adresowanie bezpośrednie.

Wewnętrzna pamięć danych (wersja 8xx2)
Uwaga Obecnie wśród producentów panuje tendencja do umieszczania 256B wewnętrznej pamięci danych. Żadko spotykane są układy ze 128 bajtami wewnętrznej pamięci danych, jednak dla pewności zawsze należy zajrzeć do noty katalogowej producenta danego układu.

Rejestry specjalne

W obszarze adresowania wewnętrznej pamięci danych powyżej 128B pamięci użytkowej, w zakresie adresów 80h do FFh, znajduje się obszar rejestrów specjalnych oznaczany skrótem SFR (ang. special function registers). W obszarze tym zgrupowane są rejestry wykorzystywane do sterowania wewnętrznymi uładami peryferyjnymi, jak liczniki-czasomierze oraz port szeregowy, a także rejestry sterujące systemem przerwań oraz trybami oszczędzania energii. Również porty równoległe P0, P1, P2 i P3 widziane są jako odpowiednie rejestry w obszarze SFR. Poniżej przedstawiono mapę tych rejestrów.

Mapa rejestrów specjalnych (wersja 8xx2)
Uwaga Chociaż nie wszystkie komórki pamięci z obszaru rejestrów specjalnych mają przypisaną określoną funkcjonalność, to te, które są niewykorzystane nie mogą być używane jako dodatkowa pamięć danych.

Większość programów asemblujących oraz kompilatorów dopuszcza odnoszenie się w rozkazach do tych rejestrów poprzez nazwę zamiast używania ich adresów. Ułatwia to znacznie pisanie programów, gdyż człowiek znacznie szybciej zapamiętuje i kojarzy nazwy niż liczby (można zauważyć, iż nazwy większości rejestrów pochodzą od anglojęzycznych opisów ich przeznaczenia, np. TMOD - Timer MODe, SCON - Serial CONtrol, PSW - Processor Status Word). Dodatkowo część z nich (te, których adresy w zaspisie szesnastkowym kończą się na 0 lub 8) może być adresowana bitowo, co oznacza, iż możliwa jest niezależna zmiana stanu poszczególnych bitów w danycm rejestrze. Ułatwia to znacznie obsługę niektórych układów peryferyjnych.

Dostęp do poszczególnych bitów rejestrów adresowanych bitowo może odbywać się na dwa sposoby. Jednym z nich jest podanie nazyw rejestru, postawienie bezpośrednio za nim kropki, a nastepnie numeru bitu w zakresie 0 do 7. Poszczególne bity w tych rejestrach mają równiez swoje nazwy, stąd inny sposób odniesienia się do nich, to specyfikowanie w instrukcjach ich nazw.

Rejestry T2MOD, RCAP2L, RCAP2H, TL2 oraz TH2 związane są licznikiem-czasomierzem T2 i występują tylko w tych wersjach mikrokontrolera, które oznaczono jako 8xx2. Inne rejestry, nie związane bezpośrednio z wewnetrznymi układami peryferyjnymi, mają następujące znaczenie funkcjonalne:

Rejestr Przeznaczenie
ACC 8-bitowy rejestr akumulatora. Stosowany przede wszystkim, jako rejestr przechowujący jeden z argumentów operacji arytmetycznych oraz uzyskany wynik.
B 8-bitowy rejestr B wykorzystywany jest bezpośrednio przy realizacji operacji mnożenia (przechowuje jeden z dwóch argumentów) o dzielenia (przechowuje dzielnik). W innych przypadkach może być wykorzystywany jako rejestr pomocniczy do czasowego zapamiętywania wartości.
DPTR 16-bitowy rejestr wskaźnika danych złożony z dwóch rejestrów 8-bitowych (DPH i DPL). Stosowany przy dostepie do zewnętrznej pamięci danych (zapis/odczyt) lub pamięci kodu (odczyt).
SBUF Rejestr 8-bitowy związany wyłącznie z portem szeregowym mikrokontrolera. W przypadku zapisu do tego rejestru następuje odniesienie do bufora nadajnika portu szeregowego (zapisana wartość zostaje automatycznie wysyłana przez port szeregowy - wyprowadzeni TxD mikrokontrolera). W przypadku operacji odczytu następuje odniesienie do bufora odbiornika portu szeregowego, w którym następuje grupowanie kolejnych bitów odczytywanych przez wyprowadzenie RxD mikrokontrolera.
SP 8-bitowy rejestr wskaźnika stosu. Przechowuje adres wierzchołka stosu. Inkrementowany za każdym razem, gdy następuje zapis na stos, a dekrementowany, gdy realizowana jest operacja zdjęcia informacji ze stosu.

Pozastałe rejestry związane z wewnętrznymi układami peryferyjnymi zawartymi w układzie mikrokontrolera zostaną szczegółowo omówione w dalszej części nieniejszego opracowania przy omawianiu tychże układów.

Stos

Stos (ang. stack) jest obszarem pamięci o organizacji LIFO (ang. last in, first out) rezydującym w wewnętrznej pamięci danych. Obszar ten jest używany przez rozkazy wywołania podprogramów oraz podczas wywołania programów obsługi przerwań do przechowywania adresów powrotu. Również użytkonik za pomoca odpowiednich rozkazów może odkładać i zdejmować dane na/z stosu w celu ich chwilowego zapamiętania.

Adres wierzchołka stosu przechowywany jest w 8-bitowym rejestrze SP (ang stack pointer). Każde odłożenie wartości na stos powoduje inkrementację rejestru SP, a następnie zapis odkładanej wartość do komórki wewnętrznej pamięci danych wskazywanej przez SP. Z kolei zdjęcie informacji ze stosu wymusza odczyt danej z komórki wewnętrznej pamięci danych wskazywanej przez SP, a następnie dekrementację zawartości rejestru SP, a więc wskazanie kolejnej komórki pamięci o adresie mniejszym o 1.

Po resecie rejestr SP inicjalizowany jest wartością 07h, stąd pierwszy zapis informacji na stos dokonywany jest w rzeczywistości pod adres 08h. Kolejne odłożenia na stos będą równoważne zapisom pod coraz wyższe adresy w wewnętrznej pamięci danych.

Uwaga Jak można zauważyć, przy domyślnych ustawieniach rejestru SP zapis na stos jest równoważny zapisowi rejestrów banku 1, a następnie 2 i 3. Dlatego, jeśli w danej aplikacji wykorzystywany jest nie tylko bank 0, to wskaźnik stosu SP powinien być programowo zainicjalizowany wartością adresu wyższą, niż adres ostatniego z wykorzystywanych rejestrów danego banku. W przeciwnym razie zawartość rejestów będzie modyfikowana nie tylko poprez odpowiednie rozkazy zapisu do rejestrów, ale również poprzez operacje działające na stosie.
Uwaga Ze względu na fakt, iż stos rozrasta się w kierunku coraz wyższych adresów, samo ominięcie banku rejestów może nie ustrzec od nieprzewidzianych błędów w programe. Mianowicie stos umieszczony powyżej banków rejestów może najść na obszar pamięci wykorzystywany do przechowywania zmiennych modyfikując te komórki pamięci. Stąd najlepszym rozwiązaniem jest ustawienie wskaźnika stosu SP na adres w wewenętrznej pamięci danych powyżej obszaru wykorzystywanego w aplikacji.

Zewnętrzna pamięć danych

Istnieje również możliwość dołaczenia zewnętrznej pamięci danych (ang. external data memory) o rozmiarze do 64kB. Maksymalny rozmiar dołączanej zewnętrznej pamięci danych wynika z 16-bitowej szny adresowej tego mikrokontrolera. Wewnętrzna i zewnętrzna pamięć danych są widziane przez ten mikrokontroler jako dwa różne obszary pamięci. Z punktu widzenia oprogramowania to, czy dana operacja odczytu/zapisu dotyczy wewnętrznej, czy zewnętrznej pamięci danych rozróżniane jest na poziomie zastosowanego rozkazu (dla pamięci wewnętrznej - instrukcja MOV, dla zewnętrznej - instrukcja MOVX).

Pamięć programu

Mikrokontrolery rodziny MCS-51 posiadają możliwość zaadresowania do 64kB pamięci programu (ang. program memory), co jest bezpośrednim następstwem 16-bitowej szyny adresowej. W niektórych wykonaniach mikrokontrolery te zaopatrzone są już w wewnętrzną pamięć programu (ang. internal program memory) umieszczoną fizycznie w układzie. Jest to zawsze pamięć stała (zatem z punktu widzenia mikrokontrolera tylko do odczytu) typu ROM, EPROM lub coraz częściej Flash. Dla przykładu klasyczne wersje tego mikrokontrolera oznaczone 8x51 posiadały 4kB wewnętrznej pamięci programu, natomiast układy oznaczone 8x52 - 8kB.

Pozostała przestrzeń adresowa może być wykorzystana do adresowania zewnętrznej pamięci programu (ang. external program memory) dołączanej zewnętrznie poprzez linie portu P0 i P2. W przeciwieństwie do pamięci danych, z punktu widzenia mikrokontrolera wewnętrzna i zewnętrzna pamięć programu widziane są jako jeden ciągły obszar pamięci.

Uwaga Istnieją klony mikrokontrolerów rodziny MCS-51, które umożliwiają zaadresowanie nawet do 16MB pamięci programu. Realizowane jest to przeważnie poprzez odpowiednie modyfikacje standardowej wersji rdzenia tego mikrokontrolera. Przykładem jest tutaj rodzina MicroConverterów ADuC8xx firmy Analog Devices. Drugim podejściem jest zastosowanie tzw. bankowania kodu programu. Jest to podejsćie programowo-sprzętowe, gdyż wymaga realizacji odpowiedniego podłączenia zewnętrznej pamięci oraz odpowiedniego programu linkera.