Aquí os dejo otra rutina más.
Hoy toca el reloj de tiempo real de Dallas/Maxim DS1302.
El susodicho
utiliza el sistema de comunicación serie. Me ha hecho sudar lo suyo porque me había empecinado en leer en modo BURST y no pude lograrlo.
No hubo manera, incluso utilizando puntillosamente las instrucciones de su hoja de datos.
Aunque sí pude grabarlo en modo BURST y luego leer los datos grabados de a uno.
Después de unos días de modificar programa y dejar las hojas de datos como si las hubiese tachonado un niño de 2 años
he podido hacer que rule.
Funciona perfectamente , simulado en el PROTEUS a 4mhz
Cualquier duda me chiflais
Incluyo archivo de prueba del PROTEUS
http://www.4shared.com/file/77239734/c0f7a0ec/DS1302.html;*****************************************************************************
; Ejemplo de utilización del RTC DS1302 y 16F877 en modo bitbang por Puerto B
;*****************************************************************************
__CONFIG _CP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _BODEN_OFF & _LVP_OFF &_CPD_OFF ;&_WRT_ENABLE_OFF
LIST P = 16F877A
#INCLUDE "P16F877A.INC"
errorlevel -302 ; Suppress message 302 from list file
errorlevel -203
errorlevel -205
CBLOCK 0x20
SEGUNDOS
MINUTOS
HORAS
FECHA
MES
DIA
AÑO
DATO ; buffer de datos in/out
CONT ; contador de bits
PDel0
PDel1
PDel2
ENDC
;Definición de pines
#define IO PORTB,2
#define RST PORTB,0
#define SCLK PORTB,1
;Constantes para grabar el calendario actual
;CAMBIARLAS CON EL TIEMPO ACTUAL !!
AÑOACTUAL equ 08h ; cambiar esta constante por el año actual
MESACTUAL equ 12h ; cambiar esta constante por el mes actual
FECHAACTUAL equ 22h ; cambiar esta constante por la fecha actual
DIAACTUAL equ 03h ; cambiar esta constante por el dia actual (Domingo=1)
HORAACTUAL equ 18h ; cambiar esta constante por la hora actual
MINACTUAL equ 09h ; cambiar esta constante por los minutos actuales
SEGACTUAL equ 00h ; dejarlo en 0
;***Constantes de comandos (NO CAMBIAR)***
CONTROLESCR equ 0x8E; comando de escritura
CONTROLLECT equ 0x8F; comando de lectura
WP equ 0x00; dato de inhabilitacion de protección de escritura
;Constantes comandos de escritura
BURSTWRITE equ 0xBE
WRITEAÑO equ 0x8C
WRITEMES equ 0x88
WRITEFECHA equ 0x86
WRITEDIA equ 0x8A
WRITEHORA equ 0x84
WRITEMIN equ 0x82
WRITESEC equ 0x80
;Constantes comandos de lectura
BURSTREAD equ 0xBF
READAÑO equ 0x8D
READMES equ 0x89
READFECHA equ 0x87
READDIA equ 0x8B
READHORAS equ 0x85
READMIN equ 0x83
READSEG equ 0x81
;******************************************
ORG 00h
goto Inicio
ORG 04H
retfie
Inicio
bsf STATUS,RP0
movlw B'00000000' ; Todo salidas, luego cambiamos el bit IO acorde a la funcion que necesite
movwf TRISB
movwf TRISD
movwf TRISC
bcf STATUS,RP0
clrf PORTB
clrf PORTD
clrf PORTC
Main
;Escritura secuencial de los datos actuales en los registros del DS1302
movlw CONTROLESCR ;Comando Escritura (control)
call ENVIAR_DATO ;Llamar rutina enviar.
movlw WP ;Deshabilitar WriteProtect
call ENVIAR_DATO
bcf RST ;Terminar comunicación
movlw BURSTWRITE ;habilito modo BURST escritura
call ENVIAR_DATO
movlw SEGACTUAL
call ENVIAR_DATO
movlw MINACTUAL
call ENVIAR_DATO
movlw HORAACTUAL
call ENVIAR_DATO
movlw FECHAACTUAL
call ENVIAR_DATO
movlw MESACTUAL
call ENVIAR_DATO
movlw DIAACTUAL
call ENVIAR_DATO
movlw AÑOACTUAL
call ENVIAR_DATO
movlw CONTROLESCR ;Comando Escritura (control)
call ENVIAR_DATO ;Llamar rutina enviar.
bcf RST ;Terminar comunicación
;Pequeña pausa entre escritura y lectura
call DEMORA1s
;Lectura de los datos actuales de los registros del DS1302
;Los datos leídos son guardados en sus respectivas variables y mostramos MINUTOS, HORAS, FECHA, MES, AÑO de a uno por el puerto D en su formato original
;o sea BCD
Lectura
call comando_lectura
movlw READMIN ;leo minutos
call ENVIAR_DATO ;Llamar rutina enviar.
call RECIBIR_DATO
movwf MINUTOS
movwf PORTD
call DEMORA1s
call comando_lectura
movlw READHORAS ;leo Horas
call ENVIAR_DATO ;Llamar rutina enviar.
call RECIBIR_DATO
movwf HORAS
movwf PORTD
call DEMORA1s
call comando_lectura
movlw READFECHA ;leo Fecha
call ENVIAR_DATO ;Llamar rutina enviar.
call RECIBIR_DATO
movwf FECHA
movwf PORTD
call DEMORA1s
call comando_lectura
movlw READMES ;leo Mes
call ENVIAR_DATO ;Llamar rutina enviar.
call RECIBIR_DATO
movwf MES
movwf PORTD
call DEMORA1s
call comando_lectura
movlw READAÑO ;leo Año
call ENVIAR_DATO ;Llamar rutina enviar.
call RECIBIR_DATO
movwf AÑO
movwf PORTD
call DEMORA1s
goto Lectura
ENVIAR_DATO
movwf DATO
movlw D'8' ;Redefinir contador
movwf CONT
bsf STATUS,RP0 ;Setear IO como salida
bcf IO ; o sea TRIS
bcf STATUS,RP0
bsf RST ;Entablar comunicación
ENVIANDO
bcf IO ;Apagar IO
btfsc DATO,0 ;Si DATO,0 es 1, entonces
bsf IO ;poner IO en 1
bsf SCLK ;Un Clock
bcf SCLK
rrf DATO,F ;Rotar DATO hacia la derecha
decfsz CONT,F ;Decrementa CONT y salta si es 0
goto ENVIANDO ;Volver si CONT no era 0
return ;No olvidar resetear comunicación manualmente.
RECIBIR_DATO
movlw D'7'
movwf CONT
bsf STATUS,RP0 ;Setear IO como entrada
bsf IO
bcf STATUS,RP0
bsf RST ;Entablar comunicación
RECIBIENDO
bcf DATO,0 ;Resetear DATO,0
btfsc IO ;Si IO es 1, entonces
bsf DATO,0 ;poner DATO,0 en 1
bsf SCLK ;Un Clock
bcf SCLK
rlf DATO,F ;Rotar DATO a la izquierda
decfsz CONT,F ;Decrementa CONT y salta si es 0
goto RECIBIENDO ;Volver si CONT no era 0
bcf RST ;Terminar comunicación
movf DATO,W ;Enviar DATO recibido a W
return
DEMORA1s movlw .14 ; 1 set numero de repeticion (C)
movwf PDel0 ; 1 |
PLoop0 movlw .72 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLoop1 movlw .247 ; 1 set numero de repeticion (A)
movwf PDel2 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
goto PLoop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
comando_lectura
movlw CONTROLLECT ;leo segundos
call ENVIAR_DATO ;Llamar rutina enviar.
movlw WP ;leo segundos
call ENVIAR_DATO ;Llamar rutina enviar.
bcf RST ;Terminar comunicación
return
END