[PIC programování] – 11. díl

Vítám vás u dalšího dílu ze série PIC programování!

Dnes se naučíme číst analogové vstupy a trochu upravíme zobrazovací rutinu pro 7-segmentový displej.

Analogový vstup

Analogový vstup je v našem případě vstup, na kterém může, vůči zemi, objevit napětí 0V až 5V. Tuto hodnotu pak můžeme číst jako n-bitové číslo. Abychom toto číslo získali, použijeme tzv. AD převodník (Analog to Digital, ADCAnalog to Digital Converter). Naše PICka je vybavena 10-bitovým AD převodníkem. To znamená, že hodnotu na našem analogovém vstupu umíme “rozkouskovat” do hodnot 0 – 1023. Náš převodník má tedy rozlišení zhruba 4,882 mV (5 / 1024 V). Hodnota 0 pro napětí 0V a hodnota 1023 pro napětí 5V.

Nastavení převodníku je velmi jednoduché a zahrnuje výběr referencí pro nulové a kladné napětí, výběr časování, výběr analogového vstupu, zapnutí/vypnutí AD převodníku a pár dalších věcí, které ale dnes nevyužijeme.

Než se pustíme do nastavování AD převodníku, budeme muset trochu upravit zapojení našich 7-segmentových displejů, protože v aktuálním zapojení nemáme k dispozici žádný analogový vstup.

Zde je nové schéma, jako analogový vstup použijeme 10kΩ trimr.

Pozn.: Displej 2 byl přesunut na pin C5. Pin A4 nyní používáme jako analogový vstup.

U dílu 10 měl kolega petrnik v komentářích několik dobrých připomínek, podle kterých jsem zavedl pár změn v kódu. Pojďme se na ně podívat.

Náš mikrokontrolér PIC16F1705 má k dispozici na adresách 0x70 až 0x7F tzv. Common RAM. Stejně jako banky je toto specialitou architektury PIC. Common RAM se od zbytku paměti RAM (až na některé speciální registry) liší tím, že je dostupná z jakékoliv banky, tím odpadá potřeba přepínat na správnou banku. Tyto registry se velmi hodí pro univerzální proměnné do podprogramů, kde mohou být využity pro pomocné výpočty, tím se dá poměrně krásně zefektivnit náš program. Náš pomocný registr R_POM tedy přesuneme do Common RAM na adresu 0x70.

Druhá změna je u několika příkazů typu (addwf, andwf, lsrf, …), tedy příkazů, kde se nějak operuje s daty v libovolném registru f. U těchto příkazů jsme doposud specifikovali pouze první operand (registr f). Druhý operand za nás automaticky doplnil kompilátor. Nyní začneme psát i druhý operand, který říká, zda se má výsledek uložit do registru W nebo f. Důvod je jednoduchý. Nyní náš kompilátor automaticky doplňuje volbu ukládání do registru f. Mohlo by se ale v budoucnu stát, že se toto výchozí nastavení změní. Tím by náš program při nové kompilaci nefungoval správně. Druhý operand může u těchto instrukcí nabývat hodnot 0 nebo 1. Naštěstí v zahrnutém includu (“p16f1705.inc”) máme nadefinované zástupné symboly W a F, takže si nemusíme pamatovat, zda 0 / 1 je pro W nebo F a opačně. Pokud např. napíšeme “andwf R_POM,F“, máme jistotu, že se výsledek vždy uloží do registru R_POM, nezávisle na nastavení kompilátoru.

R_POM přejmenujeme na RC_POM. Písmeno C v prefixu názvu nám bude napovídat, že jde o registr v Common RAM.

Po uvedených změnách, vypadá náš upravený podprogram pro nastavení registrů LATx takto:

Upravená definice RC_POM vypadá samozřejmě takto:

Pozn.: V případě instrukce “lsrf WREG,F” je samozřejmě použití druhého operandu zbytečné, protože se výsledek tak jako tak uloží do registru W. Nicméně pro udržení nějaké konzistence kódu jej zde ponechávám.

Pojďme se nyní zaměřit na nastavení AD převodníku. K jeho úplnému nastavení nám postačí pouze dva registry – ADCON0 a ADCON1. Začneme registrem ADCON0, zde je jeho struktura:

Bity CHS<4:0> (ADCON0<6:2>) připojíme AD převodník k určitému analogovému vstupu. Náš analogový vstup na pinu A4 je podle datasheetu (na straně 5) označen také jako AN3. Zde je tabulka výběru připojeného vstupu:

Z této tabulky je patrné, že hodnota CHS pro nás bude b’00011′. Dále je zde bit GO/DONE, kterým později aktivujeme převod analogové hodnoty na digitální, zatím jej ponecháme v nule. Posledním bitem, ADON, aktivujeme/deaktivujeme celý AD převodník. Ten můžeme nechat po dobu celého programu zapnutý, počáteční hodnota tedy bude 1.

Pokračujeme registrem ADCON1:

Výsledek převodu analogové na digitální hodnotu je 10-bitový. Ukládá se do dvou registrů – ADRESH a ADRESL. Bitem ADFM určujeme, zda bude výsledek zarovnán doprava nebo doleva. Zde je výstižný obrázek z datasheetu:

Protože spodní dva bity výsledku zanedbáme (tedy použijeme pouze horních 8 bitů), zvolíme zarovnání doleva (ADFM = 0). Výsledek pak budeme brát jen z registru ADRESH. Pomocí bitů volíme časování AD převodníku. Časování nevolíme náhodně, ale podle frekvence oscilátoru a vhodného časování podle následující tabulky z datasheetu:

My jsme frekvenci oscilátoru (Fosc) nastavili na 4 MHz. Z následující tabulky se pro nás jako vhodná hodnota časování AD převodníku jeví Fosc/8 (šedá pole značí nevhodná časování). Alternativně bychom mohli použít časování Fosc/4 a Fosc/16. Převod podle tabulky pak bude pro Fosc/8 na frekvenci 4 MHz trvat 2 μs. ADCS tedy zvolíme b’001′. ADNREF a ADPREF bity určují reference pro kladné a nulové napětí. Tyto hodnoty ponecháme výchozí (0), tím jsou VDD a VSS, tedy 5V a GND.

Celé nastavení AD převodníku v kódu vypadá následovně:

Zbývá nám tedy už jen vyřešit samotný převod analogové hodnoty do digitální podoby. Kód je velmi jednoduchý. Poté, co připojíme analogový vstup k AD převodníku, nastavíme bit ADCON0<1> (bit GO/DONE) na hodnotu 1. Po dokončení převodu AD převodník tento bit shodí do 0. Stačí nám tedy tento bit dokola testovat a jakmile skočí do 0, víme, že převod skončil, a můžeme výslednou hodnotu z registru ADRESH zobrazit na displeji. Kód vypadá následovně:

Tento kód vykonáváme každou půl sekundu a to z jednoho prostého důvodu. Kdybychom hodnotu na 7-segmentovém displeji (a to platí obecně) měnili příliš často, hodnota by kvůli (v tomto případě nežádoucí) persistenci vidění přestala být čitelná.

A takto vypadá celý program:

Na závěr bych jen chtěl dodat, že veškeré podrobné informace k AD převodníku najdete v datasheetu na straně 218 a pro jistotu ještě jednou uvedu odkaz:

http://ww1.microchip.com/downloads/en/DeviceDoc/40001729C.pdf.

A to je pro tento díl vše!

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.