Tento příklad je vytržen z mojí konstrukce autocomputeru, který též najdete na mých stránkách. Na stránce autocomputeru je k dispozici celé schéma.
Obvod je připojen jako vnější paměť dat. Je přímo připojen na adresovou/datovou multiplexovanou sběrnici,která vystupuje
z procesoru 8051. Vstupy dat a adresy u RTC jsou spojeny, a pomocí signálu ALE je
dekódováno, zda jde o data nebo adresu.(A0+D0 obvodu RTC-> AD0 procesoru atd.)
Dále jsou připojeny signály READ a WRITE, zajišťující čtení a zápis dat z/do obvodu.
Signál CS0 aktivující čip je připojen samostatně na 1 bit brány P1 (P1.2)
Signál CS1 zamykající obvod do režimu STNBY je připojen přes rezistor na +Ucc, a tím je
snímána velikost napájení. Po zjištění, že Ucc kleslo na 1/5 své původní velikosti přechází
obvod do stavu STNBY, kdy výrazně poklesne spotřeba (až na 5 mikroampér) a obvod je nepřístupný.
Data z obvodu jsou získávána na dotaz (t.zn. pokud chceme vědět aktuální čas nebo datum, přečteme je z obvodu).
Bedlivému pozorovateli neujde zapojení vývodu INTRPT/STD na přerušení procesoru. Dioda D10 je v cestě proto,
že na stejný vstup přerušení procesoru (P3.2, INT0) je připojena ještě jedna periferie. Procesor je nastaven na
reakci na přerušení vyvolané úrovní. Pokud dojde k přerušení, procesor vygeneruje dotaz do RTC a podle
stavu flagu IRQ FLAG v registru D zjistí, zda vektor přerušení směruje od RTC. Pokud ne, obslouží druhou periferii.
Pokud ano, následuje obsluha RTC.
Obvod RTC je nastaven tak, že na výstupu INTRPT/STD jsou generovány impulsy s frekvencí 64 Hz. Pokaždé, když je generován
impuls, následuje odskok do přerušení. Tyto impulsy jsou využity pro blikání tečky na displeji po vteřinových intervalech.
(Samozřejmě, že v obsluze přerušení je softwarový čítač, který po 64 volaných přerušeních t.j. 1 sec. blikne tečkou).
A nyní již následuje popis obsluhy obvodu na fragmentech zdrojového kódu:
Adresa připojení je zvolena tak, že vždy je vysláno 0Fx Hexa. Pozice x
odpovídá registru, z něhož chceme číst nebo do něj zapisovat. Např. nastavením adresy
na 0FDH budeme pracovat s registrem D obvodu RTC, nebo nastavením 0F3H budeme pracovat
s registrem 3 tedy s registrem desítek minut atd.
CLR P1.2 ;aktivuj CS RTC .... uvede RTC do činnosti
MOV R0,#0FDH ;aktivuj RTC-viz protokol obsazeni
bytu RTC....nastavení registru D
MOV A,#00H ;zadej hodnotu pro RTC do Acc
MOVX @R0,A ;zapiš data v Acc na adresu v R0,
tedy registr D v RTC
INC R0
MOV A,#02H ;podobně jako v předchozím kroku s tím, že
po INC R0 zapisujeme do registru E
MOVX @R0,A ;hodnota 02H znamená nastavení bitu D1
do 1.....RTC bude pracovat v přerušení
INC R0
MOV A,#04H ;podobně jako v předchozím kroku s tím, že po
INC R0 zapisujeme do registru F
MOVX @R0,A ;hodnota 04H znamená nastavení bitu D2
do 1.....RTC bude pracovat v
režimu 24 hodin (t.j. 0:00:00 - 23:59:59)
SETB P1.2 ;deaktivuj CS RTC
;---------Rutina provozniho casu-------
rtc: PUSH ACC ;uloz ACC A PSW
PUSH PSW
CLR P1.2 ;aktivuj CS_RTC
MOV R0,#0FDH ;testuj vektor preruseni......nastav registr D
MOVX A,@R0 ;čti jeho hodnotu, pokud je
vektor z RTC, je nastaven bit
IRQ FLAG v RTC, po přenosu 2 bit Acc
JB ACC.2,pokr_38 ;pokud je aktivni z RTC,proved obsluznou rutinu
SETB P1.2 ;vektor neni z RTC,deaktivuj RTC a ...
LJMP prerus_01 ;...proved obsluhu vnejsiho INT0
;-------Vektor z RTC, následuje obsluha--------------
pokr_38:MOV R0,#0FDH ;nastav registr D v RTC
CLR A
MOVX @R0,A ;pošli 0 do reg. D, t.j. nuluj IRQ FLAG
(příznak přerušení)
INC R3 ;soft citac volani INT od RTC (Fint=64 Hz)
CJNE R3,#40H,out_02 ;po dosazeni poctu volani pro 1s proved rutinu
MOV R3,#0H ;nuluj citac
.
.
.
.
.
.
RETI ;navrat z INT
Další příklad ukazuje vyčtení hodin a minut z RTC a jejich přenos do proměnných hodiny a minuty,
kde je uložen v BCD formátu.Protože jednotky a desítky jsou uloženy zvlášť v registrech,
je nutno pro získání celého čísla ve tvaru BCD provést vždy nejprve načtení desítek, vynulování
(vymaskování) vyššího nibble (4 bitů v bytu) a uložení. Pak následuje čtení jednotek, maskování a
přičtení k desítkám.
;-------------Subrutina realneho casu-------
;provadi vycitani RTC
real: CLR P1.2 ;aktivace RTC
MOV R0,#0F5H ;nacti desitky hodin
MOVX A,@R0
ANL A,#0FH ;vymaskuj je
SWAP A ;prehod a zapis do byte hodiny
MOV hodiny,A
DEC R0 ;sniz adresu na jednotky hodin
MOVX A,@R0
ANL A,#0FH ;nacti je a vymaskuj
ADD A,hodiny ;a pricti k nim desitky
MOV hodiny,A ;uloz do promenne
DEC R0 ;sniz adresu na desitky minut
MOVX A,@R0 ;nacti data
ANL A,#0FH ;vymaskuj
SWAP A ;prehod a zapis do bytu minut
MOV minuty,A
DEC R0 ;sniz adresu na jednotky minut
MOVX A,@R0 ;nacti data
ANL A,#0FH ;proved vymaskovani
ADD A,minuty ;a pricti k nim desitky minut
MOV minuty,A ;uloz do promenne
SETB P1.2 ;deaktivace RTC
LJMP pokr_99
Další příklad nastiňuje uložení dat do obvodu. U dat musí být zajištěno, že budou ukládána v
odpovídajícím tvaru a hlavně v daném rozsahu pro ten který registr. Zapsat tam jde cokoliv, ale
obvod pak může špatně počítat. Data jsou uložena v proměnných uloz_4 až uloz_1.
;------------Ulozeni real time---------
;Ulozi data do hodin a minut a vynuluje vteriny
uloz_real:CLR P1.2 ;aktivace RTC
MOV R0,#0F5H ;adresa...desitky hodin
MOV A,uloz_4 ;načti data
MOVX @R0,A ;a ulož na adresu
DEC R0 ;sniz adresu na jednotky hodin
MOV A,uloz_3 ;načti data
MOVX @R0,A ;pošli na adresu v R0
DEC R0 ;sniž adresu na desítky minut
MOV A,uloz_2
MOVX @R0,A ;zapiš data
DEC R0 ;sniž adresu na jednotky minut
MOV A,uloz_1
MOVX @R0,A ;zapiš data
DEC R0 ;sniž adresu na desítky sekund
CLR A
MOVX @R0,A ;a zapiš nulu
DEC R0 ;sniž adresu na jednotky sekund
MOVX @R0,A ;a zapiš data
;spusť RTC
MOV R0,#0FDH
MOV A,#00H
MOVX @R0,A
INC R0
MOV A,#02H
MOVX @R0,A
INC R0
MOV A,#04H
MOVX @R0,A
SETB P1.2 ;deaktivuj RTC
RET
A opět vyčtení data aktuálního dne z RTC.
Nastaví se adresa desítek do R0 a přečtou se data, např. #x2H. Protože se jedná o desítky, je to číslo dvacet. Nás
ale zajímá z přečtené hodnoty jen nižší nibble (dvojka). Proto zbytek za pomoci masky #0FH a instrukce ANL
vynulujeme, takže dostaneme #02H. Jde o desítky, tak musíme obsah prohodit (swap Acc), dostaneme
#20H v Acc a toto číslo přeneseme do proměnné displeje. Pak následuje totéž s jednotkami, také se vymaskuje
neplatná část bytu a jednotky se přičtou k desítkám a výsledek je uložen. Pozor, nezapomeňte, že se jedná sice o
hexadecimální číslo, ale zde je bráno jako BCD reprezentace.
dat_den:CLR P1.2 ;aktivuj RTC
MOV R0,#0F7H ;nacti adresu desitek
MOVX A,@R0 ;nacti data desitek
ANL A,#0FH ;vymaskuj (ponecha jen dolni nibble)
SWAP A ;prehod do horniho nibble
MOV dis,A ;a uloz do promenne displeje
DEC R0 ;sniz adresu na jednotky
MOVX A,@R0 ;nacti data
ANL A,#0FH ;vymaskuj neplatnou cast
ADD A,dis ;pricti k desitkam
MOV dis,A ;a uloz do displeje
SETB P1.2 ;deaktivuj RTC
LJMP pokr_99 ;ven
Závěrečný příklad ukazuje složitější zobrazení dne v týdnu na displeji.
Čísla v "dvt_tab" tabulce pod rutinou jsou rozsvícené segmenty zobrazovače odpovídající zobrazení písmene
uvedeného pod ním na displej. V rutině, která zde není rozebrána pro její relativní
jednoduchost se podle tabulky jejíž počáteční adresa je v DPTR ("dvt_tab") čtou data, která jsou indexována
obsahem v proměnné DIS.
Načteme den z RTC, který má např. číslo 3
(jde o den středa). Protože každé označení dne má dvě písmena (Po,Út,ST ap.) je nutno číslo násobit
dvěma, jinak by se v tomto případě četlo 3. číslo z tabulky a to je reprezentace pro
písmeno "o". Číslo po vynásobení dá 6 a to je již správná pozice v tabulce. (Pozor, první pozice v tabulce
má index 0). Pak se znova načte pozice aktuálního dne v DPTR, index se zvýší o 1 a dostaneme se na pozici
druhého písmena v tabulce. Číslo pozice se přičte k Acc, v němž v vyšší části byte máme pozici prvního
písmena a na nižší pozici je po předchozím vymaskování 0. Výsledek pro den středa je #67H. V obsluze
displeje se pak na displej pošlou čísla z pozice 6 a 7, t.j. 109 a 120, která zajistí rozsvícení
odpovídajících segmentů.
;---------------Subrutina dvt=den v tydnu-zobrazi aktualni den----
;funkce:dle BCD kodu dnu (0-6) nacte z tabulky reprezentaci.
;Cislo z RTC je nutno nasobit 2 protoze kazdy den odpovida
;dvema pismenum
dvt: CLR P1.2 ;RTC aktivni
MOV DPTR,#dvt_tab ;nacti do DPTR tabulku zobrazeni dnu
MOV R0,#0FCH ;nacti do R0 adresu dnu v RTC
MOVX A,@R0 ;nacti data
ANL A,#0FH ;maskuj neplatnou cast bytu
RL A ;nasob x2
MOV R0,A ;uloz do A
SWAP A ;prehod
MOV dis,A ;a uloz do horniho nibble 1. pismeno dne
MOV A,R0 ;znovu nacti adresu 1.dne (v DPTR)
INC A ;zvys o jednu (na 2. pismeno dne)
ADD A,dis ;a pricti k displeji
MOV dis,A ;uloz
out_10: SETB P1.2
LJMP pokr_99
dvt_tab: DB 84,121,115,92,62,120,109,120,57,120,115,119,109,92,0
;reprezentace dne n E , P o , U t , S t , C t , P A , S o,prazdny znak
POZOR, tyto rutiny nejsou samostatně schopny běhu, neboť odkazují na neexistující proměnné a
jsou vytrženy z hlavního progranu. Slouží výhradně pro příklad, jak komunikovat s RTC.
|
|
© DH servis 2002 - |