Kurs podstawowy
Fusebity, czyli konfiguracja mikrokontrolera

Zajmiemy się dziś strasznymi fusebitami, które przyprawiają o  zawrót głowy niejednego młodego elektronika. Często fusebitami straszy się, tak jak kiedyś straszone były dzieci "Czarną Wołgą". Za chwilę zobaczysz, że nie jest to takie straszne. Naturalnie, ustawiając fusebity trzeba zachować ostrożność, ale nie jest to wiedza tajemna i każdy da sobie z tym radę. Czym są owe fusebity?

 

fusebity

 

Fusebity są to rejestry pamięci FLASH, które zawierają bity konfiguracyjne mikrokontrolera, które służą do konfiguracji parametrów jego pracy. Fusebity programować możemy wyłącznie za pomocą zewnętrznego programatora w trybie szeregowym, równoległym lub wysokonapięciowym. Możliwość programowania fusebitów z pomocą poszczególnych trybów określa dokumentacja poszczególnych mikrokontrolerów, gdyż fusebity w odróżnieniu od lockbitów nie mogą być programowane w dowolnym trybie. Rejestr fusebitów składa się dwóch bajtów, czasem z trzech, które oznaczone są jako "Fuse Low Byte" - młodszy bajt, Fuse High Byte" - starszy bajt oraz "Fuse Extended Byte" - bajt rozszerzony. Wartość 0 oznacza bit zaprogramowany, natomiast wartość 1 oznacza bit niezaprogramowany. Podczas programowania fusebitów należy przestrzegać informacji zawartych w dokumentacji danego mikrokontrolera.

Poniżej krótkie omówienie poszczególnych fusebitów.

 

BODLEVEL, BODLEVEL(n)

Bity/bity ustawiające minimalny poziom napięcia zasilania, przy którym mikrokontroler pracuje prawidłowo. Gdy napięcie zasilania spadnie poniżej tego poziomu, oraz gdy bit BODEN jest zaprogramowany, mikrokontroler zostanie zresetowany przez wewnętrzny układ BOD (Brown-out Detector).

BODEN

Włączenie układu monitorowania napięcia zasilania. Jeżeli bit BODEN jest zaprogramowany układ BOD monitoruje napięcie zasilania i w momencie jego spadku poniżej określonego bitami BODLEVEL poziomu napięcia przeprowadzi procedurę resetowania mikrokontrolera. Układ BOD jest dostępny we wszystkich trybach Sleep. Powoduje to nieznaczny wzrost poboru energii. Jeżeli układ BOD nie jest konieczny w danej aplikacji powinien być wyłączony.

SUT(n)

Bity odpowiadające ustawienia czasu restartu mikrokontrolera po resecie lub włączeniu napięcia zasilania. Dla układów, gdzie napięcie zasilania narasta szybko można ustawić krótki czas restartu, natomiast w układach z wolno narastającym napięciem zasilania czas restartu powinien być wydłużony. Ustawienia bitów SUT zależą również od źródła sygnału zegarowego mikrokontrolera, aby częstotliwość oscylatora mogła się ustabilizować. W przypadku zaprogramowanego bitu BODEN nie stosuje się opóźnienia czasu restartu i  bity SUT powinny być zaprogramowane.

CKSEL(n)

Bity służące do wyboru źródła sygnału zegarowego taktującego mikrokontroler. Przy ustawianiu tych bitów należy zachować ostrożność i bezwzględnie korzystać z informacji zawartych w dokumentacji, gdyż popełniając błąd można zablokować mikrokontroler.

RSTDISBL

Bit blikujący funkcję reset. Bit ten stosowany jest w przypadku mikrokontrolerów, w których pin RESET współdzielony jest z pinem należącym do jednego z portów.

WTDON

Bit włączający blok watchdog. Watchdog taktowany jest niezależnym wewnętrznym oscylatorem i jego zadaniem jest odmierzanie określonych interwałów czasowych, po których mikrokontroler jest resetowany. Zapobiega to zawieszaniu się programu. Podczas pisania programu konieczne jest użycie w określonych miejscach, zależnie od wielkości programu, instrukcji zerującej licznik watchdog. W przypadku prawidłowej pracy mikrokontrolera instrukcja zerująca licznik watchdog zostaje wykonana i mikrokontroler pracuje nieprzerwanie, lecz w przypadku zawieszenia się programu lub wykonywania "pustej pętli" program nie napotka instrukcji zerującej licznik watchdog i mikrokontroler zostanie zresetowany przez ten układ.

SPIEN

Bit włączający interfejs SPI. Jeżeli bit nie jest zaprogramowany nie jest możiwe programowanie w gotowej aplikacji za pomocą programatorów ISP. Ustawienie bitu SPIEN nie jest możliwe poprzez interfejs SPI.

JTAGEN

Aktywacja wbudowanego interfejsu JTAG. Bit JTAGEN  umożliwia programowanie mikrokontrolera za pomocą interfejsu JTAG. Włączony Interfejs JTAG w wielu mikrokontrolerach AVR blokuje inne funkcje portów, na których jest zlokalizowany i jest przyczyną wielu frustracji początkujących elektroników. Linie interfejsu JTAG to TDI, TDO, TMS, TCK. W celu wykorzystania tych portów we własnym układzie należy pamiętać, aby wyłączyć interfejs JTAG. Ustawienie bitu JTAGEN nie jest możliwe poprzez interfejs JTAG.

CKOPT

Bit ten określa jeden z dwóch trybów pracy wzmacniacza oscylatora.  Jeżeli bit CKOPT jest niezaprogramowany amplituda wyjściowa sygnału oscylatora jest niska, zmniejszony jest pobór mocy, ograniczona jest częstotliwość pracy oscylatora. Według dokumentacji bit CKOPT może być niezaprogramowany dla oscylatorów z rezonatorami o częstotliwości do 8 MHz. Większa częstotliwość rezonatora nie gwarantuje prawidłowej pracy mikrokontrolera. Ponadto w tym trybie nie można wykorzystać sygnału z wyjścia oscylatora (XTAL2) do taktowania urządzeń zewnętrznych). W przypadku gdy bit CKOPT jest zaprogramowany wzmacniacz oscylatora pracuje w trybie "rail-to-rail", czyli amplituda sygnału wyjściowego oscylatora zawiera się praktycznie od GND do Vcc. Tryb ten można wykorzystać dla rezonatorów o częstotliwości od 1 do 16 MHz. Jest to tryb zalecany dla mikrokontrolerów pracujących w środowisku o dużych zakłóceniach. Można go także wykorzystać do taktowania innych urządzeń, W trybie "rail-to-rail" występuje zwiększony w znacznym stopniu pobór energii przez mikrokontroler. W związku z powyższym nie jest to tryb zalecany dla urządzeń z zasilaniem bateryjnym. Ponadto w przypadku używania rezonatora kwarcowego o częstotliwości 32,768 kHz przy ustawieniu bitów CKSEL3...0 na 1001, zaprogramowanie bitu CKOPT powoduje załączenie wewnętrznych kondensatorów do pinów XTAL1 i XTAL2 i masy o wartości 36 pF. Umożliwia to uproszczenie układu aplikacji i obniżenie kosztów.

EESAVE

Bit stawiający ochronę pamięci EEPROM podczas kasowania pamięci mikrokontrolera. W przypadku gdy bit EESAVE jest zaprogramowany pamięć EEPROM jest chroniona podczas kasowania pamięci FLASH.

BOOTSZ(n)

Bity określające wielkość i adres początkowy bloku pamięci przeznaczonej dla bootloadera. Utworzenie bloku bootloadera możliwe jest w mikrokontrolerach, które obsługują instrukcję SPM.

BOOTRST

Bit określający adres, do którego przejdzie mikrokontroler po sygnale reset. Gdy bit BOOTRST jest nie jest zaprogramowany po resecie mikrokontrolera program startuje od adresu 0x0000. W przypadku gdy bit BOOTRST jest zaprogramowany program rozpoczyna pracę od adresu wyznaczonego przez bity BOOTSZ(n).

DWEN

Bit włączający interfejs Debug Wire, służący do programowania i debugowania mikrokontrolera w systemie za pomocą trzech przewodów. Za pomocą Debug Wire można debugować, odczytywać bity konfiguracyjne oraz kasować pamięć mikrokontrolera. Interfejsu Debug Wire nie można wykorzystać do programowania mikrokontrolera.

CKDIV8

Bit CKDIV8, jeśli jest zaprogramowany powoduje, że częstotliwość zegara dzielona jest przez 8. Przy uruchamianiu aplikacji należy zwrócić uwagę właśnie na ten bit konfiguracyjny, gdyż może on być przyczyną problemu związanego z taktowaniem. Przykładowo, jeśli wybraliśmy częstotliwość taktowania mikrokontrolera na  8 MHz, to zaprogramowany bit CKDIV8 spowoduje, że mikrokontroler będzie w efekcie taktowany sygnałem o częstotliwości 1 MHz. Błąd tego typy jest dość powszechny i uciążliwy.

Po krótkim wstępie teoretycznym przechodzimy do wybranego mikrokontrolera, którym jest ATmega32-16PU. Aby dowiedzieć się o ustawieniach fusebitów tego mikrokontrolera zaglądamy do dokumentacji, gdzie w rozdziale "Memory Programming" znajduje się podrozdział "Fuse bits". Z opisu dowiadujemy się, że ATmega32 posiada dwa bajty konfiguracyjne, które opisane są w tabelach 104 oraz 105. W tabelach tych są podane także wartości domyślne bitów konfiguracyjnych.

Na pierwszy ogień Fuse High Byte.

 

Tabela Fuse High Byte

Rys. 1. Tabela Fuse High Byte - widok z dokumentacji

 

Widzimy, że przy bitach OCDEN, JTAGEN, SPIEN, CKOPT umieszczono odsyłacze do przypisów pod tabelą:

1. Bit SPIEN jest niedostępny w trybie programowania SPI.

2. Funkcjonalność bitu CKOPT zależy od ustawień bitów CKSEL. Zobacz szczegóły w dziale "Clock Sources" na stronie 25.

3. Domyślna wartość bitów BOOTSZ1...0  powoduje ustawienie maksymalnego rozmiaru obszaru BOOT. Zobacz tabelę 99 na stronie 255.

4. Nigdy nie należy wysyłać produkty z zaprogramowanym bitem OCDEN bez względu na ustawienia blokady i bity JTAGEN. Zaprogramowany bezpiecznik OCDEN umożliwia uruchomienie zegara we wszystkich trybach uśpienia. Może to zwiększyć zużycie energii.

5. Jeżeli interfejs JTAG nie będzie wykorzystywany, to bit JTAGEN powinien być wyłączony w celu uniknięcia statycznego prądu na linii TDO interfejsu JTAG.

 

Kolej na Fuse Low Byte.

 

Tabela Fuse Low Byte

Rys. 2. Tabela Fuse Low Byte - widok z dokumentacji

 

W tej tabeli są też odsyłacze do przypisów.

1. Domyślne wartość bitów SUT1...0 powodują maksymalny czas restartu mikrokontrolera. Szczegóły są w  tabeli 10 na stronie 30.

2. Domyślne ustawienie bitów CKSEL3...0 powodują taktowanie mikrokontrolera z wewnętrznego oscylatora RC z częstotliwością 1 MHz. Szczegóły znajdują się w tabeli 2 na stronie 25.

Przepiszmy teraz tabel w poziomie.

Tabela Fuse High Byte

NR bitu 7 6 5 4 3 2 1 0
Nazwa bitu OCDEN JTAGEN SPIEN CKOPT EESAVE BOOTSZ1 BOOTSZ0 BOOTRST
Wartość domyślna 1 0 0 1 1 0 0 1

 

Tabela Fuse Low Byte

Nr bitu 7 6 5 4 3 2 1 0
Nazwa bitu BODLEVEL BODEN SUT1 SUT0 CKSEL3 CKSEL2 CKSEL1 CKSEL0
Wartość domyślna 1 1 1 0 0 0 0 1

 

 

Rzuca się w oczy binarny zapis bajtów konfiguracyjnych. Odczytamy teraz fusebity przez avrdude z wykorzystaniem programatora USBasp, wpisując następującą komendę:

 

avrdude -p m32 -c usbasp -U lfuse:r:-:h -Ulfuse:r:-:b -U hfuse:r:-:h -U hfuse:r:-:b

 

Odczyt fusebitów przez avrdude.exe.

Rys. 3. Odczyt fusebitów przez avrdude w formacie heksadecymalnym i binarnym.

 

Po wykonaniu przez avrdude odczytu fusebitów w konsoli wypisane zostały zwrócone informacje. Widać, ze zawartość bitu lfuse w formacie heksadecymalnym wynosi 0xE1, a w formacie binarnym 0b11100001, natomiast zawartość bajtu hfuse w formacie heksadecymalnym to 0x99 oraz binarnym to 0b10011001.

Są to akurat wartości domyślne. Teraz możemy przejść do programowania fusebitów. Aby zaprogramować fusebity musimy przygotować odpowiednie dane. W tym celu określimy ustawienie każdego z bitów konfiguracyjnych.  Można to zrobić odpowiadając sobie na pytania dotyczące poszczególnych bitów.

Należy zapamiętać, że fusebity programuje się zgodnie z następującą zasadą: 0 - zaprogramowany, 1 - niezaprogramowany.

Zaczniemy od Fuse High Byte, aby określić konfigurację pracy mikrokontrolera.

Bit 0  BOOTRST - czy będziemy korzystać z bootloadera ? - Nie. Więc bit BOOTRST ustawiamy jako niezaprogramowany, czyli zapisujemy 1.

Bit 1 BOOTSZ0 oraz bit 2 BOOTSZ1 - czy będziemy korzystać z botloadera ? - Nie. Bit BOOTRST ustawiliśmy jako niezaprogramowany, więc wartość tych bitów jest dowolna, pozostawimy je bez zmian. Bit BOOTZS0 będzie miał wartość 0 oraz bit BOOTSZ1 będzie miał wartość 0.

Bit 3 EESAVE - czy pamięć eeprom ma być chroniona podczas kasowania pamięci FLASH? - Nie (ponieważ w naszej aplikacji nie będzie takiej potrzeby). Do bit EESAVE zapisujemy  wartość 1.

Bit 4 CKOPT - czy aplikacja będzie zasilana z baterii? - Nie. Zapisujemy do bitu CKOPT wartość 0. Będziemy mieli wtedy silny sygnał zegarowy. Z uwagi na to, że naszą aplikację budujemy na płytce stykowej jest to ustawienie zalecane, gdyż połączenia generują dość silne zakłócenia.

Bit 5 SPIEN - czy będziemy korzystali z interfejsu SPI? - Tak. Wartość tego bitu powinna wynosić 0.

Bit 6 JTAGEN - czy będziemy korzystali z interfejsu JTAG? - Nie Zapisujemy więc wartość 1. Uzyskamy tym samym cztery piny portu C do wykorzystania.

Bit 7 OCDEN - czy będziemy korzystali z debugera? - Nie. Do tego bitu zapisujemy wartość 1.

 

Teraz przygotujemy sobie dane dla bajtu Fuse Low Byte aby określić źródło taktowania, czas restartu oraz minimalny poziom napięcia.

Bity odpowiadające za źródło taktowania to CKSEL0, CKSEL1, CKSEL2, CKSEL3. Aby prawidłowo skonfigurować te bity zaglądamy do tabeli 4 na stronie 26 dokumentacji. Nasza aplikacja wyposażona jest w rezonator kwarcowy 16 MHz więc interesować nas będzie pozycja External Crystal/Ceramic Resonator.

 

Tabela 2 - Opcje taktowania.

Rys. 4. Tabela opcji taktowania - widok z dokumentacji.

 

Z tabeli dowiadujemy się, że ustawienia bitów CKSEL 3...0 przyjmują w zapisie binarnym wartości od 1010 do 1111. Jest to dość mało szczegółowa informacja więc musimy ja jeszcze dopracować. Zaglądamy więc do tabeli 4 na stronie 26.

 

Tabela 4 - opcje dla rezonatora kwarcowego.

Rys. 5. Tabela opcji ustawień dla oscylatora z rezonatorem kwarcowym - widok z dokumentacji.

 

 

Z tabeli 4 wyczytać możemy, że ustawienia bitów CKSEL3...1 powiązane są z ustawieniem bitu CKOPT. W naszym przypadku do bitu CKOPT zapisaliśmy wartość 0, więc bity CKSEL3...1 mogą przyjmować różne wartości. Wartość pierwsza właściwa jest dla rezonatorów kwarcowych niskiej częstotliwości (od 0,9 do 3 MHz), kolejna dla rezonatorów o średniej częstotliwości (od 3 do 8 MHz), natomiast ostatnia dla rezonatorów wysokiej częstotliwości (powyżej 8 MHz). Stąd dla bitów CKSEL3...1 przypisujemy wartość 111, gdyż podłączyliśmy kwarc o częstotliwości 16 MHz. To jeszcze za mało aby ustawić pozostałe bity CKSEL. Musimy zatem zajrzeć do tabeli 5 na stronie 27 dokumentacji.

 

Tabela 6 ustawienie czasu restartu dla rezonatora Kwarcowego.

Rys.6. Dobór czasu restartu mikrokontrolera dla wybranego rezonatora kwarcowego - widok z dokumentacji.

 

Zauważyć można, że bit CKSEL0 wraz z bitami SUT1...0 służą do wyboru czasu uruchamiania mikrokontrolera. Naszemu mikrokontrolerowi damy najdłuższy czas uruchamiania, aby mieć pewność, że napięcie zasilania oraz częstotliwość oscylatora będą ustabilizowane. Stąd wynika, że bit CKSEL0 przyjąć powinien wartość 1 a bity SUT1...0 wartość 11. Przed podsumowaniem tego bajtu konfiguracyjnego zajmijmy się jeszcze bitami BODEN i BODLEVEL. Postawmy pytanie, czy aplikacja będzie zasilana z baterii ? W naszym przypadku nie. Więc bit BODEN powinien mieć wartość 1. W takim przypadku warość bitu BODLEVEL jest nieistotna, lecz zobaczmy szczegóły dotyczące bitu BODLEVEL znajdują się w dokumentacji mikrokontrolera w tabeli 15 na stronie 37.

 

Tabela 15 - Charakterystyka sygnału RESET

Rys. 7. Tabela 15 - Charakterystyka sygnału RESET - widok z dokumentacji.

 

 

W pozycji VBOT widzimy minimalne poziomy napięć zasilania dla ustawień bitu BODLEVEL, gdzie dla wartości 1 odpowiada poziom 2,7 V a dla wartości 0, 4 V. Zwrócić uwagę należy na odsyłacz do przypisu, gdzie znajdujemy informację, że dla mikrokontrolera ATmega32L bit BODLEVEL winien mieć wartość 1, a dla mikrokontrolera ATmega32 wartość 0. Ponadto napisane jest, że BODLEVEL = 1 nie ma zastosowania dla mikrokontrolera ATmega32. Daje to nam całkowity obraz, jak ustawić bit BODLEVEL. W naszym przypadku korzystamy z mikrokontrolera ATmega32-16PU więc napięcie zasilania wynosi od 4,5 do 5,5 V. Biorąc pod uwagę powyższe informacje bit BODLEVEL powinien przyjąć wartość 0.

Podsumujmy teraz wszystkie informacje. Aby wyraźnie było widać konfigurację fusebitów wartości poszczególnych bitów wpiszemy do tabelek.

 

Tabela Fuse High Byte

NR bitu 7 6 5 4 3 2 1 0
Bazwa bitu OCDEN JTAGEN SPIEN CKOPT EESAVE BOOTSZ1 BOOTSZ0 BOOTRST
Wartość domyślna 1 1 0 0 1 0 0 1

 

Tabela Fuse Low Byte

Nr bitu 7 6 5 4 3 2 1 0
Nazwa bitu BODLEVEL BODEN SUT1 SUT0 CKSEL3 CKSEL2 CKSEL1 CKSEL0
Wartość domyślna 0 1 1 1 1 1 1

1

 

 

Wartości obu bitów zamienimy na postać heksadecymalną. Można to zrobić ręcznie lub za pomocą dowolnego kalkulatora wyposażonego w funkcje programistyczne. Bajty konfiguracyjne przedstawione w formacie heksadecymalnym mają następujące wartości:

Fuse High Byte = 0xC9

Fuse Low Byte = 0x7F

 

Można już zaprogramować fusebity. Jednak jest to nasz pierwszy raz i warto się wstrzymać na chwilę i jeszcze sprawdzić nasz wybór, aby nic nie nabroić. Jeśli używamy programatora wspieranego przez Atmel Studio 7.0 spróbujmy łatwiejszej metody, gdzie możliwość pomyłki jest ograniczona. Odczytamy fusebity w Atmel Studio 7.0.

 

Rys. 8. Odczyt fusebitów w środowisku Atmel Studio 7.0.

 

Odczytaliśmy fusebity w Atmel Studio 7.0. Są to akurat wartości domyślne. Kolejnym krokiem będzie ustawienie fusebitów zgodnie z naszymi potrzebami, które określiliśmy wyżej. Odznaczamy pozycję HIGH.JTAGEN, zaznaczamy pozycję HIGH.CKOPT, zmieniamy opcje w pozycjach LOW.BODLEVEL oraz LOW.SUT_CKSEL. Szybki rzut oka na wartości rejestrów konfiguracyjnych i porównanie z wartościami, które wyliczyliśmy sami.

 

Zmiana ustawień fusebitów W Atmel Studio 7.0.

Rys. 9. Zmiana ustawień fusebitów w Atmel Studio 7.0.

 

Widzimy wartości dla High Fuse Byte 0xC9, a dla Low Fuse Byte 0x7F. Są to te same wartości, które ustawiliśmy wybierając poszczególne opcje z dokumentacji. Możemy śmiało wcisnąć przycisk Program.  Atmel Studio 7.0 z podłączonym programatorem zgodnym z AVRISP MKII zaprogramuje fusebity mikrokontrolera. Jeżeli po wykonaniu zapisu weryfikacja rejestru fusów przebiegnie pomyślnie, oznacza to, że wszystkie fusebity ustawiliśmy prawidłowo i mikrokontroler działają poprawnie,

 

Rys. 10. Widok panelu fusebitów po wykonanym zapisie do mikrokontrolera.

 

Zróbmy to samo za pomocą avrdude.exe i programatora USBasp. Mikrokontroler jest nowy, z ustawionymi domyślnie fusebitami. Podłączamy wyjścia z programatora USBasp do odpowiednich pinów mikrokontrolera, a sam programator do wolnego portu USB. Uruchamiamy konsolę systemy Windows i przechodzimy w niej do katalogu, w którym znajduje program avrdude.exe. Następnie odczytujemy rejestry fusebitów poleceniem:

 

avrdude -p m32 -c usbasp -U lfuse:r:-:h -U hfuse:r:-:h

 

Rys. 11. Odczyt fusebitów za pomocą avrdude.exe.

 

Avrdude odczytał rejestry fusebitów widzimy wartości dla Fuse Low Byte 0xE1 oraz dla Fuse High Byte 0x99. Są to wartości domyślne dla mikrokontrolera ATmega32. Za pomocą avrdude zapiszemy w rejestrze Fuse Low Byte wartość 0x7F, a w rejestrze Fuse High Byte wartość 0xC9. Zapisu fusebitów za pomocą avrdude dokonujemy wpisując w konsoli następujące polecenie:

 

avrdude -p m32 -c usbasp -U lfuse:w:0x7F:m -U hfuse:w:0xC9:m

 

Zapis fusebitów za pomocą avrdude.exe.

Rys. 12. Zapis fusebitów za pomocą avrdude.exe.

 

Operacja zapisu fusebitów przebiegła pomyślnie.  Wszystkie ustawione przez nas wartości są prawidłowe. Tym samym przygotowaliśmy nasz mikrokontroler do aplikacji z którą poznamy tajniki programowania oraz wykonamy pierwsze projekty. Niemniej jednak zalecam ostrożność przy ustawianiu fusebitów i bezwzględne przestrzeganie zaleceń zawartych w dokumentacji. Pamiętajcie, że wszytko co robicie ze swoimi mikrokontrolerami, robicie na własne ryzyko.

Autor: Orici
Wyświetleń: 491|Komentarzy: 0|Ocena: 0|Głosów: 0