Mikrokontrolery AVR XMEGA w praktyce, część 9. Generator kwarcowy
W 8 części kursu zapoznaliśmy się z wbudowanymi generatorami RC, dostępnymi w mikrokontrolerach XMEGA, a w tej części zostanie przedstawiony generator kwarcowy. Generatory tego typu cechują się większą dokładnością i mają zastosowanie wszędzie tam, gdzie potrzebne jest precyzyjne odmierzanie czasu.
W tym odcinku, korzystając z modułu prototypowego X3-DIL64 z Leon Instruments, dostępnego w ofercie KAMAMI, zobaczymy, jak działa generator kwarcowy. Podczas ćwiczeń zbudujemy układ, którego schemat przedstawiono na rysunku 1 – schemat ten będzie przydatny dla wszystkich części kursu od 7 do 10. Pliki z kodami źródłowymi można pobrać na dole strony.
Rys. 1. Schemat układu demonstracyjnego
Generator kwarcowy
Sercem generatora tego typu jest rezonator kwarcowy, w skrócie zwany kwarcem. Podłączamy go do pinów R0 i R1 portu R. Są to piny ogólnego przeznaczenia i jeśli nie korzystamy z generatora kwarcowego, możemy je wykorzystać w innym celu. Oprócz kwarcu, musimy także podłączyć kondensatory o niewielkiej pojemności, widoczne na schemacie na rysunku 1, w sposób znany z mikrokontrolerów ATmega i ATtiny.
Większość producentów płytek testowych narzuca częstotliwość kwarcu, lutując go do płytki na stałe. Odlutowanie kwarcu, w szczególności SMD, może spowodować jego uszkodzenie lub oderwanie miedzianych ścieżek od laminatu. Moduł prototypowy X3-DIL64 z Leon Instruments wyposażono w podstawkę pod kwarc, dzięki czemu użytkownik może szybko i bez lutowania podłączyć taki kwarc, jaki uzna za najlepszy do swoich potrzeb. Zdjęcie podstawki przedstawiono na rysunku 2.
Rys. 2. Wymiana kwarcu w zestawie X3-DIL64 jest łatwa dzięki zastosowaniu podstawki
W mikrokontrolerach XMEGA możemy korzystać z kwarców zegarkowych 32 kHz oraz kwarców o częstotliwości od 0,4 MHz do 16 MHz. Chcąc uzyskać częstotliwość taktowania procesora większą od 16 MHz, musimy zastosować układ PLL, który zostanie omówiony później.
Konfiguracja generatora kwarcowego jest trochę bardziej skomplikowana niż generatory omawiane dotychczas, aczkolwiek nie jest to problem, z którym sobie nie poradzimy. Za generator kwarcowy odpowiedzialny jest rejestr OSC.XOSCCTRL. Zobaczmy fragment dokumentacji na rysunku 3.
Rys. 3. Fragment dokumentacji rejestru XOSCCTRL
Musimy zatem zastanowić się nad czterema parametrami. Pierwszy z nich, FRQRANGE, określa przedział wewnątrz którego musi znajdywać się częstotliwość kwarcu. X32KLPM służy do uruchamiania trybu oszczędzania energii dla kwarcu 32 kHz. XOSCPWR zwiększa prąd w obwodzie rezonatora, co w większości przypadków nie jest potrzebne. XOSCSEL wyznacza m. in. czas potrzebny do stabilizacji generatora.
W naszym przykładzie wykorzystamy kwarc o częstotliwości 16 MHz, a jego typowy czas startu wynosi 16 tys. cykli zegarowych. W takiej sytuacji wystarczy wpisać poniższą linijkę kodu, by skonfigurować generator.
OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc| // wybór kwarcu od 12 do 16 MHZ OSC_XOSCSEL_XTAL_16KCLK_gc; // czas na uruchomienie generatora
Następnie, uruchamiamy generator kwarcowy.
OSC.CTRL = OSC_XOSCEN_bm; // uruchomienie generatora kwarcowego
Powinniśmy teraz poczekać, aż generator się ustabilizuje. Jednak nie możemy czekać w pustej pętli na ustawienie się odpowiedniego bitu w rejestrze statusowym, bo jeśli generator się nie uruchomi, to procesor będzie czekał w nieskończoność. Dlatego musimy wprowadzić pętlę, która odliczy przykładowo 255 cykli i sprawdzi status 255 razy – jeśli w tym czasie generator się nie ustabilizuje, program stwierdzi brak kwarcu i będzie mógł powiadomić użytkownika o błędzie.
// czekanie na ustabilizowanie się generatora for(uint8_t i=0; i<255; i++) { if(OSC.STATUS & OSC_XOSCRDY_bm) { // sprawdzanie statusu CPU_CCP = CCP_IOREG_gc; // odblokowanie zmiany źródła sygnału zegarowego CLK.CTRL = CLK_SCLKSEL_XOSC_gc; // wybór źródła sygnału zegarowego na XTAL 16MHz LcdClear(); // czyszczenie wyświetlacza Lcd("XTAL"); // komunikat o uruchomieniu generatora // układ nadzorujący kwarc CPU_CCP = CCP_IOREG_gc; // odblokowanie modyfikacji ważnych rejestrów OSC.XOSCFAIL = OSC_XOSCFDEN_bm; // włączenie układu detekcji błędu sygnału zegarowego return; // wyjście z funkcji jeśli generator się uruchomił } _delay_us(10); } // komunikat w przypadku braku uruchomienia generatora kwarcowego LcdClear(); Lcd("Brak XTAL");
Mikrokontrolery XMEGA wyposażono w szereg rozwiązań zwiększających bezpieczeństwo i stabilność pracy. Jednym z nich jest układ nadzorujący pracę generatora kwarcowego. Jeśli z jakiegokolwiek powodu zostanie wykryta nieprawidłowość w pracy generatora, układ zgłosi przerwanie niemaskowalne OSC_OSCF_vect i samoczynnie przełączy źródło sygnału na wbudowany generator RC 2 MHz. Tradycyjne procesory ATtiny i ATmega w takiej sytuacji się zawieszały i nie były w stanie nic zrobić, a w skrajnych przypadkach bez sygnału zegarowego nie mogły nawet nawiązać połączenia z programatorem.
Zanim zostanie uruchomiony układ detekcji błędu generatora kwarcowego, musimy wpisać wartość CCP_IOREG_gc do rejestru CPU_CCP, aby zezwolić na modyfikację rejestrów kluczowych dla funkcjonowania procesora. Następnie, do rejestru XOSCFAIL wpisujemy wartość OSC_XOSCFDEN_bm i układ detekcji zostanie uruchomiony. Trzeba zaznaczyć, że tego układu nie można wyłączyć bez zresetowania procesora.
// układ nadzorujący kwarc CPU_CCP = CCP_IOREG_gc; // odblokowanie modyfikacji ważnych rejestrów OSC.XOSCFAIL = OSC_XOSCFDEN_bm; // włączenie układu detekcji błędu sygnału zegarowego
W razie stwierdzenia usterki generatora, zostanie wygenerowane przerwanie OSC_OSCF_vect, a generator RC 2 MHz włączy się automatycznie.
ISR(OSC_OSCF_vect) { OSC.XOSCFAIL |= OSC_XOSCFDIF_bm; // kasowanie flagi przerwania LcdClear(); Lcd("Awaria!"); }
Dystrybutorem zestawu X3-DIL64 jest KAMAMI.pl. |
Dominik Leon Bieczyński