Hodiny reálneho času

Je to jenom návrh co použít, nikomu nic nenutím. Určitě se dá najít spousta obvodů, ale mě se DS1302 zamlouvá hlavně kvůli možnosti nastavení proudu pro nabíjení záložní baterie. Hodně oblíbený je taky PCF8583.

;*****************************************************************
;
;			Podprogramy pro komunikaci s DS1302
;
;*****************************************************************

;**************************************************
; SET_TIME - zapsat čas
; INPUT:
;**************************************************
SET_TIME
	MOVLW	B'10111110'	; zapíše do W hodnotu BEh
	MOVWF	TIME_TX		; přesun z W do registru TIME_TX
	BSF		RST			; do log 1 nastaví pin RST
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
;TIME_WRITE_8
	MOVLW	TIME_TX_ADD	; 
	MOVWF	FSR			;
	MOVLW	D'8'		; do W zapíš dek. 8
	MOVWF	COUNT2		; přesun do registru COUNT2
TW1						; návěstí pro smyčku
	MOVF	INDF,W		; 
	MOVWF	TIME_TX		;
	CALL	TIME_WRITE_1;
	INCF	FSR,F		;
	DECFSZ	COUNT2,F	;
	GOTO	TW1			;
	BCF		RST			;
  RETURN

;***********************************************
; GET_TIME - přečíst čas
; INPUT:NONE
; OUTPUT:
;***********************************************
GET_TIME
	MOVLW	B'10111111'	; zapíše do W hodnotu BFh
	MOVWF	TIME_TX		; W do registru TIME_TX
	BSF		RST			; do log. 1 pin RST
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
;TIME_READ_7
	MOVLW	TIME_RX_ADD	;
	MOVWF	FSR			;
	MOVLW	D'7'		;
	MOVWF	COUNT2		;
TR2						;
	CALL	TIME_READ_1	;
	MOVF	TIME_RX,W	;
	MOVWF	INDF		;
	INCF	FSR,F		;
	DECFSZ	COUNT2,F	;
	GOTO	TR2			;
	BCF		RST			;
  RETURN

;************************************************
; TIME_READ_1 - čte hodnotu z DS1302 SINGLE-BYTE READ
; INPUT: NONE
; OUTPUT:
;************************************************
TIME_READ_1
	BANKSEL	TRISA		; vybere Banku 1
	BSF		TRISA,0 	; I_O je vstup
	BANKSEL 0     		; nastavení Banky 0
	MOVLW	D'8'		; do W zapíš dek. 8
	MOVWF	COUNT1		; přesun do registru COUNT1
TR1						; návěstí pro smyčku
	BCF		SCLK		; do log. 0 pin SCLK
	BCF		STATUS,C	; do log. 0 bit Carry v registru STATUS
	BTFSC	I_O			; testuje jestli pin I_O je v log. 0 ANO přeskočí řádek NE pokračuje na další řádek
	BSF		STATUS,C	; do log. 1 bit Carry v registru STATUS
	RRF		TIME_RX,F	; rotace registru TIME_RX přes Carry bit výsledek zpět do TIME_RX
	BSF		SCLK		; do log. 1 pin SCLK
	DECFSZ	COUNT1,F	; odečte jedničku od obsahu registru COUNT1 a výsledek uloží zpět do registru. Je-li výsledek 0, následující instrukce se neprovede.
	GOTO	TR1			; skok na návěstí TR1
	BANKSEL	TRISA		; vybere Banku 1
	BCF		TRISA,0		; I_O je výstup
	BANKSEL 0			; vybere Banku 0
	BCF		SCLK		; do log. 0 pin SCLK
  RETURN

;************************************************
; TIME_WRITE_1 - zapíše hodnotu do DS1302 SINGLE-BYTE WRITE
; INPUT: TIME_TX
;************************************************
TIME_WRITE_1			; návěstí
	MOVLW	D'8'		; do W zapíš dek. 8
	MOVWF	COUNT1		; přesun do registru COUNT1
TLOP					; návěstí pro smyčku
	BCF		I_O			; do log. 0 pin I_O
	BCF		SCLK		; do log. 0 pin SCLK 
	BTFSC	TIME_TX,0	; testuje bit 0 v registru TIME_TX je v log. 0 ANO přeskočí řádek NE pokračuje na další řádek
	BSF		I_O			; do log. 1 pin I_O
	RRF		TIME_TX,F	; rotace doprava registru TIME_TX
	BSF		SCLK		; do log. 1 pin SCLK
	DECFSZ	COUNT1,F	; odečte 1-čku a testuje jestli registr je 0 jestli ANO přeskočí řádek NE tak skok na návěstí TLOP 
	GOTO	TLOP		; skok na návěstí TLOP
	BCF		SCLK		; do log. 0 pin SCLK
  RETURN

;************************************************
; INIT_DS1320 - provede nastavení registru u DS1302
; INPUT: TIME_TX
;************************************************
INIT_DS1320

	call	CONTROL_BIT_CH

;na adresu 90h zapíše AC nastaví TRICKLE CHARGE REGISTER
	BSF		RST			; začátek zápisu
	MOVLW	90h			; zapíše do W hodnotu 90h ;
	MOVWF	TIME_TX		; přesun z W do registru TIME_TX
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
	MOVLW	B'10100101'	; zapíše do W hodnotu ACh
	MOVWF	TIME_TX		; přesun z W do registru TIME_TX
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
	BCF		RST			; konec zápisu

  RETURN

;************************************************
; CLR_RAM - Smaže registry pro uložení hodnot
;************************************************
CLR_RAM
	CLRF	SEC_W		;SEKUNDY
	CLRF	MIN_W		;MINUTY
	CLRF	HOUR_W		;HODINY
	CLRF	DATE_W		;DNY
	CLRF	MONTH_W		;MESICE
	CLRF	YEAR_W		;ROKY
	CLRF	DATE_WEEK_W	;DEN V TYDNU

  RETURN
;************************************************
;	PROTECT_BIT_CLR - smaže ochranný bit proti zápisu
;************************************************
PROTECT_BIT_CLR
	BSF		RST			; začátek zápisu
	MOVLW	8Eh			; nastaví CLOCK HALT FLAG do log. 0
	MOVWF	TIME_TX		; přesun z W do registru TIME_TX
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
	MOVLW	B'00000000'	; zapíše do W hodnotu ACh
	MOVWF	TIME_TX		; přesun z W do registru TIME_TX
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
	BCF		RST			; konec zápisu

  RETURN
;************************************************************
; CONTROL_BIT_CH - po resetu se zkontroluje bit CH v registru sekund
; přečte registr sekund -> otestuje bit7 -> 
; ANO je tak ho vynuluje a zapíše zpět do registru sekund
; NE není tak nic mas tam vir 
; na adresu 80h zapíše D0 nastaví CLOCK HALT FLAG do log. 0
;************************************************************
CONTROL_BIT_CH
;adresa registru sekund pro čtení
	MOVLW	81h			; zapíše do W hodnotu 81h
	MOVWF	TIME_TX		; W do registru TIME_TX
	BSF		RST			; do log. 1 pin RST
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
;čtení hodnoty
	CALL	TIME_READ_1	;
	BCF		RST			;
	MOVF	TIME_RX,W	;
;testování bitu CH
	BTFSS	TIME_RX,7	; bude 0 následují instrukce se provede
  RETURN
;adresa registru sekund pro zápis
	MOVLW	80h			; zapíše do W hodnotu 81h
	MOVWF	TIME_TX		; W do registru TIME_TX
	BSF		RST			; do log. 1 pin RST
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
;nulování bitu CH a zapsání
	BCF		TIME_RX,7	; vynuluje bit 7 v registru
	MOVF	TIME_RX,W	;
	MOVWF	TIME_TX		; W do registru TIME_TX
	CALL	TIME_WRITE_1; volá podprogram TIME_WRITE_1
	BCF		RST			;
  RETURN