Hola amigo, prueba con este código, debes analizarlo y adaptarlo a tu necesidad
saludos.
title ¨ MANEJO DEL RELOJ SRIAL DS1307¨
list p=16f873a
;registros de proposito especifico
dir_ind equ 00
tmr0 equ 01
pc equ 02
status equ 03
fsr equ 04
porta equ 05
portb equ 06
portc equ 07
eedata equ 08
eeadr equ 09
pclath equ 0a
intcon equ 0b
pir1 equ 0c
;==============================================================================
;registros de configuracion
trisa equ 05
trisb equ 06
trisc equ 07
pie1 equ 0c
;=====================================================================
;registros de proposito general
cblock h'20'
conta1, respaldo, respaldo_b, respaldo_a
seg_uni, seg_dec, minu_uni, minu_dec, hora_uni, hora_dec
dia_semana, dia_uni, dia_dec, mes_uni, mes_dec, año_uni, año_dec
endc
;==============================================================================
;bit de registro status
c equ 00
z equ 02
rp0 equ 05
w equ 00
f equ 01
sda equ 07
scl equ 06
;==============================================================================
org 00
goto inicio
;==============================================================================
;==============================================================================
inicio bsf status,rp0
movlw b'00111111'
movwf trisb
bcf status,rp0
;=============
movlw h'ff'
movwf portb
clrf respaldo
;==============================================================================
call conf_DS1307
call leer_DS1307
goto $-1
;==============================================================================
;==============================================================================
tiempo_I2C movlw d'11' ;TIEMPO DE 100 Us PARA LA COMUNICACION
movwf conta1 ;I2C
nop
decfsz conta1,f
goto $-2
nop
return
;=======================================================
stop bsf portb,scl ;STOP
call tiempo_I2C
bsf portb,sda
call tiempo_I2C
return
;=======================================================
start bcf portb,sda ;START
call tiempo_I2C
bcf portb,scl
call tiempo_I2C
return
;=======================================================
pulso_ack bcf portb,sda ;PULSO DE ACK
call tiempo_I2C
bsf portb,scl
call tiempo_I2C
bcf portb,scl
call tiempo_I2C
return
;=======================================================
env_dat_I2C movwf respaldo
movlw d'8'
movwf respaldo_b
otro_bit_sda rlf respaldo,f
btfss status,c
bcf portb,sda
btfsc status,c
bsf portb,sda
call tiempo_I2C
bsf portb,scl
call tiempo_I2C
bcf portb,scl
call tiempo_I2C
decfsz respaldo_b,f
goto otro_bit_sda
call tiempo_I2C
bcf portb,sda
return
;=======================================================
lee_dat_I2C bcf intcon,7 ;SE CONFIGURA SDA COMO ENTRADA
bsf status,rp0
bsf trisc,sda
bcf status,rp0
movlw d'8'
movwf respaldo_b
lee_otro_sda call tiempo_I2C
bsf portb,scl
call tiempo_I2C
btfss portb,sda
bcf status,c
btfsc portb,sda
bsf status,c
bcf portb,scl
rlf respaldo,f
decfsz respaldo_b,f
goto lee_otro_sda
;=============
call tiempo_I2C
bsf status,rp0 ;SE CONFIGURA SDA COMO ENTRADA
bcf trisc,sda
bcf status,rp0
bsf intcon,7
movf respaldo,w
return
;==============================================================================
;==============================================================================
conf_DS1307 call start
;=============
movlw b'11010000' ;CONFIGURACION DS1703
call env_dat_I2C
;=============
call pulso_ack
;=============
clrw
call env_dat_I2C ;DIRECCION DONDE EMPIEZAN LOS DATOS
;============= ;DEL RELOJ
call pulso_ack
;=============
swapf seg_dec,w
iorwf seg_uni,w
call env_dat_I2C ;SE ENVIA EL DATO DE SEGUNDOS
;=============
call pulso_ack
;=============
swapf minu_dec,w
iorwf minu_uni,w
call env_dat_I2C ;SE ENVIA EL DATO DE MINUTOS
;=============
call pulso_ack
;=============
swapf hora_dec,w
iorwf hora_uni,w
call env_dat_I2C ;SE ENVIA EL DATO DE LAS HORAS
;=============
call pulso_ack
;=============
movf dia_semana,w ;SE ENVIA EL DATO DE DIA SEMANA
call env_dat_I2C
;=============
call pulso_ack
;=============
swapf dia_dec,w
iorwf dia_uni,w
call env_dat_I2C ;SE ENVIA EL DATO DE LOS DIAS DEL MES
;=============
call pulso_ack
;=============
swapf mes_dec,w
iorwf mes_uni,w
call env_dat_I2C ;SE ENVIA EL DATO DE MES
;=============
call pulso_ack
;=============
swapf año_dec,w
iorwf año_uni,w
call env_dat_I2C ;SE ENVIA EL DATO DE AÑO
;=============
call pulso_ack
;=============
movlw b'00000000' ;SE ENVIA EL DATO DE PULSO DE SALIDA
call env_dat_I2C
;=============
call pulso_ack
;=============
call stop
return
;=======================================================
;=======================================================
leer_DS1307 call start
;=============
movlw b'11010000' ;CONFIGURACION DS1703
call env_dat_I2C
;=============
call pulso_ack
;=============
clrw
call env_dat_I2C ;DIRECCION A PARTIR DE LA CUAL VA A EMPEZAR
;============= ;LA LECTURA
call pulso_ack
;=============
call stop
;===========================
call tiempo_I2C
call start
movlw b'11010001' ;CONFIGURACION DS1703
call env_dat_I2C
;=============
call pulso_ack
;=============
call lee_dat_I2C ;SE LEE EL DATO DE LOS SEGUNDOS
movwf seg_uni
bcf respaldo,7
swapf respaldo,w
movwf seg_dec
movlw h'0f'
andwf seg_uni,f
andwf seg_dec,f
;=============
call pulso_ack
;=============
call lee_dat_I2C ;SE LEE EL DATO DE LOS MINUTOS
movwf minu_uni
swapf respaldo,w
movwf minu_dec
movlw h'0f'
andwf minu_uni,f
andwf minu_dec,f
;=============
call pulso_ack
;=============
call lee_dat_I2C ;SE LEE EL DATO DE LAS HORAS
movwf hora_uni
swapf respaldo,w
movwf hora_dec
movlw h'0f'
andwf hora_uni,f
andwf hora_dec,f
;=============
call pulso_ack
;=============
call lee_dat_I2C ;SE LEE EL DATO DEL DIA DE LA SEMANA
movwf dia_semana
;=============
call pulso_ack
;=============
call lee_dat_I2C ;SE LEE EL DATO DE LOS DIAS DEL MES
movwf dia_uni
swapf respaldo,w
movwf dia_dec
movlw h'0f'
andwf dia_uni,f
andwf dia_dec,f
;=============
call pulso_ack
;=============
call lee_dat_I2C ;SE LEE EL DATO DEL MES
movwf mes_uni
swapf respaldo,w
movwf mes_dec
movlw h'0f'
andwf mes_uni,f
andwf mes_dec,f
;=============
call pulso_ack
;=============
call lee_dat_I2C ;SE LEE EL DATO DEL AÑO
movwf año_uni
swapf respaldo,w
movwf año_dec
movlw h'0f'
andwf año_uni,f
andwf año_dec,f
;=============
call stop
return
;==============================================================================
end