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

Vítám vás u dalšího dílu PIC programování.

V tomto díle se podíváme na to, jak zobrazit číslici na 7-segmentovém displeji, abychom v pozdějších dílech mohli zobrazit data přijatá na sériových sběrnicích.

Nejprve uvedu schéma zapojení a vysvětlím, jak 7-segmentový displej funguje a jak jej budeme řídit. Pokud již toto znáte, můžete následující část článku přeskočit.

Zde je schéma zapojení:

Pojďme se nyní zaměřit na samotný displej. Jeho vnitřní schéma vypadá takto:

Na obrázku vlevo můžete vidět, kam jsou jednotlivé vývody displeje zapojeny do PIC mikrokontroléru (dále jen MCU – Microcontroller Unit). Displej se skládá z osmi LEDek, kde sedm z nich rozsvěcí sedm segmentů číslice a jedna rozsvěcí tečku. Všechny LEDky mají společnou anodu, tzn. pokud vývody A0-A2, C0-C4 připojíme ke groundu (LATxy = 0), budou dané segmenty svítit.

A to je celá magie…

Abychom mohli rozumně zobrazovat čísla např. z pracovního registru (WREG) v assembleru, musíme si nejprve udělat podprogram, který nám číslo převede na segmenty.

Řekněme, že máme číslo 5. Pak rozsvícené segmenty budou a, c, d, f, g (případně tečka – dp). To odpovídá bitům LATA<2>, LATC<1>, LATC<3>, LATA<1>, LATA<0>, případně LATC<2>, na MCU.

To odpovídá těmto hodnotám registrů LATx:

LATA = b’?????000′
LATC = b’???10×01′

kde ? je libovolná hodnota (tyto piny na MCU nepoužíváme), x je volitelná hodnota pro tečku.

Všimněme si, že celkový počet námi použitých bitů je 8. Toho můžeme využít a ukládat celé nastavení předchozích dvou LATx registrů do jednoho registru. Tedy náš podprogram bude jako vstup přijímat číslo od 0 – 15 (to je jedna číslice v hexadecimální soustavě) a jako výstup poskytne jeden registr s nastavením registrů LATx.

Formát tohoto výstupu bude následující: Bity LATA<0:2> budeme ukládat ve spodních třech bitech, bity LATC<0:4> budeme ukládat v horních pěti bitech. Tedy výstup bude vypadat takto: C4:C3:C2:C1:C0:A2:A1:A0.

Pro všechny možnosti budeme muset sestavit tabulku:

<Vstup>: <Výstup>
0x0: b’00100001
0x1: b’11100111
0x2: b’00110010
0x3: b’10100010
0x4: b’11100100
0x5: b’10101000
0x6: b’00101000
0x7: b’11100011
0x8: b’00100000
0x9: b’10100000
0xa: b’01100000
0xb: b’00101100
0xc: b’00111001
0xd: b’00100110
0xe: b’00111000
0xf: b’01111000

Pozn.: V tabulce výše je tečka vždy zhasnutá.

Pro takovéto tabulky máme v assembleru šikovný nástroj. Příkaz brw je skoková instrukce, která načte hodnotu pracovního registru (WREG) a skočí o stejný počet instrukcí dopředu.

tedy pokud WREG = 0x04, pak se po zavolání brw přeskočí následující čtyři instrukce a provede se až pátá.

Ukázka:
(WREG = 0x02)

MCU přečte hodnotu WREG, a provede instrukci bcf LATC,0. Pokračuje prováděním instrukce bsf LATC,0

V minulém díle jsme použili instrukci “return” pro návrat z podprogramu. Dnes použijeme “retlw …”, což je obdoba return s tím rozdílem, že vracíme konstantu v registru W (dosadíme za …).

Tedy místo, abychom psali např.

napíšeme pouze

V naší rutině musíme zajistit, aby program neskočil o neošetřený počet instrukcí. Pokud bychom měli jen 4 možnosti a v registru W bylo číslo 5, mohli bychom se dostat do potíží. Z tohoto důvodu použijeme logickou operaci AND (často označována symbolem &), abychom odřízli nežádoucí bity. Pro 4 možnosti musíme aplikovat WREG & b’11’.

Pro jistotu uvedu, jak logická operace AND (nebo také logický součin) funguje. AND přijímá dva vstupní bity a vrací jeden.

Zde je pravdivostní tabulka:
0, 0 -> 0
0, 1 -> 0
1, 0 -> 0
1, 1 -> 1

Pokud se podíváte pozorně, zjistíte, že se opravdu jedná o součin. Pro vícebitová čísla platí stejná pravidla, operace se provede bit po bitu. V našem případě tedy “b’xxxxxxxx’ & b’11′” vrátí hodnotu b’000000xx’. Ta je dvoubitová, takže může nabývat hodnot 0 – 3.

V assembleru pro operaci AND máme instrukce andwf (provede AND mezi registry W a f) a andlw (provede AND mezi registem W a konstantou).

Náš assemblerovský podprogram pro segmenty bude vypadat takto:

Instrukcí retlw se MCU vrátí z podprogramu k provádění předchozího kódu a tím se zabrání v provádění dalších nežádoucích instrukcí. Pokud bychom měli např. jen 13 možností a masku 0x0F, pak bychom na zbylá 3 místa vložili instrukci nop. S tímto případem se možná v následujících dílech setkáme.

Dále budeme potřebovat podprogram, který převezme výsledek předchozího podprogramu a podle něj nastaví registry LATA a LATC. Nejjednodušší způsob je vzít první tři bity z výsledku a přesunout je do LATA, poté vzít posledních 5 bitů z výsledku a přesunout je do LATC. K tomu budeme potřebovat logický bitový posun.

Logický bitový posun může být doprava nebo doleva. Než abych se pouštěl do slovního vysvětlování, vypůjčím si obrázek z anglické wikipedie (https://en.wikipedia.org/wiki/Bitwise_operation):

A stejně pro jistotu popíšu…
Všechny bity se posunou doleva/doprava a krajní bit vlevo/vpravo zanikne, zatímco protější krajní bit vpravo/vlevo je doplněn nulou.

Příklad.:

Na konstantu b’10010100′ použijeme operaci levý logický posun. Výsledek bude b’00101000′. Tato operace je ekvivalntní operaci násobení dvěma a vychází z matematiky dvojkové soustavy. Pokud bychom udělali “levý číslicový posun” v desítkové soustavě (přidání nuly napravo), byla by tato operace ekvivalentní operaci násobení deseti. Pro pravý bitový posun platí obdobně, že je ekvivalentní operaci dělení dvěma.

Assembler nám poskytuje operace lslf (Logical Shift Left f) a lsrf (Logical Shift Right f).

Náš podprogram udělá následující kroky:

Přijme hodnotu z registru W. Tuto hodnotu si uloží do pomocného registru. Aplikuje operaci WREG & b’111′ a výsledek přesune do registru LATA. Poté načte původní hodnotu z pomocného registru do W a aplikuje tři pravé bitové posuny. Výsledek je přesunut do registru LATC.

A zde je zdrojový kód:

Nyní, když máme vše potřebné k zobrazování číslic na displeji, můžeme přistoupit k hlavnímu programu. V něm vytvoříme čítač. Hodnotu tohoto čítače proženeme oběma rutinami a následně čítač inkrementujeme. Náš displej by měl počítat od 0 do F (v šestnáctkové soustavě) stále dokola.

A tady je celý zdrojový kód:

A to je pro dnešek vše.

Napsat komentář

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