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.

Vytisknout stránku

Zpátky Zpátky
© DH servis 2002 -