|
Wyjście Spis treści Wstecz Dalej
Autor artykułu |
©2026 mgr Jerzy Wałaszek
|

If you use Microchip copyrighted material solely for educational (non-profit) purposes falling under the “fair use” exception of the U.S. Copyright Act of 1976 then you do not need Microchip’s written permission. For example, Microchip’s
permission is not required when using copyrighted material in:
https://www.microchip.com/about-us/legal-information/copyright-usage-guidelines
Mikrokontroler udostępnia mechanizm samoprogramowania do samodzielnego ładowania i odczytywania kodu programu. Samoprogramowanie może wykorzystywać dowolny z dostępnych interfejsów danych i związanych z nimi protokołów komunikacyjnych do odczytu i zapisu (programowania) tego kodu w pamięci programu.
Pamięć programu jest uaktualniana krokami strona po stronie. Przed zaprogramowaniem strony danymi umieszczonymi w tymczasowym buforze, strona musi zostać wymazana. Bufor tymczasowy wypełniany jest po jednym słowie naraz przy pomocy instrukcji SPM, a bufor można zapełnić albo przed rozkazem kasowania strony (ang. Page Erase command), albo pomiędzy kasowaniem strony a operacją zapisu strony (ang. Page Write command):
Jeśli tylko część strony wymaga zmiany, reszta tej strony musi zostać zapamiętana (na przykład w tymczasowym buforze strony) przed kasowaniem, a następnie zapisana ponownie.
Jeśli jest wykorzystywana alternatywa 1, to program bootloadera może korzystać z użytecznej własności odczytu-modyfikacji-zapisu (ang. Read-Modify-Write), która pozwala oprogramowaniu użytkownika najpierw odczytać stronę, wykonać niezbędne zmiany, a następnie zapisać z powrotem zmodyfikowane dane.
Jeśli używana jest alternatywa 2, to nie można odczytać starych danych podczas ładowania, ponieważ strona została już skasowana. Tymczasowy bufor strony można zapisywać w dowolnej kolejności. Ważne jest, aby adres strony używany w obu operacjach Kasowania i Zapisu adresował tę samą stronę.
Aby wykonać operację kasowania strony pamięci FLASH, ustaw jej adres we wskaźniku Z (R30-31), wpisz “00000011” do rejestru SPMCSR i wykonaj instrukcję SPM w ciągu czterech taktów zegara po zapisie do SPMCSR. Dane w rejestrach R1 i R0 są ignorowane. Adres strony musi być wpisany do pola PCPAGE we wskaźniku Z. Pozostałe bity we wskaźniku Z będą zignorowane podczas tej operacji.
Uwaga: Jeśli w obrębie sekwencji czasowej wystąpi przerwanie, to nie można zapewnić dostępu w czterech taktach. Aby zapewnić operację atomową (niepodzielną czasowo), powinieneś zablokować przerwania przed zapisem do rejestru SPMCSR.
Aby wpisać słowo instrukcji, ustaw jego adres we wskaźniku Z i dane w rejestrach R1:R0, wpisz “00000001” do rejestru SPMCSR i w ciągu czterech taktów po zapisie rejestru SPMCSR wykonaj instrukcję SPM. Zawartość pola PCWORD w rejestrze Z jest używana do adresowania danych w buforze tymczasowym. Bufor tymczasowy wykasuje się automatycznie po operacji zapisu strony (ang. Page Write operation) lub przez zapis bitu RWWSRE w rejestrze SPMCSR. Jest również kasowany po resecie systemowym. Zauważ, iż nie można zapisać każdego adresu więcej niż raz bez skasowania bufora tymczasowego. Jeśli wystąpi zapis do pamięci EEPROM w środku operacji ładowania strony przez SPM, wszystkie załadowane dane będą stracone.
Aby wykonać zapis strony, ustaw jej adres we wskaźniku Z, wpisz “00000101” do rejestru SPMCSR i w ciągu czterech taktów po zapisie do SPMCSR wykonaj instrukcję SPM. Dane w rejestrach R1 i R0 są ignorowane. Adres strony musi być zapisany w polu PCPAGE. Pozostałe bity we wskaźniku Z muszą być zapisane zerami podczas tej operacji.
| Bit | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
| ZH (R31) | Z15 | Z14 | Z13 | Z12 | Z11 | Z10 | Z9 | Z8 |
| ZL (R30) | Z7 | Z6 | Z5 | Z4 | Z3 | Z2 | Z1 | Z0 |
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Ponieważ pamięć FLASH jest zorganizowana w strony, to licznik programu (ang. Program Counter) można potraktować tak, jakby składał się z dwóch różnych sekcji. Jedna sekcja składająca się z najmniej znaczących bitów adresuje słowa wewnątrz strony, natomiast bity najbardziej znaczące adresują te strony. Pokazane to jest na poniższym rysunku. Zauważ, że operacje kasowania strony (ang. page erase) i zapisu strony (ang. page write) używają osobnych adresów. Dlatego jest bardzo ważne, aby oprogramowanie boot-loadera adresowało tę samą stronę w obu tych operacjach.
Instrukcja LPM również korzysta ze wskaźnika Z do przechowywania adresu. Ponieważ instrukcja ta adresuje pamięć FLASH bajt po bajcie, to również bit LSB (bit Z0) wskaźnika Z jest używany.

Zauważ, iż operacja zapisu pamięci EEPROM zablokuje wszelkie programowanie pamięci FLASH. Odczyt bitów bezpiecznikowych i blokujących z poziomu oprogramowania jest również zablokowany podczas operacji zapisu EEPROM. Zaleca się sprawdzanie bitu stanu EEPE w rejestrze EECR i upewnieniu się, iż jest on wyzerowany, przed zapisywaniem rejestru SPMCR.
Możliwy jest programowy odczyt zarówno bitów bezpiecznikowych jak i bitów blokujących. Aby odczytać bity blokujące, załaduj wskaźnik Z wartością 0x0001 i ustaw bity BLBSET i SPMEN w rejestrze SPMCR. Gdy w ciągu trzech taktów mikroprocesora po tej operacji zostanie wykonana instrukcja LPM , to wartość bitów blokujących zostanie załadowana do rejestru docelowego. Bity BLBSET i SPMEN wyzerują się automatycznie po zakończeniu odczytu bitów blokujących lub jeśli żadna instrukcja LPM nie będzie wykonana w ciągu trzech taktów mikroprocesora lub żadna instrukcja SPM nie będzie wykonana w ciągu czterech taktów mikroprocesora. Gdy bity BLBSET i SPMEN wyzerują się, instrukcja LPM będzie działać zgodnie z opisem.
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Rd | – | – | – | – | – | – | LB2 | LB1 |
Algorytm odczytu dolnego bajtu bitów bezpiecznikowych jest podobny do algorytmu opisanego powyżej dla odczytu bitów blokujących. Aby odczytać dolny bajt bitów bezpiecznikowych, załaduj wskaźnik Z wartością 0x0000 i ustaw bity BLBSET i SPMEN w rejestrze SPMCR. Gdy instrukcja LPM zostanie wykonana w ciągu trzech taktów po ustawieniu bitów BLBSET i SPMEN w SPMCR, wartość dolnego bajtu bitów bezpiecznikowych (FLB) będzie załadowana do rejestru docelowego, jak pokazano poniżej.
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Rd | FLB7 | FLB6 | FLB5 | FLB4 | FLB3 | FLB2 | FLB1 | FLB0 |
Podobnie przy odczycie górnego bajtu bitów bezpiecznikowych załaduj wskaźnik Z wartością 0x0003. Gdy instrukcja LPM zostanie wykonana w ciągu trzech taktów po ustawieniu bitów BLBSET i SPMEN w SPMCR, wartość górnego bajtu bitów bezpiecznikowych (FHB) będzie załadowana do rejestru docelowego, jak pokazano poniżej.
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Rd | FHB7 | FHB6 | FHB5 | FHB4 | FHB3 | FHB2 | FHB1 | FHB0 |
Podobnie przy odczycie rozszerzonego bajtu bitów bezpiecznikowych załaduj wskaźnik Z wartością 0x0002. Gdy instrukcja LPM zostanie wykonana w ciągu trzech taktów po ustawieniu bitów BLBSET i SPMEN w SPMCR, wartość rozszerzonego bajtu bitów bezpiecznikowych (EFB) będzie załadowana do rejestru docelowego, jak pokazano poniżej.
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Rd | EFB7 | EFB6 | EFB5 | EFB4 | EFB3 | EFB2 | EFB1 | EFB0 |
Zaprogramowane bity bezpiecznikowe i blokujące mają przy odczycie stan zero, natomiast bity niezaprogramowane dają przy odczycie stan jeden.
Błędom w FLASH można łatwo zapobiec stosując się do następujących zaleceń projektowych (jedno jest wystarczające):
Kalibrowany oscylator RC jest używany do odmierzania czasu dostępów do pamięci FLASH. Poniższa tabela pokazuje typowy czas programowania FLASH przy dostępie przez mikroprocesor.
| Symbol | Min. czas programowania | Max. czas programowania |
| Zapis FLASH (wymazywanie strony, zapis strony i zapis bitów blokujących przez SPM) | 3,7 ms | 4,5 ms |
;-Procedura zapisuje jedną stronę danych z RAM do FLASH ; Pierwszy adres danych w RAM jest wskazywany przez wskaźnik Y ; Pierwszy adres danych we FLASH jest wskazywany przez wskaźnik Z ;-Obsługa błędów nie została zrealizowana ;-Procedura musi się znaleźć w obszarze boot-loadera ; (przynajmniej podprogram Do_spm). Tylko kod wewnątrz sekcji NRWW może ; być odczytywany podczas samoprogramowania (wymazywania strony i zapisu strony). ;-Używane rejestry: r0, r1, temp1 (r16), temp2 (r17), looplo (r24), ; loophi (r25), spmcrval (r20) ; W procedurze nie zastosowano zachowywania i odtwarzania rejestrów. ; Wykorzystanie rejestrów można zoptymalizować kosztem rozmiaru kodu. ;-Zakłada się, iż albo tablica przerwań została przeniesiona do sekcji ; boot-loadera, albo przerwania są wyłączone. .equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB jest rozmiarem strony w bajtach, nie w słowach .org SMALLBOOTSTART Write_page: ; Wymazywanie strony ldi spmcrval, (1<<PGERS) | (1<<SPMEN) rcall Do_spm ; Ponowne uaktywnienie sekcji RWW ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN) rcall Do_spm ; Przenieś dane z RAM do bufora strony FLASH ldi looplo, low(PAGESIZEB) ;Inicjuj zmienną pętli ldi loophi, high(PAGESIZEB) ;Niepotrzebne dla PAGESIZEB<=256 Wrloop: ld r0, Y+ ld r1, Y+ ldi spmcrval, (1<<SPMEN) rcall Do_spm adiw ZH:ZL, 2 sbiw loophi:looplo, 2 ;Użyj subi dla PAGESIZEB<=256 brne Wrloop ; Wykonaj zapis strony subi ZL, low(PAGESIZEB) ;Odtwórz wskaźnik sbci ZH, high(PAGESIZEB) ;Niepotrzebne dla PAGESIZEB<=256 ldi spmcrval, (1<<PGWRT) | (1<<SPMEN) rcall Do_spm ; Ponowne uaktywnienie sekcji RWW ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN) rcall Do_spm ; Odczytaj z powrotem i sprawdź, opcjonalne ldi looplo, low(PAGESIZEB) ;Inicjuj zmienną pętli ldi loophi, high(PAGESIZEB) ;Niepotrzebne dla PAGESIZEB<=256 subi YL, low(PAGESIZEB) ;Odtwórz wskaźnik sbci YH, high(PAGESIZEB) Rdloop: lpm r0, Z+ ld r1, Y+ cpse r0, r1 rjmp Error sbiw loophi:looplo, 1 ;Użyj subi dla PAGESIZEB<=256 brne Rdloop ; Wróć do sekcji RWW ; Sprawdź, czy odczyt sekcji RWW jest bezpieczny Return: in temp1, SPMCR sbrs temp1, RWWSB ;Jeśli bit RWWSB jest ustawiony, sekcja RWW nie jest jeszcze gotowa ret ; Ponowne uaktywnienie sekcji RWW ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN) rcall Do_spm rjmp Return Do_spm: ; Sprawdź zakończenie poprzedniej instrukcji SPM Wait_spm: in temp1, SPMCR sbrc temp1, SPMEN rjmp Wait_spm ; Wejście: spmcrval określa działanie SPM ; Wyłącz przerwania, jeśli są włączone, zachowaj stan in temp2, SREG cli ; Sprawdź, iż nie następuje zapis do EEPROM Wait_ee: sbic EECR, EEWE rjmp Wait_ee ; Sekwencja czasowa SPM out SPMCR, spmcrval spm ; Odtwórz SREG (aby włączyć przerwania, jeśli oryginalnie były włączone) out SREG, temp2 ret |
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
| 0x37 (0x57) | SPMIE | RWWSB | SIGRD | RWWSRE | BLBSET | PGWRT | PGERS | SPMEN | SPMCR |
| Zapis/Odczyt | Z/O | O | ZO | Z/O | Z/O | Z/O | Z/O | Z/O | |
| Wartość początkowa | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Gdy bit SPMIE zostanie zapisany jedynką i bit I w rejestrze stanu SREG jest ustawiony, to zostanie włączone przerwanie gotowości instrukcji SPM. Przerwanie to będzie wykonywane tak długo, jak bit SPMEN jest wyzerowany.
Gdy zostanie zainicjowana operacja samoprogramowania (wymazywanie lub zapis strony) w sekcji RWW, bit RWWSB jest ustawiany (na jeden) sprzętowo. Gdy bit ten jest ustawiony, to nie ma dostępu do sekcji RWW. Bit RWWSB wyzeruje się, gdy do bitu RWWSRE zostanie wpisana jedynka po zakończeniu operacji samoprogramowania. Alternatywnie bit RWWSB jest automatycznie zerowany, gdy zostanie zainicjowana operacja ładowania strony.
Jeśli ten bit zostanie zapisany logiczną jedynką w tym samym czasie co bit SPMEN, to instrukcja LPM wykonana w ciągu następnych trzech taktów odczyta bajt z wiersza sygnatury i umieści go w rejestrze docelowym. Szczegóły znajdziesz w podrozdziale "Programowy odczyt wiersza sygnatury". Instrukcja SPM wykonana w ciągu czterech taktów po ustawieniu bitów SIGRD i SPMEN nie będzie miała żadnego efektu. Operacja ta jest zarezerwowana na przyszły użytek i nie powinna być wykorzystywana.
Funkcjonalność tego bitu w ATmega 48A/48PA jest podzbiorem funkcjonalności w ATmega88A/88PA/168A/168PA/328/328P. Jeśli bit RWWSRE zostanie zapisany podczas wypełniania tymczasowego bufora strony, bufor zostanie wymazany i dane będą utracone.
Funkcjonalność tego bitu w ATmega 48A/48PA jest podzbiorem funkcjonalności w ATmega88A/88PA/168A/168PA/328/328P. Instrukcja LPM wykonana w ciągu trzech taktów po ustawieniu bitów BLBSET i SPMEN odczyta albo bity blokujące, albo bity bezpiecznikowe (zależnie od Z0 we wskaźniku Z) do rejestru docelowego. Szczegóły znajdziesz w podrozdziale "Programowy odczyt bitów bezpiecznikowych i blokujących".
Jeśli jedynka zostanie wpisana do tego bitu w tym samym czasie co do SPMEN, to następna instrukcja SPM w ciągu czterech taktów zegara wykona zapis strony danymi umieszczonymi w buforze tymczasowym. Adres strony zostanie pobrany z górnej części wskaźnika Z. Dane w rejestrach R1 i R0 są ignorowane. Bit PGWRT bit wyzeruje się automatycznie po zakończeniu zapisu strony lub jeśli żadna instrukcja SPM nie będzie wykonana w ciągu czterech taktów zegarowych. W czasie zapisu strony mikroprocesor jest zatrzymywany.
Jeśli jedynka zostanie wpisana do tego bitu w tym samym czasie co do SPMEN, to następna instrukcja SPM w ciągu czterech taktów zegara wykona kasowanie strony. Adres strony zostanie pobrany z górnej części wskaźnika Z. Dane w rejestrach R1 i R0 są ignorowane. Bit PGERS bit wyzeruje się automatycznie po zakończeniu kasowania strony lub jeśli żadna instrukcja SPM nie będzie wykonana w ciągu czterech taktów zegarowych. Mikroprocesor jest wstrzymany przez całą operację kasowania strony.
Ten bit włącza instrukcję SPM przez następne cztery takty zegarowe. Jeśli jedynka logiczna zostanie umieszczona w nim oraz w jednym z bitów RWWSRE, BLBSET, PGWRT lub PGERS, to następna instrukcja SPM będzie miała specjalne znaczenie, zobacz na opisy umieszczone powyżej. Jeśli będzie zapisany tylko sam bit SPMEN, to następna instrukcja SPM umieści wartość R1:R0 w tymczasowym buforze strony adresowanym przez wskaźnik Z. Najmłodszy bit, LSB, wskaźnika Z jest ignorowany. Bit SPMEN wyzeruje się automatycznie po zakończeniu instrukcji SPM lub jeśli żadna instrukcja SPM nie będzie wykonana w ciągu kolejnych czterech taktów zegarowych. Podczas wymazywania strony i zapisu strony bit pozostaje w stanie wysokim aż do zakończenia operacji.
Zapis innej kombinacji bitów niż “10001”, “01001”, “00101”, “00011” lub “00001” w dolnych pięciu bitach rejestru SPMCR nie wywołuje żadnego efektu.
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 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.