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