![]() ![]() |
Nejjednodušší (a je to opravdu příklad, neboť málokdy budeme připojovat pouze jedno číslo) je zapojit sedmisegmentovku segmenty přímo k jednomu portu. Má to jednu velikou výhodu týkající se software, kterou Vám prozradím o kousek dál. Pokud se podíváme na obrázek, zjistíte, že jeden každý segment je připojen k jednomu bitu portu. Nyní poněkud odbočím. Pro pochopení funkce budeme uvažovat, že pro rozsvícení jednoho některého segmentu nastavíme vývod do logické úrovně H. Je to lepší pro pochopení, prostě úroveň log. H na vývodu = segment svítí. Abych Vás nezmátl, ve skutečnosti je situace poněkud komplikovanější, má to souvislost s konstrukcí výstupních budičů portu procesoru, ale o tom až později, až si osvojíte toto jednoduché připojení. Označme si jednotlivé segmenty písmeny podle abecedy a budeme pro začátek uvažovat o zobrazovací jednotce se společnou katodou. Jestliže tedy přivedeme na segment a úroveň log. H, segment se rozsvítí. A totéž platí i pro ostatní. Nyní, chceme-li rozsvítit například číslo 1, které je zde na příkladu zobrazeno, musíme nastavit do úrovně log. H segment b a c, a naopak ostatní ponechat v log. úrovni L. Tak tedy rozsvítit jednotlivé segmenty umíme, to není problém, v programu bychom pro rozsvícení znaku pro jedničku prostě napsali: ;-------------------- CLR P2.0 ;zhasne segment A SETB P2.1 ;rozsvítí segment B SETB P2.2 ;rozsvítí segment C CLR P2.3 ;zhasne segment D CLR P2.4 ;zhasne segment E CLR P2.5 ;zhasne segment F CLR P2.6 ;zhasne segment G CLR P2.7 ;zhasne segment H (des. tecka) ;--------------------ALE - jistě sami uznáte, je to možná přehledné, ale zcela jistě dlouhé (představte si takto vypisovat všechny kombinace pro číslice od 0 do 9, pro některá písmena a ještě se na ně odkazovat), zabere to zbytečně mnoho paměti a v programu nanejvýš nepraktické, a proto se takovýto přístup k ovládání kupodivu nepoužívá a ani na to tady nenajdete příklad Na jiný, troufám si říci správný (nejsem dokonalý, kdyžtak mne opravte) přístup se podíváme dál. Tahle kapitolka měla jen nastínit, jak segmentovku připojit, a jak rozsvítit jednotlivé segmenty. |
| 01010101B (binárně) |
| 0x128+1x64+0x32+1x16+0x8+1x4+0x2+1x1 |
| 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | B (binárně) | Px.7 | Px.6 | Px.5 | Px.4 | Px.3 | Px.2 | Px.1 | Px.0 | Bity portu (P0 až P3) |
| L | H | L | H | L | H | L | H | Logické úrovně |
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | Váhy bitů |
![]() | ![]() |
![]() |
![]() |
![]() |
| 2 | 3 | E | 0 | 0 s tečkou |
| 91D / 5BH | 79D / 4FH | 121D / 79H | 63D / 3FH | 191D / BFH |
Vše má těsnou souvislost s hardwarem - jedná se o konstrukci portů u procesoru typu x51 (pokud jste pozapomněli, podívejte se na stránku portů a vraťte se sem zpět). Totiž všechny porty kromě portu P0 jsou pseudoobousměrné, a ne plnohodnotné obousměrné porty. Port je schopen "stáhnout" úroveň na pinu k zemi, ale protože výstupní tranzistor pinu (je vidět na obrázcích na odkazované stránce) - opět kromě P0, má kolektor připojen k Vcc přes ošetřovací rezistor relativně velké hodnoty, není schopen, dodat vývodem výstupní proud směrem ven (řečeno laicky).
připojenou na +Vcc, a jednotlivé vývody katod připojené k pinům portu. Nyní se změní samozřejmě i hodnota zasílaná na port, a to tak, že musíme jednotlivé bity negovat, jinak by segmenty, které chceme mít zhasnuté svítili a naopak. K tomu je určena instrukce negace - CPL. Nejlépe si vše objasníme na opět velmi jednoduchém konkrétním funkčním příkladu programu.
Toto zapojení jsem kdysi dělal do jednoho soutěžního vozu, pro signalizaci zařazeného rychlostního stupně, a nyní nám poslouží jako triviální příklad. Takže opět si zapojte vše podle schématu (schéma ke stažení ve větším rozlišení naleznete na konci stránky, a taktéž jak zdrojový tak i přeložený soubor příkladu). A nyní se podíváme na vlastní zdrojový kód programu. V něm se mimo jiné naučíme použití několika dalších instrukcí, testování vstupů a také si vysvětlíme pojem podprogram (rutina, subrutina). K tomuto příkladu již nebudu malovat vývojový diagram, vše si popíšeme slovně. Než začneme, bylo by vhodné, popsat, jak program pracuje.
;********************************************************************
$MOD51
$TITLE(BYTE SIGNED MULTIPLY)
$PAGEWIDTH(132) ;HLAVICKA
$DEBUG
$OBJECT
$NOPAGING
;********************************************************************
ORG 0
MOV P1,#0FFH ;aktivace portu pro cteni vst. hodnot
MOV A,#080H
ACALL displej
smyc1: JNB P1.0,jedna ;testuj stavy mikrospinacu a pri
JNB P1.1,zpatecka ;aktivite posli cislo na displej
JNB P1.2,neutral
JNB P1.3,pet
JNB P1.4,ctyri
JNB P1.5,tri
JNB P1.6,dva
SJMP smyc1
jedna: MOV A,#6H ;reprezentave cisla 1
ACALL displej
SJMP smyc1
dva: MOV A,#05BH ;reprezentave cisla 2
ACALL displej
SJMP smyc1
tri: MOV A,#04FH ;reprezentave cisla 3
ACALL displej
SJMP smyc1
ctyri: MOV A,#66H ;reprezentave cisla 4
ACALL displej
SJMP smyc1
pet: MOV A,#06DH ;reprezentave cisla 5
ACALL displej
SJMP smyc1
neutral:MOV A,#40H ;reprezentave pomlcky
ACALL displej
SJMP smyc1
zpatecka:MOV A,#39H ;reprezentave znaku C
ACALL displej
SJMP smyc1
;********************************************************************
displej:CPL A ;provede negaci a posle ven
MOV P2,A
RET
END
;********************************************************************
|
Na začátku je jako vždy nejprve hlavička zdrojového souboru. Direktivou ORG0 nastavíme počáteční adresu programu na adresu 0. Nyní zápisem hodnoty 0FFH zapíšeme do výstupního registru portu P1 jedničky, tím jej nastavíme do vstupního režimu. Nyní vložíme do Akumulátoru (již známe z minula) hodnotu 80H. Proč ? To si za chvilku povíme. Následující instrukcí je instrukce ACALL. Tuto instrukci ještě neznáme. tak se na ni podíváme podrobněji. Tato instrukce provede volání podprogramu ležícího na adrese uvedené za touto instrukcí. V praxi to znamená, že se uloží návratová adresa do zásobníku, provede se skok na podprogram, a po jeho vykonání se instrukcí RET na konci podprogramu vyzvedne návratová adresa ze zásobníku a zavede se do programového čítače (Program counter - PC). Prostě a jednoduše instrukcí RET se vrátíme z podprogramu zpět na instrukci následující za instrukcí volání podprogramu. Pro naprosté pochopení můžeme opět sáhnout po staré dobré kuchařkové analogii. V receptu máme např. rozklepněte vejce, a vložte na pánev. Takže co uděláme ? Po přečtení rozklepněte vejce "bude zavolán podprogram" který zajistí dojít do lednice, rozklepnout vejce a uklidit skořápku. Po návratu z tohoto podprogramu se bude pokračovat dalším krokem - vložte na pánev. Protože hledání adresy, na kterou skočit je nemyslitelné, opět použijeme nám již známé návěští, kterým je libovolné slovo, pro lepší orientaci jsem zvolil slovo displej. Takže volání ACALL displej provede skok na adresu s tímto návěštím. Jestliže se podíváme na samý konec prográmku, na rutinu "displej" zjistíme, že provede následující kroky: instrukcí CPL A neguje všechny bity akumulátoru - to je nutné kvůli hardwarovému připojení displeje - aktivní jsou bity v log. L. Další instrukce (MOV P2,A) provede odeslání hodnoty na port procesoru, a v tomto okamžiku se tedy rozsvítí ty segmenty, kde je na portu log. úroveň L, naopak zůstanou zhasnuté ty, kde je log. úrpveň H. Poslední instrukcí této rutinky je RET, která zajistí návrat z tohoto podprogramu na instrukci následující za instrukci ACALL. Ptáte se, v čem je hlavní kouzlo podprogramů ? Představte si, že místo každého volání "ACALL displej" budete muset vložit obsah této rutiny. Jsou to sice jen 2 řádky, použitím podprogramu máme ušetřeno cca 7 řádek kódu, ale vezměte si např. rutinu vícebytového dělení, která má kolem 100 řádek kódu. To je již značná úspora (času, paměti, nervů, račte doplnit další ... |
| Odpovídající reprezentace | 3FH | 06H | 5BH | 4FH | 66H | 6DH | 7DH | 7H | 7FH | 6FH | 40H | 0H | 80H |
| Zobrazený znak | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - | prázdny znak | tečka |
|
| Příklady - ASM i HEX soubor a schéma v plné velikosti |
|
© DH servis 2002 - |