Třetí část pokračování stránek o základech programování. V tomto pokračování si povíme o multiplexu pro sedmisegmentové zobrazovače, co to je, a jak jej programově vytvořit. Zároveň se naučíme několik dalších pojmů a instrukcí procesoru na bázi 8051.

     Při pohledu na obrázek z minulé stránky (vlevo) Vás jistě napadlo - "hmm, hezké, ale jedna cifra, to tedy není žádný zázrak". Není. Pro zobrazení více čísel potřebujeme samozřejmě více číslicovek. A tu se dostáváme k problému, jak je připojit k procesoru. Pokud budeme mít čtyři zobrazovací jednotky, každou se sedmi segmenty a tečkou, budeme potřebovat pro obsluhu všech segmentů 4x8=32 vstupně/výstupních linek procesoru. A to je velmi mnoho, na vstup například klávesnice, nebo UARTu (sériové komunikace po RS232, bude rozebráno někdy jindy), případně jiných signálů ať vstupních nebo výstupních nám již nezbyl vůbec žádný pin. Řešení je několik. Jedním z nich je například použití expandéru (viz jiná stránka tohoto webu), kterým si rozšíříme jednu bránu procesoru na více bitů (vodičů, drátů...). Hezké, funkční, ale pro menší aplikace zbytečně složité, co se týká hardware a později návrhu plošného spoje, větší spotřeba a jiné "neřesti". Samozřejmě expandéry mají své nezastupitelné místo, nelze je hned zatracovat.
     Ale protože já osobně jsem líný, a co můžu udělat softwarově taky tak prostě udělám, ukážeme si druhé, jednodušší řešení. Mimo jiné, ne každý má po ruce šuplík s expandéry.
     Tedy řešení, které si ukážeme se jmenuje multiplex. Znamená to přepínání. Ve své podstatě toto řešení využívá stejného principu, jako televizní přenos, a tím je jak já s oblibou říkám "princip oblbnutí lidského oka". Pro příklad si vezměme schéma dalším obrázku. Připojených součástek dole na levé straně procesoru si všímat nebudeme, ty již byste měli znát a vědět k čemu jsou (kontrolní otázka, zkuste si zodpovědět, jinak odpověď je zde.) Princip multiplexu tkví v tom (pokud to již znáte, můžete přeskočit), že se rychle po sobě rozsvicují jednotlivé zobrazovače, a na každém se rozsvicuje požadované číslo. V podstatě v jednom časovém okamžiku svítí VŽDY jen a pouze jedno číslo. Protože se ale přepínání čísel velmi rychle střídá, člověk díky setrvačnosti svého oka vnímá displej tak, jako by svítila všechna čísla najednou.
     Nejjednodušší bude, pokud si to vysvětlíme na příkladu. Podle schématu je čtyřmístný displej zapojen tak, že katody stejných segmentů všech číslicovek jsou spojeny (A s A, B s B ...atd.) a přivedeny na jeden port procesoru. Anody jednotlivých číslovek jsou řízeny přes spínací tranzistory, každé číslo zvlášť.
     Tímto uspořádáním dostaneme ve výsledku to, že pokud například kombinací dat (pinů) na portu A, kam máme připojeny katody bychom rozsvítili třeba číslo 3, pak postupným spínáním jednotlivých tranzistorů (resp. anod číslicovek) budeme toto číslo schopni rozsvicovat postupně na segmentovkách (sepneme T1, svítí 1. zobrazovač, sepneme T2, svítí druhý atd. až po čtvrtý zobrazovač)

Jak to pracuje
Pokud například chci mít na displeji zobrazený "nápis" davi, procesor musí zabezpečit následující činnost: Zhasne všechny znaky (tedy rozepne všechny tranzistory). Následně vyšle na port A kombinaci bitů, odpovídající písmenu "d". Displej stále nesvítí, tranzistory rozepnuty. Nyní sepneme tranzistor T1. V tomto okamžiku se nám rozsvítí na první číslicovce znak "d". Po určité době tranzistor rozepneme, tím číslo zhasne. Načteme znak požadovaný k zobrazení na druhém displeji, písmeno "A", a sepneme tranzistor T2 - svítí znak "A" na druhé segmentovce. Opět po časové pauze tranzistor rozepneme, znak zhasne. A zase načteme znak požadovaný na třetím displeji, sepneme třetí tranzistor atd. Po zobrazení posledního čtvrtého znaku začínáme opět od začátku, případně si můžeme opět díky setrvačnosti oka dovolit menší pauzu po zobrazení celého displeje. V této pauze a pauzách mezi rozsvicováním jednotlivých znaků máme spoustu času na výpočty (spoustu rozuměno pro procesor, 10 msec. je cca 8000 jednobytových instrukcí při taktování 12MHz). Protože se toto střídání jednotlivých displejů velmi rychle mění (velmi rychle pro oko), díky setrvačnosti my vidíme svítit celý displej najednou. Pokud Vás zarazí velmi nízká hodnota rezistorů na portu (22R), pak je to proto, že segmenty pracující v dynamickém impulsním režimu musí pro dosažení stejného jasu jako u statického režimu "dostávat" podstatně větší proudové impulsy. Segmentům to neublíží, pokud sepnutí netrvá dlouho a je opravdu impulsní. Při ladění programu doporučuji hodnotu poněkud zvětšit, při případném "zakousnutí" a trvalém svitu se segmenty neničí. Tak, tohle byla teoretická a relativně jednoduchá příprava, a dál se podíváme na to, jak to všechno zabezpečit programově.

Abych nezapomněl - něco pro šťouraly - tato rutina zobrazování se nejlépe používá v přerušení, kdy se o časování nemusíme starat (na rozdíl při umístění v hlavní smyčce programu), ale protože přerušení zatím ještě neumíme, nebudeme tuto možnost zatím řešit.



Programové vybavení
Software pro obsluhu multiplexu pro čtyři čísla s vyčítáním reprezentací zobrazovaných dat z tabulky nepřímým adresováním je poměrně složité pro začátečníky (nerozumíte té větě ? - vidíte, mám zatím pravdu, ale to napravíme, na konci stránky budete vědět, co přesně "ta nesmyslná věta" znamená.) Proto se pro pochopení principu multiplexu budeme ze začátku zabývat jednodušším příkladem. Tento příklad na čtyřmístný displej vypíše slovo"dAvI". Samozřejmě písmena jsou daná možnostmi sedmisegmentovek (takže malé v, je zobrazeno jako u, ale to je daň číslicovek, samozřejmě pro znakové zobrazovače by byla situace jiná).

$MOD52
$TITLE(BYTE SIGNED MULTIPLY)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING


org 00
AJMP start			;cold START

;**********************************************
;obsazeni portu PORT 1 jsou katody / 8 vyvodu
;PORT 3 - cast jsou anody

anoda_0_dis_1	bit P3.0
anoda_1_dis_1	bit P3.4
anoda_2_dis_1	bit P3.5
anoda_3_dis_1	bit P3.7
;**********************************************
;          H L A V N I   S M Y C K A
;**********************************************
cseg at 50h
start:
	LCALL zhasni			;volej podprogram (rutinu) s nazvem "zhasni"  
	JMP	logo			;skok na rutinu logo
;-------------------------------------------------
;zhasne cislo/pro zjednoduseni se zhasinaji vsechny najednou (i "zhasnute")
zhasni:		SETB anoda_0_dis_1	;nastav bit do H = vypni 1.tranzistor 
		SETB anoda_1_dis_1	;vypni 2. tranzistor
		SETB anoda_2_dis_1	;vypni 3. tranzistor
		SETB anoda_3_dis_1	;vypni 4. tranzistor	
		RET			;navrat z podprogramu

;-----vypise na displej logo DAVI--------
logo:		MOV A,#94D		;uloz reprezentaci pismena do Acc
		LCALL na_port		;negace cisla kvuli aktivni log. L
		CLR anoda_0_dis_1	;sepni prvni anodu - sviti "d"
		LCALL pausa		;pausa behem ktere sviti "d"
		LCALL zhasni		;zhasneme "d" (pro jednoduchost se vypne vse)
		MOV A,#119D		;uloz reprezentaci pismena do Acc
		LCALL na_port		;proved negaci cisla kvuli
		CLR anoda_1_dis_1	;sepni druhou anodu - sviti "A"
		LCALL pausa		;atd. atd. atd.
		LCALL zhasni
		MOV A,#28D
		LCALL na_port
		CLR anoda_2_dis_1
		LCALL pausa
		LCALL zhasni
		MOV A,#6D
		LCALL na_port
		CLR anoda_3_dis_1
		LCALL pausa
		LCALL zhasni
		JMP logo		;a zpet na zacatek
		
;--------------------------------------
na_port:	CPL A			;neguje cislo v Acc kvuli aktivni urovni L
		MOV P1,A		;vysle na port
		RET			;navrat
;--------------------------------------
pausa:    mov R3,#246			;cekaci smycka
on3:      mov R2,#162
on2:      mov R1,#1
on1:      djnz R1,on1
          djnz R2,on2
          djnz R3,on3
          Ret
END
Nejprve si probereme kód postupně řádek po řádce, pak si jej můžete vyzkoušet v praxi.
Takže po nám známé hlavičce následuje deklarace pinů. Proměnné kromě registrů s daným pojmenováním (R1 až R3) nepoužíváme žádné, pouze si pro zjednodušení přiřadíme výstupním pinům ovládajícím spínací tranzistory jednotlivých segmentovek názvy vhodné pro nás. Zvolil jsem název anoda_0_dis_1 pro první segmentovku až anoda_3_dis_1 pro čtvrtou číslicovku. Jako obvykle, je jedno, co si tam napíšete, ale musíte si to pamatovat.
Program začíná vždy na adrese 0, pokud si nenastavíte jinak. V tomto programu je na adrese 0 proveden odskok na adresu 50H (návěští START) pomocí instrukce AJMP START. Je to proto, aby bylo možno (ne zde a ne tedˇ) někdy v budoucnu použít skoky dle vektorů přerušení (tohle zatím neberte moc vážně).
Za návěštím START začíná vlastní jednoduchý program. Hlavní smyčka se skládá z volání dvou podprogramů. První s názvem ZHASNI zajistí uzavření všech PNP tranzistorů (nastaví jim na bázi log. H), řídících anody segmentovek, t.zn. zhasnutí všech číslicovek. Po provedení následuje návrat z rutiny. Pokračujeme další rutinou (LOGO), zajišťující rozsvícení "nápisu".
V rutině logo nejprve uložíme do akumulátoru hodnotu, která reprezentuje rozsvícené segmenty (tohle už by Vam mělo být jasné, pokud ne, vraťte se zpátky). Následně je zavolaná rutina na_port, která zajistí invertování jednotlivých bitů čísla v akumulátoru (proč ? - tohle už by také mělo být jasné z této stránky). Po inverzi je hodnota odeslána na port P1. Následuje návrat z rutiny. Další instrukcí (CLR anoda_0_dis_1) nastavíme na bázi prvního tranzistoru log. L a tím jej sepneme - na první číslicovce se rozsvítí znak "d". Pokračujeme voláním rutiny PAUSA, která zajistí časové zpoždění (pokud máte zájem o detailní popis, klikněte zde.)
Po odčasování rutinou PAUSA pokračuje program zhasnutím svítící segmentovky (pro jednoduchost se nastavují do log. H všechny výstupy). A následuje načtení znaku, který bude rozsvícen na druhé segmentovce. Opět se provede negace a opět rozsvícení segmentovky, tentokrát druhé. A takto se postupuje až do čtvrté segmentovky. A protože náš program nic jiného za úkol nemá, vrátí se po dokončení zpět na začátek skokem (instrukce JMP logo) a začne vypisováním znaků znova. Tímto postupným a pro oko rychlým střídáním znaků vzniká pro člověka (vlivem setrvačnosti oka) dojem, že svítí celý displej najednou.

U multiplexu je nezbytné si uvědomit, že nemůžeme někde zastavit a stát, protože by prostě zůstalo svítit jedno číslo a zbytek displeje by zhasnul a na to je třeba vždy pamatovat.


     Výše uvedený prográmek jsem schválně udělal sve dvou verzích s různou časovou smyčkou. První časová smyčka (ve výše uvedeném příkladu s názvem v archivu multi1.asm) je delší a slouží k tomu, abyste viděli, jak se jednotlivé znaky na displeji po sobě zobrazují. Po správném zapojení a naprogramování procesoru byste měli na displeji vidět zhruba tento obrázek :


     Druhý příklad (multi2.asm) má smyčku podstatně kratší a po uložení programu do procesoru a spuštění již byste měli vidět celý "nápis" vypadající asi takto:


     A třetí příklad s názvem multi3.asm je pro ty, co si chtějí pobádat jak a co v multiplexu pracuje, je již poněkud složitější, doporučuji si předem spustit příklad, a teprve pak bádat .



Ke stažení jsou tyto soubory:


Velikost 28 kByte  Příklady - ASM i HEX soubor a schéma


Jsme zase o něco dál. Slíbené taje nepřímého (indirect) adresování jsem nechal na příště, protože nechci psát kapitoly zbytečně dlouhé a tím čtenáře případně odradit (a taky po pravdě nemám tolik času). Chcete-li, můžete pokračovat další stránkou popisující přerušení.


Vytisknout stránku

Zpátky Zpátky
© DH servis 2002 -