Projekt: Stopky na čtyřmístném 7-segmentovém displeji

Když se s časovačema a přerušením naučíš pracovat, tak Ti to ušetří do budoucna obrovské množství práce. Například právě zobrazení na multiplexovaném 7-segmentovém displeji většinou řeším právě přes časovač a přerušení. Ve vlastním programu pak jenom zapisuju hodnoty do RAM a nestarám se o to, kdy se má která část zobrazit. Když to pak zkombinuju s OCR registrem a AD převodníkem na kterém je fotoodpor, tak mám k dispozici dokonce i třeba řízení jasu těch 7-segmentovek.

Principiálně to udělám takto :

Hlavní program

Inicializace -

    Spustit AD převodník do freerunning režimu (tzn., že provádí převod pořád dokola) se zarovnáním doleva a pak číst jen horních 8 bitů - ten se použije ke snímání okolního světla a následné regulaci jasu displeje. Ve dne pak displej svítí více a je tak dobře vidět, za tmy pak displej sníží jas a nezáří do okolí jako reflektor. Používám to ve většině zařízení, kde používám LED 7-segmentové zobrazovače, podsvícení displejů, LED jako kontrolky apod.
    Do RAM nastavit "výchozí hodnoty" pro displej
    Pokud už je alespoň jeden AD převod hotový, načíst hodnotu AD převodníku
    Časovač :
              Povolit přeručení TOV a OCR
              Nastavit OCR = do OCR uložit hodnotu z AD převodníku
              Nastavit časovač = spustit časovač s takovým prescalerem, aby vycházel refresh celého displeje alespoň na 80Hz (kvůli blikání).
Příklad : MCU běží na IntRC 8 MHz, mám 4-místný 7-segmentový displej.
8000000(rychlost mcu)/256(rozlišení časovače)/4(počet míst displeje)/prescaler<80 =>
8000000(rychlost mcu)/256(rozlišení časovače)/4(počet míst displeje)/80(požadovaný refresh)>prescaler =>
8000000/256/4/80=97,65625 =>
Prescaler časovače vyberu tak, aby byl menší, než 97,65625 - tedy 64.
Refresh pak mám 8000000/256/4/64=122 Hz

Plus samozřejmě další inicializace, kterou bude vyžadovat program

    Povolit přerušení

Tady už bude hlavní smyčka programu

V hlavní smyčce programu pak jenom vypočítám, co na který pozici má být - v případě 7-segmentového displeje dělám rovnou “překlad” na hodnotu posílanou na port - a uložím na svá místa v RAM. O vlastní zobrazení se starají přerušení od časovače.

Podprogramy pro přerušení

Přerušení TOV :
    Vyberu hodnotu pro další znak
    Na port pošlu hodnotu
    Vyberu a zapnu správnou anodu/katodu
    Přečtu hodnotu z AD převodníku
    Uložím ji do OCR
    Konec

Přerušení OCR :
    Vypnu všechny anody/katody
    Konec

Pokud nebudu komplikovat situaci s AD převodníkem a řízením jasu displeje, pak z inicializace vynecháš nastavení AD převodníku, OCR a povolení přerušení pro OCR.

Podprogram pro přerušení vypadal nějak takto

Přerušení TOV :
    Vypnu všechny anody/katody
    Vyberu hodnotu pro další znak
    Na port pošlu hodnotu
    Vyberu a zapnu správnou anodu/katodu
    Konec

Ve Tvém případě pro stopky bych nastavil časovač do asynchronního režimu s krystalem 32768 Hz a přerušení by vypadalo nějak takhle :

Přerušení TOV:
    Pokud jsou spuštěny stopky, přičíst 1/128 sekundy
    konec

Vlastní program by vypadal takto :

Inicializace -
    Nastavit časovač do asynchronního režimu s prescalerem 1 - perioda pak vychází 32768(frekvence krystalu)/256(rozlišení časovače)/1(prescaler)=128 Hz (počet přerušení za sekundu)

Hlavní smyčka -
    Zpracování tlačítek a spuštění/zastavení/nulování stopek.

Na první pohled to možná vypadá složitě, ale jakmile se s přerušeníma a časovačema naučíš pracovat, tak Ti to následné ušetří spoustu práce a výrazně to zjednoduší programování. Hlavně odpadne “starost” s tím, co se volá pravidelně a co může v podstatě běžet autonomně “na pozadí” vlastního programu…

Neber to, prosím, jako nějaké vytahování se apod. Každý začátek je těžký a všichni jsme si tím prošli. Zkus to vzít jako inspiraci a náznak možností, které Ti použití časovačů, přerušení a vůbec splupráce s integrovanými periferiemi přímo v mcu přináší. Pro začátek si zkus třeba jenom blikání LEDkou pomocí přerušení, vyzkoušej si co a jak.

K multiplexovanému 7-segmentovému LED displeji : Spousta začátečníků dělá tu chybu, že při přepínání znaků přepne segmentovku a pak změní data pro segmenty nebo opačně nejdřív změní data pro segmenty a pak přepne segmentovku. Pak do segmentovky “prosvítá” znak z vedlejší číslice. Vtip je právě v tom, že musíš nejdřív segmentovku zhasnout (vypnout společnou anodu/katodu), pak změnit data pro segmenty a pak teprve segmentovku rozsvítit (zapnout společnou anodu/katodu) - prostě přepnutí společnou anody/katody udělat ve dvou krocích. Druhá varianta je zhasnout segmenty (poslat “zhasnuté” segmenty), přepnout společnou anodu/katodu a pak teprve vyslat vlastní znak.

Ale to už jsem se nějak moc rozepsal, tak držím palce a přeju spoustu objevů při bádání.