SEMESTRÁLNÍ  PRÁCE  Z UPS 

ZADÁNÍ Č. 5:

VYHODNOCENÍ POČTU PRŮJEZDŮ AUTOMOBILŮ 
V KAŽDÉM SMĚRU

Autor:		Martin Hudlička
Datum odevzdání:	25. 4. 2000

1.	Zadání

Vyhodnocujte počet průjezdů automobilů v každém směru. Tento počet zobrazte na světelných diodách v binárním kódu (hodnota se zobrazí, jakmile se rozsvítí v daném směru červená). Při počtu aut větších než 15 se bude počítat znovu od nuly. Průjezd auta je simulován tlačítkem pro chodce.
Semafory pro chodce ani světlo pro odbočení doprava není ovládáno.

2.	Rozbor úlohy

Pokud má být vyhodnocován počet průjezdů automobilů v každém směru křižovatky, musí být povolen průjezd aut vždy jen v jednom směru. Zelená barva se proto na semaforu střídá cyklicky S, V, J, Z. Během doby, kdy svítí v daném směru zelená barva, je možno simulovat průjezd automobilů stisknutím tlačítka pro chodce. Poté, co v daném směru naskočí červená, se na LED diodách zobrazí v binárním formátu počet aut, která v daném směru projela a tento počet svítí na diodách tak dlouho, dokud se v následujícím průjezdném směru nezmění barva semaforu na červenou. Na začátku programu proto na LED diodách nesvítí nic (tedy vlastně čtyři nuly). 
Semafory pro chodce nejsou ovládána. Stejně tak nejsou ovládána světla pro odbočení doprava, jelikož by se tím ztížilo vyhodnocování počtu projetých aut. Muselo by se testovat několik tlačítek najednou. Další variantou by bylo rozsvícení zelené ve dvou protichůdných směrech najednou. I zde by se musela testovat dvě tlačítka najednou a projetá auta se buď sčítat, nebo např. v jednom směru přičítat, ve druhém odčítat. 

3.	Popis algoritmu a vývojový diagram

Program je koncipován jako nekonečná smyčka, která obíhá stále dokola. Po startu programu se inicializují registry AX, SI pro další použití. Na semafor pro auta, semafor pro chodce i světelné diody se nejprve vyšle kombinace samých nul, tzn. všechna světla zhasnuta. Tento krok se provádí z důvodu vynulování neočekávané náhodné hodnoty ve vnitřních registrech přípravku, tedy aby se po spuštění programu v prvním kroku neobjevovaly chaotické kombinace rozsvícených světel. 
Poté jsou do AX postupně vkládány binární kombinace odpovídající jednotlivým stavům na křižovatce. Po vyslání celého slova z tabulky na výstupní port je volána čekací rutina. Nejprve je však třeba rozhodnout o počtu průchodů touto čekací smyčkou. K tomu slouží tabulka PRODLEVY, ze které program čte hodnoty podle toho, jaká je aktuální hodnota SI. Konečným důsledkem je, že červená (popř. zelená) barva svítí na semaforu 6x déle, než žlutá. To se přibližuje realitě na běžné křižovatce. V čekací rutině jsou zároveň testována tlačítka signalizující průjezd automobilu, o kterých se zmíním později. Po návratu z čekací rutiny jsou vyslána data pro zobrazení počtu projetých automobilů na LED diodách. 
Algoritmus pro testování tlačítek v čekací rutině je navržen poměrně komplikovaně a dle mého soudu by šel při troše snahy zjednodušit. Při testování počtu stisků tlačítka jsem se neustále potýkal s problémem, jak zajistit pouze jeden stisk tlačítka, i když je tlačítko stisknuto déle. Program totiž probíhá velice rychle ve srovnání s dobou stisknutí tlačítka. Pokud je počet průchodů čekací smyčkou 600 (svítí zelená barva), má program možnost 600x otestovat stav tlačítek. Bohužel při jednom stisku projde program touto rutinou mnohokrát a dává nesmyslné výsledky. Zlepšení nepřinesl ani pokus umístit krátkou čekací rutinu za každý test stavu tlačítek (za současného zkrácení počtu průchodů hlavní čekací rutinou). Zde byl problém zase opačný – program měl jen ve velmi krátkých časových okamžicích možnost otestovat stav tlačítek a poté byl nečinný. Postup, který jsem nakonec použil vychází z toho, že mezi dvěma stisky tlačítka musí nastat stav, kdy je z výstupního portu čtena hodnota “žádné tlačítko nestisknuto”. Proto je hned v prvním průchodu smyčkou testována hodnota z výstupního portu na 077h, tedy nestisknuto nic. V pozitivním případě se do registru BH (který jinde v programu nepoužívám) zapíše hodnota 1. Při dalším průchodu smyčkou se např. načte z výstupního portu 03Fh, tedy stisknuto tlačítko Z. Otestuje se, zda je v BH hodnota 1 a v kladném případě se může do BL přičíst jedno projeté auto. Pokud je v BH hodnota 0, znamená to, že hodnota 03Fh byla na výstupu i v předchozím cyklu a jedná se tedy o tentýž stisk tlačítka, který by se započítal několikrát. V případě BH = 1 je navíc testováno, zda je tlačítko stisknuto právě v okamžiku, kdy je v daném směru zelená pro automobily. Jinak by se přičítaly i stisky tlačítek ze směrů, kde zrovna nesvítí zelená. Dále je porovnávána hodnota registru BL s 15 a při počtu větším se registr vynuluje, což má za následek, že po projetí 15 aut se počítá znovu od nuly.
Rutina pro vyslání kombinace na LED diody pracuje s hodnotou registru BL, která se mění během průchodu rutinou čtení stavu tlačítek. Hodnota BL je rotována tak dlouho, dokud nejsou vyslány všechny 4 binární hodnoty.
Všechny tři rutiny pro vysílání dat na výstupní port – semafory pro automobily, semafory pro chodce a indikační LED diody – pracují v podstatě stejným způsobem. Hodnota vstupního registru je rotována a vysílán je pouze jeden bit. U každého bitu se musí vyslat ještě hodinový puls zabezpečující synchronizaci s vnitřními obvody přípravku. Tyto tři rutiny se od sebe liší pouze velikostí používaného registru a adresou výstupního portu.

Vývojový diagram je přiložen na zvláštním listě.

4.	Závěr

Algoritmus je implementován nejjednodušším možným způsobem vyhovujícím zadání. Neovládají se např. světla pro chodce ani světla pro odbočení doprava. V principu by to samozřejmě šlo, ale např. při ovládání světel pro odbočení doprava by muselo být umožněno čtení hodnot ze dvou tlačítek současně, protože z jedné silnice by se auto mohlo vydat dvěma směry. Další možnou variantou řešení by bylo např. povolení průjezdu aut vždy v celém jednom směru, tedy zprůjezdnit směry S-J nebo V-Z. Pak by se počet projetých aut vyhodnocoval tak, že ve směru S by se do registru čísla přičítala, ve směru J naopak odčítala. Dvě auta, která by projela v navzájem opačných směrech by tedy přičetla a zase odečetla 1.
Jediným větším problémem v implementaci je přílišná rychlost provádění instrukcí, takže pokud držíme tlačítko trochu déle, načte se do registru číslo větší, než kolikrát jsme ve skutečnosti stiskli tlačítko. Řešení je popsáno v implementaci algoritmu. 
Jedinou věcí, kterou se program liší od zadání je to, že se počet projetých aut nezobrazuje při změně barvy semaforu na červenou, ale krátce zasvítí v okamžiku, kdy naskočí žlutá a při červené diody opět zhasnou. Tento požadavek jsem nedokázal ani po dlouhém zkoušení uspokojivě vyřešit.