Kurs XMEGA: sygnały zegarowe (07)

|

Kurs XMEGA
W mikrokontrolerach ATmega i ATtiny układ dystrybucji sygnałów zegarowych był tak prosty, że wręcz aż prymitywny. W szczególności w procesorach starej generacji, takich jak ATmega8, mogliśmy wybrać źródło sygnału zegarowego przy pomocy fusebitów i podczas pracy procesora w żaden sposób nie można było go zmienić. Ponadto, błędne ustawienie fusebitów mogło prowadzić do zablokowania procesora. Najwyższy czas, by porzucić poczciwą ósemkę i przejść na mikrokontrolery nowej generacji!

Elementy elektroniczne, zestawy prototypowe, Arduino

W XMEGA układ zegarowy jest zdecydowanie bardziej rozbudowany. Mamy do dyspozycji różne źródła sygnału zegarowego, takie jak wbudowany generator szybki 32 MHz, energooszczędny 32 kHz oraz normalny 2 MHz, który uruchamia się zawsze po włączeniu zasilania. Możemy te częstotliwości podzielić preskalerem lub pomnożyć wbudowanym układem PLL. Oprócz tego, możemy oczywiście podłączyć różne kwarce, a w razie uszkodzenia kwarcu, procesor samoczynnie przełączy się na wbudowany generator. Mało tego – podczas pracy możemy zmieniać nie tylko częstotliwość zegara, ale również źródło sygnału. Różne peryferia mogą być taktowane różnymi zegarami, a niektóre z nich mogą pracować nawet z częstotliwością 128 MHz!
Pliki do pobrania:
Uproszczony schemat układu dystrybucji sygnałów zegarowych przedstawiono na rysunku poniżej. Po wybraniu jednego z pięciu dostępnych źródeł, mamy do dyspozycji aż trzy preskalery, umożliwiające taktowanie poszczególnych peryferiów mikrokontrolera różnymi zegarami. CLKCPU to zegar dla rdzenia procesora i może mieć maksymalnie 32MHz. CLKPER taktuje większość peryferiów. CLKPER2 i CLKPER4 służą do taktowania peryferiów zdolnych do pracy z zegarem szybszym od CLKCPU. Oprócz tego, mamy jeszcze osobne zegary dla RTC i USB, jeśli mikrokontroler jest wyposażony w te peryferia.



Sposób wyboru źródła sygnału zegarowego sprowadza się do trzech punktów:
  • Konfiguracja i uruchomienie generatora
  • Oczekiwanie na stabilizację generatora
  • Przełączenie źródła

W tej części kursu napiszemy kilka funkcji, umożliwiających przełączenie źródła sygnału taktującego oraz obserwację efektów tej zmiany przy pomocy migającej diody i wyświetlacza LCD ze sterownikiem HD44780. Wykorzystamy wewnętrzny generator RC 2 MHz, 32 MHz, a także zewnętrzny generator kwarcowy i układ PLL.



Zacznijmy od przeanalizowania funkcji main().
 
#define F_CPU 62000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "hd44780.h"

int main(void) {
    
    // zmienna
    uint8_t pll         =    4;
    
    // diody
    PORTE.DIR           =    PIN0_bm;             // dioda LED
                    
    // przyciski
    PORTA.DIRCLR        =    PIN0_bm;             // przycisk - RC 2MHz
    PORTA.PIN0CTRL      =    PORT_OPC_PULLUP_gc;  // podciągnięcie do zasilania
    PORTE.DIRCLR        =    PIN5_bm;             // przycisk FLIP - RC 32MHz
    PORTE.PIN5CTRL      =    PORT_OPC_PULLUP_gc;  // podciągnięcie do zasilania
    PORTE.DIRCLR        =    PIN6_bm;             // przycisk - XTAL
    PORTE.PIN6CTRL      =    PORT_OPC_PULLUP_gc;  // podciągnięcie do zasilania
    PORTF.DIRCLR        =    PIN4_bm;             // przycisk - PLL
    PORTF.PIN4CTRL      =    PORT_OPC_PULLUP_gc;  // podciągnięcie do zasilania
    
    // wyświetlacz LCD
    LcdInit();
    
    // komunikat o źródłe sygnału zegarowego
    LcdClear();
    Lcd("RC 2MHz");
    
    // włączenie przerwań
    sei();
    
    while(1) {
        PORTE.OUTTGL    =    PIN0_bm;
        _delay_ms(50);
        
        if(!(PORTA.IN & PIN0_bm)) Osc2MHz();
        if(!(PORTE.IN & PIN5_bm)) Osc32MHz();
        if(!(PORTE.IN & PIN6_bm)) OscXtal();
        if(!(PORTF.IN & PIN4_bm)) {    
            pll++;                                // zwiększ zmienną pll
            if(pll > 31) pll = 1;                 // jeśli pll większe od 31 to ustaw na 1
            OscPLL(pll);                          // funkcja konfigurująca PLL
        }
    }
}
 
Zwróćmy uwagę na funkcję opóźniającą _delay_ms(50); Co w niej jest nie tak? Funkcja powoduje, że procesor kręci się w pustej pętli nic nie robiąc, aż upłynie żądany czas. Jednak funkcja _delay_ms() oblicza ilość potrzebnych cykli na podstawie definicji #define F_CPU 62000000UL. W przypadku kiedy częstotliwość taktowania się zmienia, to pamiętajmy, że standardowe funkcje opóźniające nie uwzględniają aktualnej częstotliwości, w związku z czym odmierzony czas nie będzie prawidłowy. Zaobserwujemy ten problem w naszym programie testowym – dioda podłączona do E0 będzie mrugać z różną częstotliwością, mimo że w pętli głównej jest _delay_ms(50) ze stałym argumentem równym 50.

Ściągnij poniższe pliki źródłowe – będziemy używać biblioteki do obsługi wyświetlacza autorstwa Radosława Kwietnia, którą opisałem w 5 części kursu (wyświetlacz LCD w XMEGA). W kolejnych odcinkach przedstawię, jak działają poszczególne generatory i jak skonfigurować ich rejestry kontrolne.
Pliki do pobrania:
Kurs XMEGA:Moduły prototypowe:

9 komentarze :

stack overflow pisze...

Mam pytanie. Z racji faktu, iż xmega może się "sama" poprzez program przetaktowywać, jakim procesorem najlepiej zastąpić atmegę644p do projektu przenośnego zegarka zasilanego z akumulatora litowo-polmerowego, gdzie prawie wszystkie piny są zajęte? Oraz kwestia wspominanego gdzieś bootloader-a - normalnie planowałbym loader na USB do atmegi, gdzie konsekwencją jest ciągła praca na 12MHz, co przy zasilaniu akumulatorowym jak na zegarek jest bez sensu - co potrzeba, by móc z tego "wbudowanego" dobrodziejstwa do programowania xmegi korzystać?
Pozdrawiam. :)

Dominik Leon Bieczyński pisze...

Nic nie potrzeba, włączasz i działa :) Układ USB ma własny zegar CLKUSB, którym się taktuje. Zegar procesora możesz ustawić dowolny i dowolne jest źródło sygnału. Zero ograniczeń!

Anonimowy pisze...

Witam
Mam pytanie jak jest ze stabilnością i dokładnością wewnętrznych generatorów? Albo jestem ślepy albo nie mogę coś tego znaleźć. Pozdrawiam

Anonimowy pisze...

Witam,
Po uruchomieniu przykładu na Eclipse Luna, nie są wyświetlane wszystkie komunikaty na LCD oprócz pierwszego 32MHz i PLL 2 MHz , czy może po uruchomieniu nowego zegara RC należy robić InitLcd ?

Dominik Leon Bieczyński pisze...

To, że w Eclipse coś nie działa, jakoś mnie nie dziwi. Na problemy z Eclipse jest jedno rozwiązanie - Panel Sterowania - Odinstaluj programy. Następnie należy zainstalować najnowszą wersję Atmel Studio, opublikowaną na stronie firmy Atmel. Oryginalne oprogramowanie jest DARMOWE i nie ma ŻADNYCH OGRANICZEŃ. Po co wyważać otwarte drzwi?

Anonimowy pisze...

Witam. Przy kompilowaniu w atmel studio wywala mi błąd przy Osc2MHz() , Osc32MHz(), OscXtal() oraz OscPLL(pll). Gdzie leży problem?

Dominik Leon Bieczyński pisze...

Skopiuj cały kod, a nie tylko funkcję main(). Nad spisem treści jest link do całego kodu.

Anonimowy pisze...

Mógłbym prosić o podpowiedź dot. miejsca, gdzie można znaleźć informacje dot. zarządzania zegarem (np. o strukturze OSC, procedurze zmiany źródła taktowania itp.). Przeglądam dokumentacje, ale wszysto opisane jest dosyć ogólnie... Dzięki za odpowiedź!

Dominik Leon Bieczyński pisze...

W dokumentacji Atmela wszystko jest napisane :)

Prześlij komentarz

Skomentuj!

Sklep Leon Instruments