Serwis Edukacyjny w I-LO w Tarnowie Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej Autor artykułu: mgr Jerzy Wałaszek |
©2024 mgr Jerzy Wałaszek |
https://www.microchip.com/about-us/legal-information/copyright-usage-guidelines
Ten rozdział opisuje różne pamięci w mikrokontrolerze ATmega64. Architektura AVR posiada dwie główne przestrzenie pamięciowe: przestrzeń pamięci danych (ang. data memory space) oraz przestrzeń pamięci programu (ang. program memory space). Dodatkowo mikrokontroler ATmega64 jest wyposażony w nieulotną pamięć EEPROM (ang. Electrically Erasable and Programmable Read-Only Memory) na przechowywanie danych. Wszystkie przestrzenie pamięciowe są liniowe i regularne.
Trwałość pamięci FLASH wynosi co najmniej 10.000 cykli zapisu/kasowania. Licznik rozkazów (ang. Program Counter, PC) w ATmega64 jest 15-bitowy, co pozwala mu na zaadresowanie 32768 komórek pamięci programu. Działanie sekcji programu boot-loadera wraz z powiązanymi bitami blokującymi dla bezpieczeństwa oprogramowania jest opisane szczegółowo w rozdziale "Wsparcie bootloadera – odczyt przy zapisie – samoprogramowanie".
W rozdziale "Programowanie pamięci" znajdziesz szczegółowy opis szeregowego ładowania programu do pamięci FLASH za pomocą końcówek interfejsu SPI (ang. Serial Programming Interface), JTAG lub trybu programowania równoległego.
Tablice ze stałymi mogą być umieszczane w całej przestrzeni adresowej pamięci programu (zobacz na opis instrukcji LPM).
Mapa pamięci
programu
Konfiguracja | Wewnętrzna pamięć danych SRAM | Zewnętrzna pamięć danych SRAM |
Tryb normalny | 4096 | do 64KB |
Tryb kompatybilności z ATmega103 | 4000 | do 64KB |
Poniższy rysunek pokazuje organizację pamięci SRAM w ATmega64:
Konfiguracja pamięci A | Konfiguracja pamięci B | |
ATmega64 jest złożonym mikrokontrolerem posiadającym więcej modułów peryferyjnych niż może być obsługiwane przez 64 komórki zarezerwowane w kodach operacyjnych dla instrukcji IN i OUT. Do rozszerzonej przestrzeni we/wy w SRAM od adresu 0x60 do 0xFF można stosować tylko instrukcje LD/LDS/LDD i ST/STS/STD. Rozszerzona przestrzeń we/wy nie istnieje, gdy mikrokontroler ATmega64 pracuje w trybie kompatybilności z ATmega103.
Pierwsze 4352 adresy pamięci danych odnoszą się do zestawu rejestrów ogólnego przeznaczenia, pamięci we/wy, rozszerzonej pamięci we/wy oraz wewnętrznej pamięci SRAM. Pierwsze 32 adresy obejmują zestaw rejestrów, następne 64 obejmują standardową pamięć we/wy, dalej występuje 160 komórek rozszerzonej pamięci we/wy i następne 4096 adresów obejmuje wewnętrzną pamięć danych SRAM.
W trybie kompatybilności z ATmega103 pierwsze 4096 adresów pamięci danych obejmuje zestaw rejestrów, pamięć we/wy i wewnętrzną pamięć SRAM. Pierwsze 32 adresy odnoszą się do zestawu rejestrów, następne 64 adresy odnoszą się do standardowej pamięci we/wy i kolejne 4000 adresów obejmuje komórki wewnętrznej pamięci SRAM.
Z ATmega można używać opcjonalnej, zewnętrznej pamięci danych SRAM. Pamięć ta zajmie obszar pozostałych adresów w 64K przestrzeni adresowej. Obszar ten rozpoczyna się za wewnętrzną pamięcią SRAM. Zestaw rejestrów, we/wy, rozszerzone we/wy i wewnętrzna pamięć SRAM zajmują najniższe 4352 bajty w trybie normalnym i najniższe 4096 bajty w trybie kompatybilności z ATmega103 (brak rozszerzonego we/wy), zatem w trakcie używania 64KB (65536 B) pamięci zewnętrznej, 61184 bajty tej pamięci jest dostępne w trybie normalnym i 61440 bajty w trybie kompatybilności z ATmega105. Więcej szczegółów na temat korzystania z pamięci zewnętrznej znajdziesz w podrozdziale "Interfejs pamięci zewnętrznej".
Gdy adresy odnoszące się do przestrzeni pamięci SRAM wykraczają poza komórki wewnętrznej pamięci danych, to następuje dostęp do pamięci zewnętrznej SRAM w obrębie tej samej instrukcji mikroprocesora (pamięć zewnętrzna nie wymaga osobnych instrukcji przy dostępie do niej z poziomu programu). Przy dostępie do pamięci wewnętrznych końcówki strobowe odczytu i zapisu (PG0 i PG1) są nieaktywne przez cały cykl dostępu. Pamięć zewnętrzna SRAM jest uaktywniana ustawieniem bitu SRE w rejestrze MCUCR. Dostęp do pamięci zewnętrznej zabiera jeden dodatkowy takt na bajt w porównaniu z dostępem do wewnętrznej pamięci SRAM. Oznacza to, iż rozkazy LD, ST, LDS, STS, LDD, STD, PUSH i POP wykonują się o jeden dodatkowy takt zegara dłużej. Jeśli stos zostanie umieszczony w pamięci zewnętrznej SRAM, to przerwania, wywołania podprogramów i powroty zajmują trzy dodatkowe takty zegara, ponieważ 2-bajtowy licznik rozkazów jest zapisywany na stos i odczytywany ze stosu, a dostęp do pamięci zewnętrznej nie korzysta z zakładkowego dostępu w pamięci wewnętrznej. Gdy zewnętrzna pamięć SRAM jest używana z taktami oczekiwania, to jednobajtowy dostęp zewnętrzny zabiera dwa, trzy lub cztery dodatkowe takty zegarowe odpowiednio dla jednego, dwóch lub trzech taktów oczekiwania. Przerwania, wywołania podprogramów i powroty będą potrzebowały pięć, siedem lub dziewięć taktów zegarowych więcej niż określono w opisie rozkazów AVR dla jednego, dwóch lub trzech taktów oczekiwania.
Pięć różnych trybów adresowania pamięci danych pokrywa: adresowanie bezpośrednie (ang. Direct Addressing Mode), adresowanie pośrednie z przesunięciem (ang. Indirect with Displacement Addressing Mode), adresowanie pośrednie (ang. Indirect Addressing Mode), adresowanie pośrednie z predekrementacją (ang. Indirect with Pre-decrement Addressing Mode) oraz adresowanie pośrednie z postinkrementacją (ang. Indirect with Post-increment Addresing Mode). W zestawie rejestrów rejestry od R26 do R31 pełnią dodatkową funkcję rejestrów wskaźnikowych do pośredniego adresowania pamięci.
Adresowanie bezpośrednie obejmuje całą przestrzeń danych.
Adresowanie pośrednie z przesunięciem obejmuje 63 komórki od adresu bazowego danego w rejestrze Y lub Z.
Gdy jest używane pośrednie adresowanie z automatyczną predekrementacją lub postinkrementacją, rejestry adresowe X, Y lub Z są zwiększane lub zmniejszane.
Wszystkie te tryby adresowania w ATmega64 pozwalają na dostęp do każdej komórki w przestrzeni danych: do zestawu 32 rejestrów ogólnego przeznaczenia, 64 rejestrów we/wy oraz 4096 bajtów wewnętrznej pamięci danych SRAM. Opis zestawu rejestrów znajdziesz w podrozdziale "Zestaw rejestrów ogólnego przeznaczenia".
Dostęp do pamięci SRAM wykonywany jest w dwóch taktach clkCPU, co pokazuje poniższy rysunek:
Rejestry dostępu do EEPROM znajdują się w przestrzeni we/wy.
Czasy dostępu dla EEPROM są podane przy opisie rejestru sterującego pamięcią EEPROM, EECR (ang. EEPROM Control Register). Jednakże funkcja odmierzająca samoczynnie czas pozwala wykryć oprogramowaniu użytkownika, kiedy można zapisać następny bajt. Jeśli kod użytkownika zawiera instrukcje, które zapisują pamięć EEPROM, należy podjąć pewne środki ostrożności. W mocno filtrowanych źródłach zasilania napięcie VCC może wzrastać lub opadać wolno przy włączaniu/wyłączaniu. Powoduje to, iż mikrokontroler przez pewien okres czasu pracuje przy napięciu niższym od określonego jako minimalne dla używanej częstotliwości zegarowej. Zobacz do podrozdziału "Zapobieganie uszkodzeniu danych w EEPROM", gdzie znajdziesz więcej informacji o tym, jak unikać problemów w takich sytuacjach.
Aby zapobiec niezamierzonym zapisom w EEPROM, należy zastosować specjalną procedurę zapisu. Zobacz do opisu rejestru EECR.
Gdy odczytywana jest pamięć EEPROM, to mikroprocesor zostaje wstrzymany przez cztery takty zegarowe przed wykonaniem następnej instrukcji. Gdy zapisywana jest pamięć EEPROM, mikroprocesor jest wstrzymywany przez dwa takty zegara przed wykonaniem następnej instrukcji.
Poniższe przykłady kodów pokazują po jednej funkcji w asemblerze i w języku C dla zapisu EEPROM. Przykłady zakładają globalne wyłączenie przerwań (wyzerowany bit I w rejestrze stanu SREG), aby żadne z przerwań nie wystąpiło podczas wykonywania tych funkcji. Założono również, iż oprogramowanie nie korzysta z boot-loadera. Jeśli kod programu ładującego jest obecny, to funkcja zapisu EEPROM musi również czekać na zakończenie każdego wykonywanego rozkazu SPM.
Przykład w kodzie maszynowym |
EEPROM_write: ; Czekaj na zakończenie poprzedniego zapisu sbic EECR,EEWE rjmp EEPROM_write ; Ustaw adres (r18:r17) w rejestrze adresowym out EEARH, r18 out EEARL, r17 ; Zapisz dane (r16) do rejestru danych out EEDR,r16 ; Zapisz logiczną jedynkę w bicie EEMWE sbi EECR,EEMWE ; Rozpocznij zapis EEPROM przez ustawienie EEWE sbi EECR,EEWE ret |
Przykład w języku C |
void EEPROM_write(unsigned int uiAddress, unsigned char ucData) { /* Czekaj na zakończenie poprzedniego zapisu */ while(EECR & (1<<EEWE)) ; /* Ustaw rejestry adresu i danych */ EEAR = uiAddress; EEDR = ucData; /* Zapisz logiczną jedynkę w bicie EEMWE */ EECR |= (1<<EEMWE); /* Rozpocznij zapis EEPROM przez ustawienie EEWE */ EECR |= (1<<EEWE); } |
Następne przykłady kodu pokazują funkcje w asemblerze i w języku C dla odczytu EEPROM. Przykłady zakładają globalne wyłączenie przerwań podczas wykonywania tych funkcji..
Przykład w kodzie maszynowym |
EEPROM_read: ; Czekaj na zakończenie poprzedniego zapisu sbic EECR,EEWE rjmp EEPROM_read ; Ustaw adres (r18:r17) w rejestrze adresowym out EEARH, r18 out EEARL, r17 ; Rozpocznij odczyt EEPROM przez zapis bitu EERE sbi EECR,EERE ; Odczytaj dane z rejestru danych in r16,EEDR ret |
Przykład w języku C |
unsigned char EEPROM_read(unsigned int uiAddress) { /* Czekaj na zakończenie poprzedniego zapisu while(EECR & (1<<EEWE)) ; /* Ustaw rejestr adresowy */ EEAR = uiAddress; /* Rozpocznij odczyt EEPROM przez zapis bitu EERE */ EECR |= (1<<EERE); /* Zwróć dane z rejestru danych */ return EEDR; } |
Przy wejściu w tryb uśpienia wyłączenia zasilania podczas aktywnej operacji zapisu EEPROM, operacja ta będzie kontynuowana aż do swojego zakończenia. Jednakże po zakończeniu operacji zapisu oscylator kontynuuje pracę i w konsekwencji mikrokontroler nie wejdzie w pełni w tryb wyłączenia. Dlatego zaleca się sprawdzenie zakończenia operacji zapisu EEPROM przed wejściem w ten tryb uśpienia.
Podczas okresów niskiego napięcia zasilającego VCC dane w EEPROM mogą ulec uszkodzeniu przy zapisie, ponieważ napięcie zasilające jest zbyt niskie na poprawne funkcjonowanie mikroprocesora oraz EEPROM. Problem ten jest taki sam jak w systemach z zewnętrznymi pamięciami EEPROM i te same rozwiązania powinny być stosowane.
Uszkodzenie danych w EEPROM może być spowodowane przez dwie sytuacje, gdy napięcie jest zbyt niskie. Po pierwsze normalna sekwencja zapisu do EEPROM wymaga minimalnego napięcia, aby zadziałać prawidłowo. Po drugie sam mikroprocesor może nieprawidłowo wykonywać instrukcje, jeśli napięcie zasilania jest zbyt niskie.
Uszkodzeniu danych w EEPROM można łatwo zapobiec, stosując następujące zalecenia projektowe:
Utrzymuj końcówkę AVR RESET w stanie aktywnym (niskim 0) podczas okresów niewystarczającego napięcia zasilania. Można to zrobić, przez uaktywnienie wewnętrznego detektora spadku napięcia (ang. Brown-out Detector, BOD). Jeśli poziom wykrywania wewnętrznego detektora BOD nie odpowiada wymaganemu poziomowi wykrywania, to można użyć zewnętrznego układu resetowania przy niskim napięciu VCC. Jeśli reset wystąpi podczas operacji zapisu, operacja ta zostanie dokończona o ile napięcie zasilania jest wystarczające.
Wszystkie układy we/wy ATmega64 obsługiwane są poprzez rejestry w przestrzeni we/wy. Dostęp do wszystkich rejestrów we/wy wykonywany jest przez instrukcje LD/LDS/LDD i ST/STS/STD, przesyłające dane pomiędzy 32 rejestrami ogólnego przeznaczenia a przestrzenią we/wy. Rejestry we/wy o adresach w zakresie 0x00 – 0x1F są bezpośrednio dostępne bitowo przy pomocy instrukcji SBI i CBI. W rejestrach tych wartość pojedynczych bitów można sprawdzać instrukcjami SBIS i SBIC. Gdy są używane dedykowane instrukcje IN i OUT, należy używać adresów we/wy 0x00 – 0x3F. Gdy rejestry we/wy są adresowane w przestrzeni danych za pomocą instrukcji LD i ST, należy do tych adresów dodać 0x20.
Dla kompatybilności z przyszłymi mikrokontrolerami zarezerwowane bity powinny być zapisywane stanami 0 przy dostępie do rejestrów. Zarezerwowanych adresów w pamięci we/wy nie należy nigdy zapisywać.
Niektóre ze znaczników stanu są zerowane przez zapis w nich stanu 1. Zwróć uwagę, iż w przeciwieństwie do większości innych mikrokontrolerów AVR instrukcje CBI i SBI działają tylko na określonym bicie i można je z tego powodu używać na rejestrach zawierających takie znaczniki stanu. Instrukcje CBI i SBI pracują jedynie na rejestrach od 0x00 do 0x1F.
Rejestry we/wy oraz sposoby sterowania modułów peryferyjnych opisane są w dalszych rozdziałach tej instrukcji.
Gdy zostanie uaktywniona pamięć zewnętrzna (ang. eXternal MEMory, XMEM), staje się dostępna przestrzeń adresowa poza wewnętrzną pamięcią SRAM przy użyciu dedykowanych końcówek pamięci zewnętrznej:
Poniższe rysunki przedstawiają konfigurację pamięci:
Konfiguracja pamięci A | Konfiguracja pamięci B | |
Uwaga: | 1. | ATmega64 nie w trybie kompatybilności z ATmega103:
dostępna konfiguracja pamięci A (konfiguracja
pamięci B nieaktywna). ATmega64 w trybie kompatybilności z ATmega103: dostępna konfiguracja pamięci B (konfiguracja pamięci A nieaktywna). |
Oba rejestry sterowania pamięcią zewnętrzną, XMCRA i XMCRB, są umieszczone w rozszerzonej przestrzeni we/wy. W trybie kompatybilności z ATmega103 rejestry te są niedostępne, a w konsekwencji również są niedostępne funkcje wybierane przez nie. Mikrokontroler wciąż jest kompatybilny z ATmega103, ponieważ funkcji tych nie było w ATmega103. Ograniczenia w trybie kompatybilności z ATmega103 są następujące:
Interfejs złożony jest z:
Bity sterujące interfejsem pamięci zewnętrznej znajdują się w trzech rejestrach: w rejestrze sterującym mikrokontrolerem (ang. MCU Control Register – MCUCR), w rejestrze A sterującym pamięcią zewnętrzną (ang. External Memory Control Register A – XMCRA) i w rejestrze B sterującym pamięcią zewnętrzną (ang. External Memory Control Register B – XMCRB).
Gdy zostanie uaktywniony interfejs XMEM, unieważnia on ustawienia w rejestrach kierunków danych, które odnoszą się do portów przeznaczonych na interfejs XMEM. Interfejs XMEM automatycznie wykrywa, czy dostęp dotyczy pamięci wewnętrznej lub zewnętrznej. Jeśli dostęp jest zewnętrzny, to interfejs XMEM wyprowadzi adres, dane i sygnały sterujące na porty zgodnie z poniższym rysunkiem (przebiegi przedstawiono z pominięciem taktów oczekiwania):
Gdy sygnał ALE (ang. Address Latch Enable) przechodzi ze stanu wysokiego w niski, na liniach AD7:0 jest ważny adres. Podczas przesyłu danych sygnał ALE ma stan niski. Gdy zostanie włączony interfejs XMEM, to również dostęp do pamięci wewnętrznej spowoduje działania na portach adresu, ALE i danych, lecz stroby RD i WR nie zmienią swoich stanów podczas tych operacji.
Gdy interfejs XMEM jest wyłączony, to są używane normalne ustawienia końcówek i ich kierunków przesyłu danych. Zauważ, iż przy wyłączonym interfejsie XMEM przestrzeń adresowa ponad granicą wewnętrznej pamięci SRAM nie jest odwzorowywana w SRAM.
Powyższy rysunek przedstawia sposób podłączenia zewnętrznej pamięci SRAM do mikrokontrolera AVR za pomocą układu ośmiu przerzutników D typu Latch (zwykle jest to układ 74573 lub jego odpowiednik), które przepuszczają dane, gdy wejście bramkujące G ma stan wysoki.
Z powodu dużej prędkości pracy interfejsu XRAM, przerzutniki zatrzaskowe adresu należy wybierać z uwagą dla prędkości systemu powyżej 8 MHz przy 4V i 4 MHz przy 2,7V. Przy pracy w warunkach wykraczających poza te częstotliwości typowe stare serie przerzutników Latch typu 74HC stają się nieodpowiednie. Interfejs pamięci zewnętrznej został zaprojektowany do współpracy z przerzutnikami Latch serii 74AHC. Jednakże można zastosować większość przerzutników Latch pod warunkiem spełniania przez nie następujących parametrów czasowych:
Interfejs pamięci zewnętrznej zaprojektowano z zagwarantowaniem minimalnego
czasu podtrzymania adresu po przejściu G w stan niski równego
Oporniki podciągające na portach AD7:0 można aktywować, jeśli odpowiadający im rejestr portu zostanie zapisany stanem logicznym jeden. Aby zredukować pobór energii w trybie uśpienia, zaleca się wyłączenie oporników podciągających przez zapis zera do rejestru portu przed wejściem w uśpienie.
Interfejs XMEM dostarcza również podtrzymywania magistrali (ang. Bus Keeper) na liniach AD7:0. Podtrzymywanie można włączać lub wyłączać programowo, co podano w opisie rejestru sterującego pamięcią zewnętrzną (ang. External Memory Control Register B – XMCRB). Gdy podtrzymywanie jest włączone, to zapewni zdefiniowany poziom logiczny (zero lub jeden) na magistrali AD7:0, gdy linie te w przeciwnym przypadku zostałyby przełączone w stan wysokiej impedancji przez interfejs XMEM.
Pamięci zewnętrzne posiadają różne wymogi czasowe. Aby je spełnić, interfejs XMEM mikrokontrolera ATmega64A udostępnia cztery różne ustawienia taktów oczekiwania opisane w poniższej tabelce (zobacz do opisu rejestru XMCRA):
SRWn1 | SRWn0 | Takty oczekiwania |
0 | 0 | Bez taktów oczekiwania. |
0 | 1 | Jeden takt oczekiwania podczas strobu odczytu/zapisu. |
1 | 0 | Dwa takty oczekiwania podczas strobu odczytu/zapisu. |
1 | 1 | Oczekiwanie dwóch taktów podczas odczytu/zapisu i jednego taktu przy wysyłaniu nowego adresu. |
Ważne jest rozważenie specyfikacji czasowych zewnętrznej pamięci przed wyborem taktów oczekiwania. Najważniejszym parametrem jest czas dostępu dla pamięci zewnętrznej w porównaniu z wymogiem ustawiania danych mikrokontrolera ATmega64A. Czas dostępu dla pamięci zewnętrznej jest zdefiniowany jako czas liczony od momentu otrzymania sygnałów wyboru/adresu układu do momentu pojawienia się danych spod tego adresu na magistrali. Ten czas dostępu nie może przekraczać czasu od momentu przejścia impulsu ALE w stan niski do momentu, gdy dane muszą być stabilne podczas sekwencji odczytu (czas: tLLRL+ tRLRH - tDVRH wartości tych czasów znajdziesz w parametrach elektrycznych mikrokontrolera ATmega64). Takty oczekiwania są ustawiane programowo. Dodatkową własnością jest możliwość podziału przestrzeni pamięci zewnętrznej na dwa sektory z indywidualnymi ustawieniami taktów oczekiwania. Umożliwia to podłączenie do tego samego interfejsu XMEM dwóch różnych układów pamięciowych o różnych wymaganiach czasowych.
Zauważ, iż interfejs XMEM jest asynchroniczny, a przebiegi czasowe na poniższych rysunkach odnoszą się do wewnętrznego zegara systemowego. Skos (ang. skew) pomiędzy zegarem wewnętrznym a zewnętrznym (XTAL1) nie jest gwarantowany (różni się pomiędzy układami oraz zależy od temperatury i napięcia zasilającego). W konsekwencji interfejs XMEM nie jest przystosowany do pracy synchronicznej.
Cykle zewnętrznej pamięci danych bez taktów oczekiwania(1)
(SRWn1 = 0 i SRWn0 =0)
Cykle zewnętrznej pamięci danych przy SRWn1 = 0 i SRWn0 = 1(1)
Cykle zewnętrznej pamięci danych przy SRWn1 = 1 i SRWn0 = 0(1)
Cykle zewnętrznej pamięci danych przy SRWn1 = 1 i SRWn0 = 1(1)
Konfiguracja pamięci A (ATmega64) |
Konfiguracja pamięci B (Tryb kompatybilności z ATmega103) |
|
Ponieważ pamięć zewnętrzna jest odwzorowywana w przestrzeni adresowej za pamięcią wewnętrzną (jak na rysunku powyżej), to pamięć zewnętrzna nie jest adresowana przy dostępie do pierwszych 4352 bajtów przestrzeni danych. Może się wydawać, iż te pierwsze 4352 bajty pamięci zewnętrznej jest niedostępne (adresy pamięci zewnętrznej od 0x0000 do 0x10FF). Jednakże przy dołączaniu pamięci zewnętrznej mniejszej od 64 KB, na przykład 32 KB, te komórki są łatwo dostępne po prostu przez adresowanie od 0x8000 do 0x90FF. Ponieważ bit A15 nie jest połączony z pamięcią zewnętrzną, to adresy od 0x8000 do 0x90FF pojawiają się dla pamięci zewnętrznej jako adresy od 0x0000 do 0x10FF. Adresowanie ponad adres 0x90FF nie jest zalecane, ponieważ zaadresuje komórkę pamięci zewnętrznej, do której jest już dostęp pod innym (niższym) adresem. Dla programu aplikacji zewnętrzna pamięć 32 KB pojawi się jako 32 KB liniowa przestrzeń adresowa od 0x1100 do 0x90FF. Zilustrowane to zostało na poniższym rysunku.
Konfiguracja pamięci A (ATmega64) |
Konfiguracja pamięci B (Tryb kompatybilności z ATmega103) |
|
Gdy mikrokontroler pracuje w trybie kompatybilności z ATmega103, wewnętrzna przestrzeń adresowa ma rozmiar 4096 bajtów (dokładnie 4KB). Wynika z tego, iż dostęp do pierwszych 4096 bajtów pamięci zewnętrznej można uzyskać pod adresami od 0x8000 do 0x8FFF. Dla programu aplikacji pamięć zewnętrzna pojawi się jako jedna 32 KB liniowa przestrzeń adresowa od adresu 0x1000 do 0x8FFF.
Konfiguracja pamięci A (ATmega64) |
Konfiguracja pamięci B (Tryb kompatybilności z ATmega103) |
|
Ponieważ pamięć zewnętrzna jest odwzorowana w przestrzeni adresowej mikrokontrolera AVR jak na powyższym rysunku, tylko 60KB pamięci zewnętrznej jest standardowo dostępne (przestrzeń adresowa od 0x0000 do 0x10FF/0x0FFF jest zarezerwowana na pamięć wewnętrzną). Jednakże możliwe jest wykorzystanie całej pamięci zewnętrznej poprzez maskowanie na zero starszych bitów adresowych. Można to zrobić przez użycie bitów XMM i sterowanych przez program najstarszych bitów adresu. Przez ustawienie portu C na wyprowadzanie wartości 0x00 i zwolnienie najbardziej znaczących bitów do normalnej pracy końcówek portu interfejs pamięci zaadresuje 0x0000 - 0x1FFF. Zobacz na poniższe przykłady.
Przykład w kodzie maszynowym |
; OFFSET jest zdefiniowany na 0x2000 w celu zapewnienia ; dostępu do pamięci zewnętrznej ; Skonfiguruj port C (górny bajt adresu) na ; wyprowadzanie 0x00, gdy końcówki zostaną uwolnione ; do normalnej pracy końcówki portu ldi r16, 0xFF out DDRC, r16 ldi r16, 0x00 out PORTC, r16 ; uwolnij PC7:5 ldi r16, (1<<XMM1)|(1<<XMM0) sts XMCRB, r16 ; wpisz 0xAA pod adres 0x0001 pamięci zewnętrznej ldi r16, 0xaa sts 0x0001+OFFSET, r16 ; z powrotem przywróć PC7:5 do pracy z pamięcią zewnętrzną ldi r16, (0<<XMM1)|(0<<XMM0) sts XMCRB, r16 ; umieść 0x55 pod adresem (OFFSET + 1) pamięci zewnętrznej ldi r16, 0x55 sts 0x0001+OFFSET, r16 |
Przykład w języku C |
#define OFFSET 0x2000 void XRAM_example(void) { unsigned char *p = (unsigned char *) (OFFSET + 1); DDRC = 0xFF; PORTC = 0x00; XMCRB = (1<<XMM1) | (1<<XMM0); *p = 0xaa; XMCRB = 0x00; *p = 0x55; } |
Przy stosowaniu tej opcji należy postępować bardzo ostrożnie, ponieważ większość pamięci jest wymaskowana.
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0x35 (0x55) | SRE | SRW10 | SE | SM1 | SM0 | SM2 | IVSEL | IVCE | MCUCR |
Zapis/Odczyt | Z/O | Z/O | Z/O | O | Z/O | Z/O | Z/O | Z/O | |
Wartość początkowa | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Zapis jedynki do bitu SRE powoduje włączenie interfejsu pamięci zewnętrznej. Zostają uaktywnione funkcje końcówek AD7:0, A15:8, ALE, WR i RD jako alternatywne funkcje końcówek. Bit SRE unieważnia ustawienia kierunku przesyłu danych na końcówce w odpowiednich rejestrach kierunku danych. Wpisanie zera do SRE wyłącza interfejs pamięci zewnętrznej i przywraca normalne funkcje końcówek oraz ich kierunki przesyłu danych.
Szczegółowy opis dla ATmega64 znajdziesz poniżej w opisie bitów rejestru XMCRA. W trybie kompatybilności z ATmega103 zapis jedynki do bitu SRW10 uaktywnia takt oczekiwania i jeden dodatkowy cykl będzie dodawany podczas strobu odczytu/zapisu, jak na rysunku poniżej:
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
(0x6D) | – | SRL2 | SRL1 | SRL0 | SRW01 | SRW00 | SRW11 | – | XMCRA |
Zapis/Odczyt | O | Z/O | Z/O | O | Z/O | Z/O | Z/O | O | |
Wartość początkowa | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Bity te są zarezerwowane i zawsze zwracają zero przy odczycie. Dla kompatybilności z przyszłymi modelami mikrokontrolera zapisuj te bity stanem zero.
Możliwe jest skonfigurowanie różnych stanów oczekiwania dla różnych adresów pamięci zewnętrznej. Przestrzeń adresową pamięci zewnętrznej można podzielić na dwa sektory, które posiadają osobne bity stanów oczekiwania. Bity SRL2, SRL1 i SRL0 wybierają podział tych sektorów, co pokazano na poniższym rysunku i w tabelce. Standardowo bity SRL2, SRL1 i SRL0 są ustawione na zero i cała przestrzeń adresowa pamięci zewnętrznej traktowana jest jako jeden sektor. W tym przypadku takty oczekiwania są konfigurowane przez bity SRW11 i SRW10.
Konfiguracja pamięci A (ATmega64) |
Konfiguracja pamięci B (Tryb kompatybilności z ATmega103) |
|
SRL2 | SRL1 | SRL0 | Granice sektorów |
0 | 0 | 0 | Dolny sektor = N/A Górny sektor = 0x1100 - 0xFFFF |
0 | 0 | 1 | Dolny sektor = 0x1100 - 0x1FFF Górny sektor = 0x2000 - 0xFFFF |
0 | 1 | 0 | Dolny sektor = 0x1100 - 0x3FFF Górny sektor = 0x4000 - 0xFFFF |
0 | 1 | 1 | Dolny sektor = 0x1100 - 0x5FFF Górny sektor = 0x6000 - 0xFFFF |
1 | 0 | 0 | Dolny sektor = 0x1100 - 0x7FFF Górny sektor = 0x8000 - 0xFFFF |
1 | 0 | 1 | Dolny sektor = 0x1100 - 0x9FFF Górny sektor = 0xA000 - 0xFFFF |
1 | 1 | 0 | Dolny sektor = 0x1100 - 0xBFFF Górny sektor = 0xC000 - 0xFFFF |
1 | 1 | 1 | Dolny sektor = 0x1100 - 0xDFFF Górny sektor = 0xE000 - 0xFFFF |
Bity SRW11 i SRW10 określają liczbę taktów oczekiwania dla górnego sektora przestrzeni adresowej pamięci wewnętrznej. Opis znajdziesz w tabelce poniżej.
Bity SRW01 i SRW00 określają liczbę taktów oczekiwania dla górnego sektora przestrzeni adresowej pamięci wewnętrznej. Opis znajdziesz w tabelce poniżej.
SRWn1 | SRWn0 | Takty oczekiwania |
0 | 0 | Bez taktów oczekiwania. |
0 | 1 | Jeden takt oczekiwania podczas strobu odczytu/zapisu. |
1 | 0 | Dwa takty oczekiwania podczas strobu odczytu/zapisu. |
1 | 1 | Oczekiwanie dwóch taktów podczas odczytu/zapisu i jednego taktu przy wysyłaniu nowego adresu. |
n = 0, dolny sektor; n = 1, górny sektor
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
(0x6C) | XMBK | – | – | – | – | XMM2 | XMM1 | XMM0 | XMCRB |
Zapis/Odczyt | Z/O | O | O | O | O | Z/O | Z/O | Z/O | |
Wartość początkowa | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Wpisanie jedynki do bitu XMBK uaktywnia opcję podtrzymywania na liniach AD7:0 interfejsu pamięci zewnętrznej. Gdy podtrzymywanie jest włączone, zapewnia poziom logiczny zero lub jeden na liniach AD7:0, gdy w przeciwnym wypadku linie te weszłyby w stan wysokiej impedancji. Wpisanie zera do XMBK wyłącza tę funkcję. Podtrzymywanie nie jest powiązane z bitem SRE w rejestrze MCUCR, zatem nawet gdy interfejs XMEM jest nieaktywny, podtrzymywanie wciąż działa tak długo, jak bit XMBK ma wartość jeden.
Bity te są zarezerwowane i zawsze zwracają zero przy odczycie. Dla kompatybilności z przyszłymi modelami mikrokontrolera zapisuj te bity stanem zero.
Gdy pamięć zewnętrzna zostaje uaktywniona, wszystkie końcówki portu C są
standardowo używane jako górne bity adresowe. Jeśli nie jest potrzebna pełna
przestrzeń adresowa 60 KB do dostępu do pamięci zewnętrznej, to niektóre lub
wszystkie końcówki portu C mogą zostać uwolnione do spełniania normalnych
funkcji końcówek portu, co opisuje tabelka poniżej. Zobacz do podrozdziału "Używanie
wszystkich komórek pamięci zewnętrznej mniejszej niż 64 KB".
Końcówki portu C zwolnione do swoich normalnych funkcji przy uaktywnieniu pamięci zewnętrznej
XMM2 | XMM1 | XMM0 | Liczba górnych bitów adresu | Zwolnione końcówki portu |
0 | 0 | 0 | 8 (pełna przestrzeń 60 KB) | Żadna |
0 | 0 | 1 | 7 | PC7 |
0 | 1 | 0 | 6 | PC7 - PC6 |
0 | 1 | 1 | 5 | PC7 - PC5 |
1 | 0 | 0 | 4 | PC7 - PC4 |
1 | 0 | 1 | 3 | PC7 - PC3 |
1 | 1 | 0 | 2 | PC7 - PC2 |
1 | 1 | 1 | Bez górnych bitów adresowych | Pełny port C |
Bit | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | |
0x1F (0x3F) | – | – | – | – | – | EEAR10 | EEAR9 | EEAR8 | EEARH |
0x1E (0x3E) | EEAR7 | EEAR6 | EEAR5 | EEAR4 | EEAR3 | EEAR2 | EEAR1 | EEAR0 | EEARL |
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
Zapis/Odczyt | O | O | O | O | O | Z/O | Z/O | Z/O | |
Zapis/Odczyt | Z/O | Z/O | Z/O | Z/O | Z/O | Z/O | Z/O | Z/O | |
Wartość początkowa | 0 | 0 | 0 | 0 | 0 | 0 | X | X | |
X | X | X | X | X | X | X | X |
Te bity są zarezerwowane w ATmega64 i przy odczycie dają zawsze wartość 0.
Rejestry adresowe EEPROM – EEARH i EEARL – określają adres EEPROM (starszy i młodszy bajt adresu) w 2048-bajtowej przestrzeni pamięci EEPROM. Bajty EEPROM są adresowane liniowo od 0 do 2047. Początkowa zawartość rejestru EEAR jest niezdefiniowana. Właściwą wartość należy wpisać przed dostępem do EEPROM.
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0x1D (0x3D) | MSB | LSB | EEDR | ||||||
Zapis/Odczyt | Z/O | Z/O | Z/O | Z/O | Z/O | Z/O | Z/O | Z/O | |
Wartość początkowa | X | X | X | X | X | X | X | X |
Dla operacji zapisu w EEPROM rejestr EEDR zawiera dane do zapisania pod adresem podanym przez rejestr EEAR. Dla operacji odczytu z EEPROM rejestr EEDR zawiera dane odczytane z komórki EEPROM o adresie podanym w rejestrze EEAR.
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0x1C (0x3C) | – | – | – | – | EERIE | EEMWE | EEWE | EERE | EECR |
Zapis/Odczyt | O | O | O | O | Z/O | Z/O | Z/O | Z/O | |
Wartość początkowa | 0 | 0 | 0 | 0 | 0 | 0 | X | 0 |
Te bity są zarezerwowane w ATmega64 i zawsze przy odczycie dają zero.
Wpisanie jedynki do bitu EERIE włącza przerwania przy gotowości EEPROM, jeśli bit I w rejestrze SREG jest ustawiony. Wpisanie zera do EERIE wyłącza te przerwanie. Przerwanie od gotowości EEPROM jest generowane ciągle, gdy bit EEWE jest wyzerowany.
Bit ten umożliwia zabezpieczenie EEPROM przed przypadkowym zapisem. Określa on, czy ustawienie bitu EEWE na jeden spowoduje zapis do EEPROM. Gdy bit EEMWE zostanie ustawiony, to ustawienie bitu EEWE w ciągu czterech taktów zegarowych spowoduje zapis danych do EEPROM pod wybranym adresem. Jeśli bit EEMWE ma wartość zero, to ustawienie bitu EEWE nie spowoduje żadnego efektu. Gdy bit EEMWE zostanie ustawiony na jeden programowo, to będzie on automatycznie wyzerowany po upływie czterech taktów zegarowych.
Bit EEWE jest strobem zapisu EEPROM. Gdy zostaną poprawnie ustawione adres i dane, to należy wpisać jedynkę do bitu EEWE, aby dane zapisać w pamięci EEPROM. Przed dokonaniem tego zapisu należy ustawić na jeden bit uaktywnienia zapisu EEMWE, w przeciwnym razie zapis do EEPROM nie zostanie wykonany. Należy zastosować poniższą procedurę (kolejność kroków 3 i 4 jest istotna):
Pamięć EEPROM nie może być programowana podczas zapisu przez mikroprocesor danych do pamięci FLASH. Program użytkownika musi sprawdzić, czy programowanie FLASH jest ukończone przed zainicjowaniem zapisu do EEPROM. Krok 2 jest tylko wtedy istotny, gdy oprogramowanie zawiera boot loader, który pozwala mikroprocesorowi programować FLASH. Jeśli pamięć FLASH nigdy nie jest uaktualniana przez mikroprocesor, krok 2 można pominąć. Zobacz do rozdziału "Wsparcie bootloadera – odczyt przy zapisie – samoprogramowanie".
Uwaga: przerwanie pomiędzy krokiem 5 a 6 spowoduje porażkę cyklu zapisu, ponieważ bit uaktywniający zapis EEPROM, EEMWE, straci ważność (zostanie wyzerowany sprzętowo po czterech taktach zegara). Jeśli procedura przerwania uzyskująca dostęp do EEPROM przerwie pracę innemu procesowi dostępu do EEPROM, to rejestr EEAR lub EEDR zostanie zmodyfikowany, powodując porażkę przerwanego procesu dostępu do EEPROM. Zaleca się wyzerowanie globalnego znacznika przerwań I w rejestrze SREG w celu uniknięcia tych problemów.
Gdy upłynie czas przeznaczony na zapis, bit EEWE jest zerowany sprzętowo. Program użytkownika może przeglądać zawartość tego bitu i czekać na zero przed zapisem kolejnego bajtu. Gdy bit EEWE został ustawiony, mikroprocesor zatrzymuje się na dwa cykle przed wykonaniem następnej instrukcji.
Bit EERE jest strobem odczytu EEPROM. Gdy został ustawiony poprawny adres w rejestrze EEAR, należy wpisać logiczną jedynkę do bitu EERE, aby wyzwolić odczyt EEPROM. Odczyt zajmuje jedną instrukcję i zażądane dane są dostępne natychmiast. Gdy jest odczytywana pamięć EEPROM, mikroprocesor zatrzymuje się na cztery cykle przed wykonaniem następnej instrukcji. Użytkownik powinien przeglądać stan bitu EEWE przed rozpoczęciem operacji odczytu. Jeśli trwa operacja zapisu, nie można odczytywać EEPROM ani zmieniać zawartości rejestru EEAR.
Do odmierzania czasu przy dostępie do EEPROM wykorzystywany jest kalibrowany oscylator. Poniższa tablica wymienia typowy czas programowania przy dostępie do EEPROM z poziomu mikroprocesora.
Symbol | Liczba taktów kalibrowanego oscylatora RC(1) | Typowy czas programowania |
Zapis EEPROM (z mikroprocesora) | 8448 | 8,4 ms |
Uwaga: | 1. | Używa zegara 1 MHz niezależnie od ustawień bitów bezpiecznikowych CKSEL |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2024 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.