3. Systém hodin

Hodiny jsou hnacím motorem každého mikrokontroléru. ATtiny3217 lze taktovat několika možnými zdroji. Lze využít vnitřní oscilátor nebo můžeme použít vnější zdroj hodin. Vnitřní oscilátor může být 16 MHz, 20 MHz nebo 32 768 Hz. Jako externí zdroj můžeme použít krystalový oscilátor 32 768 Hz připojený na vývody TOSC2 (RB2) a TOSC1 (RB3) nebo jiný externí zdroj 32 768 Hz, který je připojen na TOSC1. Další externí zdroj hodin lze pak připojit na vývod EXTCLK (PA3). Systémové hodiny lze též vyvést z mikrokontroléru na výstupní pin CLKOUT (PB5). Grafické vyjádření systému hodin je na níže uvedeném obrázku.

clock
Obrázek 7. Clock systém

Výchozím zdrojem hodin, který je nastaven z výroby, je interní oscilátor 20 MHz s předděličkou 6, tedy přibližně 3,3 MHz. Výběr interního oscilátoru 16 nebo 20 MHz je možný naprogramováním pojistek (Fuses), o kterých se dozvíme více v některé z dalších kapitol. Výběr ostatních zdrojů lze provést pomocí registru MCLKCTRLA.

3.1. Předdělička hlavních hodin

Taktovací kmitočet CPU a periferií lze upravit (zmenšit) pomocí předděličky. Toto nastavení provedeme pomocí čtveřice bitů PDIV[3:0] v registru MCLKCTRLB. Dělicí poměr lze nastavit na 2, 4, 6, 8, 10, 12, 16, 24, 32, 48, 64.

preddelicka
Obrázek 8. Předdělička hlavních hodin

Možná vás napadá otázka, proč dělit (snižovat) kmitočet mikrokontroléru? Většinou chceme, aby byl program co nejrychlejší, tak proč ho úmyslně zpomalovat? Důvodů může být více, ale jedním z nich je spotřeba. Se zvyšováním frekvence spotřeba roste. Podívejte se na následující tabulku jak. Pokud si říkáte, že vás pár miliampér nevytrhne, tak věřte, že u mobilních zařízení, která jsou napájena z baterie, se hodí každá miliampéra. Taktéž platí, že čím vyšší proud, tím vyšší teplota a problémy spojené s tím. Vždy tedy zvažte, zda je potřeba "hnát" CPU mikrokontroléru na maximální rychlost.

Tabulka 2. Spotřeba v závislosti na frekvenci (napájení 5 V)
Frekvence Spotřeba

20 MHz

10,0 mA

10 MHZ

5,3 mA

5 MHz

3,0 mA

32,768 kHz

19,2 µA

3.2. Registry pro Clock System

Zápis do všech registrů pro nastavení hodin, kromě registru MCLKSTATUS, je chráněn proti neúmyslné změně (Configuration Change Protection - CCP). Chceme-li do těchto registrů zapisovat, musíme tento krok nejprve potvrdit vložením klíče IOREG (0xD8) do registru CCP. Tím zpřístupníme registry na čtyři instrukční cykly. Zápis do registru proto musí následovat bezprostředně po vložení klíče.
/* Zápis do chráněných registrů */
CPU_CCP = CCP_IOREG_gc;       // Odemčení chráněných registrů (na 4 instrukční cykly)
CLKCTRL.MCLKCTRLB = 0x00;     // Zápis do chráněného registru

Struktura CLKCTRL

Přístup k registrům pro správu hodin je možný pomocí struktury CLKCTRL. Deklarace této struktury je uvedena níže.

/* Clock controller */
typedef struct CLKCTRL_struct
{
    register8_t MCLKCTRLA;      /* MCLK Control A */
    register8_t MCLKCTRLB;      /* MCLK Control B */
    register8_t MCLKLOCK;       /* MCLK Lock */
    register8_t MCLKSTATUS;     /* MCLK Status */
    register8_t reserved_1[12];
    register8_t OSC20MCTRLA;    /* OSC20M Control A */
    register8_t OSC20MCALIBA;   /* OSC20M Calibration A */
    register8_t OSC20MCALIBB;   /* OSC20M Calibration B */
    register8_t reserved_2[5];
    register8_t OSC32KCTRLA;    /* OSC32K Control A */
    register8_t reserved_3[3];
    register8_t XOSC32KCTRLA;   /* XOSC32K Control A */
    register8_t reserved_4[3];
} CLKCTRL_t;

Registr MCLKCTRLA - Main Clock Control A

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

CLKOUT

CLKSEL1

CLKSEL0

R/W - 0

R/W - 0

R/W - 0

Tabulka 3. Význam jednotlivých bitů registru MCLKCTRLA
bit Symbol Význam bitu Popis

b7

CLKOUT

Hodiny na výstupu CLKOUT

0:  zakázáno;
1:  povoleno;

b1 až b0

CLKSEL[1:0]

Výběr zdroje hodin

00:  interní oscilátor 16/20 MHz;
01:  interní oscilátor 36.768 kHz;
10:  externí oscilátor 32.768 kHz;
11:  externí zdroj hodin na pinu PA3;

Registr MCLKCTRLB - Main Clock Control B

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

PDIV3

PDIV2

PDIV1

PDIV0

PEN

R/W - 1

R/W - 0

R/W - 0

R/W - 0

R/W - 1

Tabulka 4. Význam jednotlivých bitů registru MCLKCTRLB
bit Symbol Význam bitu Popis

b4 až b1

PDIV[3:0]

Dělicí faktor předděličky

0000:  f/2;
0001:  f/4;
0010:  f/8;
0011:  f/16;
0100:  f/32;
0101:  f/64;
1000:  f/6;
1001:  f/10;
1010:  f/12;
1011:  f/24;
1100:  f/48;

b0

PEN

Povolení předděličky

0:  předdělička zakázána; dělicí faktor = 1;
1:  předdělička povolena; dělicí faktor = PDIV;

Registr MCLKLOCK - Main Clock Lock

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

LOCKEN

R/W - x

Tabulka 5. Význam jednotlivých bitů registru MCLKLOCK
bit Symbol Význam bitu Popis

b0

LOCKEN

Uzamčení konfiguračních registrů

0:  žádný efekt;
1:  uzamkne registry MCLKCTRLA a MCLKCTRLB; odemčení je možné pouze hardwarovým resetem; hodnota tohoto bitu po resetu závisí na nastavení pojistek FUSE.OSCCFG;

Registr MCLKSTATUS - Main Clock Status

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

EXTS

XOSC32KS

OSC32KS

OSC20MS

SOSC

R - 0

R - 0

R - 0

R - 0

R - 0

Tabulka 6. Význam jednotlivých bitů registru MCLKSTATUS
bit Symbol Význam bitu Popis

b7

EXTS

Status externích hodin

0:   externí hodiny neběží;
1:   externí hodiny běží;

b6

XOSC32KS

Status externích hodin 32 kHz

0:   nestabilní;
1:   stabilní;

b5

OSC32KS

Status interního osc. 32 kHz

0:   nestabilní;
1:   stabilní;

b4

OSC20MS

Status interního osc. 20 MHz

0:   nestabilní;
1:   stabilní;

b0

SOSC

Změna zdroje hodin

0:   zdroj hodin není měněn;
1:   probíhá změna zdroje hlavních hodin;

Registr OSC20MCTRLA - 16/20 MHz Oscillator Control A

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

RUNSTDBY

R/W - 0

Tabulka 7. Význam jednotlivých bitů registru OSC20MCTRLA
bit Symbol Význam bitu Popis

b1

RUNSTDBY

Vynucení oscilátoru ve Standby módu

1:   oscilátor 16/20 MHz poběží ve všech módech, a to i když není využíván systémem;

Registr OSC20MCALIBA - 16/20 MHz Oscillator Calibration A

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

CAL20M5

CAL20M4

CAL20M3

CAL20M2

CAL20M1

CAL20M0

R/W - x

R/W - x

R/W - x

R/W - x

R/W - x

R/W - x

Tabulka 8. Význam jednotlivých bitů registru OSC20MCALIBA
bit Symbol Význam bitu Popis

b5 až b0

CAL20M[5:0]

Kalibrace oscilátoru 16/20 MHz

hodnota po resetu závisí na FUSE.OSCCFG

Registr OSC20MCALIBB - 16/20 MHz Oscillator Calibration B

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

LOCK

TEMPCAL20M3

TEMPCAL20M2

TEMPCAL20M1

TEMPCAL20M0

R/W - x

R/W - x

R/W - x

R/W - x

R/W - x

Tabulka 9. Význam jednotlivých bitů registru OSC20MCALIBB
bit Symbol Význam bitu Popis

b7

LOCK

Uzamčení kalibračních registrů

0:  žádný efekt;
1:   uzamkne registry OSC20MCALIBA, OSC20MCALIBB; hodnota po resetu závisí na FUSE.OSCCFG;

b5 až b0

CAL20M[5:0]

Teplotní kalibrace oscilátoru 16/20 MHz

hodnota po resetu závisí na FUSE.OSCCFG;

Registr OSC32KCTRLA - 32.768 kHz Oscillator Control A

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

RUNSTDBY

R/W - 0

Tabulka 10. Význam jednotlivých bitů registru OSC32KCTRLA
bit Symbol Význam bitu Popis

b1

RUNSTDBY

Vynucení oscilátoru ve Standby módu

1:   oscilátor 32 kHz poběží ve všech módech, a to i když není využíván systémem;

Registr XOSC32KCTRLA - 32.768 kHz Crystal Oscillator Control A

Detail

bit_7

bit_6

bit_5

bit_4

bit_3

bit_2

bit_1

bit_0

CSUT1

CSUT0

SEL

RUNSTDBY

ENABLE

R/W - 0

R/W - 0

R/W - 0

R/W - 0

R/W - 0

Tabulka 11. Význam jednotlivých bitů registru XOSC32KCTRLA
bit Symbol Význam bitu Popis

b5 až b4

CSUT[1:0]

Čas náběhu ext. osc. 32 kHz

00:   1k cyklů;
01:   16k cyklů;
10:   32k cyklů;
11:   64k cyklů;

b2

SEL

Výběr zdroje hodin

0:   externí krystal;
1:   externí hodiny na vývodu TOSC1;

b1

RUNSTDBY

Vynucení oscilátoru ve Standby módu

1:   externí krastalový oscilátor 32 kHz poběží ve všech módech, a to i když není využíván systémem;

b0

ENABLE

Povolení vstupu

1:   změní konfiguraci vývodů na TOSC1 a TOSC2; bity SEL a CSUT lze pouze číst;

3.3. Příklad: Nastavení hodin

Pro ověření práce s nastavením hodin vytvoříme jednoduchý prográmek, na kterém vyzkoušíme nastavení zdroje hodin, předděličky a dostupnost hlavních hodin na výstupu mikrokontroléru. Schéma zapojení je uvedeno níže. Využijeme tlačítko, které je na desce Curiosity, a je připojeno na vývod PB7. Pomocí tohoto tlačítka budeme měnit dělicí faktor předděličky. Výstupní signál budeme pozorovat na pinu CLKOUT (PB5).

schema
Obrázek 9. Schéma zapojení

Program je velice jednoduchý. Nastavíme PB5 jako výstup, dále je potřeba nastavit pull-up na PB7 (tlačítko při stisku přivádí na vstup log. nulu). Jako zdroj hlavních hodin je nastaven interní oscilátor 32,768 kHz a je povolen výstup CLKOUT. Poté v nekonečné smyčce kontrolujeme, zda bylo tlačítko stisknuto. Pokud ano, je nastavena předdělička na f/64 a po jeho uvolnění je nastavena zpět na výchozí hodnotu f/6.

#include <avr/io.h>

int main(void) {
    PORTB.DIRSET = PIN5_bm;                     //PORTB5 výstup
    PORTB.PIN7CTRL |= PORT_PULLUPEN_bm;         //pull-up pro tlačítko
    CPU_CCP = CCP_IOREG_gc;                     //povolit zápis do MCLKCTRLA
    CLKCTRL.MCLKCTRLA = 0b10000001;             //32 kHz/6, CLKOUT povoleno
    while (1) {
        if(!(PORTB.IN & PIN7_bm)) {             //tlačítko stisknuto
            CPU_CCP = CCP_IOREG_gc;             //povolit zápis do MCLKCTRLB
            CLKCTRL.MCLKCTRLB = 0b00001011;     //předdělička f/64
            while(!(PORTB.IN & PIN7_bm)){};     //čeká na uvolnění tlačítka
            CPU_CCP = CCP_IOREG_gc;             //povolit zápis do MCLKCTRLB
            CLKCTRL.MCLKCTRLB = 0b00010001;     //předdělička f/6
        }
    }
}

Na obrázcích vidíte signály na tlačítku a výstupu CLKOUT. Z průběhů je zřejmé, jak dlouho trvá přepnutí dělicího faktoru.

prubehy down
Obrázek 10. Časové průběhy při stisku tlačítka
prubehy up
Obrázek 11. Časové průběhy při uvolnění tlačítka

Na závěr je třeba říci, že změna frekvence hodin nebo zdroje hodin v průběhu provádění programu není až tak častá činnost. Zpravidla se zdroj hodin nastaví při startu programu a více se s tímto nastavením nemanipuluje. V příštím díle se podíváme na ovládání vstupů a výstupů mikrokontroléru, což je asi nejčastější činnost při programování.