TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: pibe en 23 de Diciembre de 2008, 08:13:07
-
Aquí os dejo otra rutina más.
Hoy toca el reloj de tiempo real de Dallas/Maxim DS1302.
El susodicho :mrgreen: 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 :P he podido hacer que rule.
Funciona perfectamente , simulado en el PROTEUS a 4mhz
Cualquier duda me chiflais :P
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 :P
;***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
-
Gracias Pibe por el aporte!, y ya que te quedo todo el manual tachado y corregido, podes descargar otro manual de aqui (http://www.datasheetcatalog.org/datasheets2/22/222522_1.pdf) :D :D :D :mrgreen:
Un abrazo
Norberto
-
ahi te va la rutina para leer el DS1302 en modo burst ;), funciona en Proteus OJO, lo programe para un pic PIC12F1822 necesitas migrar lo de MOVLB a BSF STATUS,RP0 (para entrar a TRISB o TRISA) y CLRF BSR SERIA BCF STATUS,RP0 fuera de ahi todo funcionaria en cualquier pic ;)
LEERCLOCK
BCF INTCON,GIE
MOVLW 0x22
MOVWF FSR0
BSF PORTA,5 ;CE
MOVLW 0xBF
MOVWF OUTCLOCK
CALL ENVIRELOJ
CALL RECIRELOJ
INCF FSR0,F
CALL RECIRELOJ
INCF FSR0,F
CALL RECIRELOJ
INCF FSR0,F
CALL RECIRELOJ
INCF FSR0,F
CALL RECIRELOJ
INCF FSR0,F
CALL RECIRELOJ
INCF FSR0,F
CALL RECIRELOJ
BCF PORTA,5 ;CE
BCF PORTA,2
BSF INTCON,GIE
RETURN
ENVIRELOJ
MOVLB 0x01
BCF PORTA,4 ;I/O
CLRF BSR
MOVLW 0x08
MOVWF COUNTBIT
ENVIANREL
BCF PORTA,2
BCF STATUS,C
RRF OUTCLOCK,F
BCF PORTA,4
BTFSC STATUS,C
BSF PORTA,4 ;I/O
BSF PORTA,2 ;SCLK
DECFSZ COUNTBIT,F
GOTO ENVIANREL
RETURN
RECIRELOJ
MOVLB 0x01
BSF PORTA,4
CLRF BSR
MOVLW 0x08
MOVWF COUNTBIT
RECIBIREL
BCF PORTA,2
BCF STATUS,C
BTFSC PORTA,4
BSF STATUS,C
BSF PORTA,2 ;SCLK
RRF INDF0,F
DECFSZ COUNTBIT,F
GOTO RECIBIREL
RETURN