hola JOSEMP.ya hace tiempo controle ese chip.e hize un programa para su gestion.te pondre lo que hize.igual te sirve algo.aunque no puedo
dartelo ordenado por falta de tiempo.ademas es para un pic de la serie 18F.saludos
LIST
;-------------------------------------------------------------------------------------------;
; SUBRUTINAS DE I2C ;
;-------------------------------------------------------------------------------------------;
Leer_RTC RCALL Start_I2C ;Llama a la subrutina de START
;CALL DEMORA
MOVLW 0xD0 ;Carga en W el Address del DS1307 y el bit de escritura
MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
RCALL Write_I2C ;Llama a la subrutina de escritura
MOVLW 0x00 ;Carga en W la primer posición de memoria
MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
RCALL Write_I2C ;Llama a la subrutina de escritura
RCALL Restart_I2C ;Llama a la subrutina de RESTART
MOVLW 0xD1 ;Carga en W el Address del DS1307 y el bit de lectura
MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
RCALL Write_I2C ;Llama a la subrutina de escritura
;LFSR FSR0,0x000 ;Limpia el puntero
;MOVLW 0X06
;MOVWF FSR0H
movlw 0x00 ;principio de ram donde se introduciran los datos leidos del RTC
movwf FSR2L
Bucle_Leer RCALL Read_I2C ;Llama a la subrutina de lectura
MOVFF SSPBUF,POSTINC2 ;Guarda el dato en la Ram e incrementa el puntero
movlw 0x07
xorwf FSR2L,W
BTFSS STATUS,Z ;Si FSR0L no llegó a 0x07
RCALL Send_I2C_Ack ;Llama a la subrutina de ACKNOWLEDGE
movlw 0x07
xorwf FSR2L,W
BTFSS STATUS,Z ;Si FSR0L no llegó a 0x07
;BTFSS FSR2L,3,0 ;Si FSR0L no llegó a 0x08
BRA Bucle_Leer ;continúa leyendo
RCALL Send_I2C_NoAck ;Si llegó a 8 llama a la subrutina de ACKNOWLEDGE
RCALL Stop_I2C ;Llama a la subrutina de STOP
RETURN ;Retorna de la subrutina
Escribir_I2C1 RCALL Start_I2C ;Llama a la subrutina de START
MOVLW 0xD0 ;Carga en W el Address del DS1307 y el bit de escritura
MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
RCALL Write_I2C ;Llama a la subrutina de escritura
MOVLW 0x00 ;Carga en W la primer posición de memoria
MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
RCALL Write_I2C ;Llama a la subrutina de escritura
;LFSR FSR0,0x000 ;Limpia el puntero
MOVLW 0X50 ;principio de ram donde se introduciran los datos para escribir en el RTC
MOVWF FSR2L
Bucle_Escribir1 MOVFF POSTINC0,SSPBUF ;Carga el dato de la Ram en SSPBUF e incrementa el puntero
RCALL Write_I2C ;Llama a la subrutina de escritura
BTFSS FSR2L,3,0 ;Si FSR0L no llegó a 0x08
BRA Bucle_Escribir1 ;continúa enviando datos
RCALL Stop_I2C ;Llama a la subrutina de STOP
RETURN ;Retorna de la subrutina
Start_I2C BSF SSPCON2,SEN,0 ;Pone a uno el bit de START
S2 BTFSC SSPCON2,SEN,0 ;Espera a que se ponga a cero el bit de START
BRA S2
S3 BTFSS PIR1,SSPIF,0 ;Espera a que la condicion de START haya sido completada
BRA S3 ;cuando se ponga a 1 la bandera de interrupción
BCF PIR1,SSPIF,0 ;Borra la bandera de la interrupción
RETURN ;Retorna de la subrutina
Write_I2C BTFSC SSPSTAT,R_W,0 ;Verifica que se ponga a cero el bit R/W
BRA Write_I2C ;Espera a que termine de enviar el dato
W2 BTFSC SSPCON2,ACKSTAT,0 ;Espera a que reciba el bit de ACKNOWLEDGE
BRA W2
BCF PIR1,SSPIF,0 ;borra la bandera de la interrupción
CLRWDT
RETURN ;Retorna de la subrutina
Restart_I2C BSF SSPCON2,RSEN,0 ;Pone a uno el bit de RESTART
R2 BTFSC SSPCON2,RSEN,0 ;Espera a que se ponga a cero el bit de RESTART
BRA R2
R3 BTFSS PIR1,SSPIF,0 ;Espera a que la condicion de RESTART haya sido completada
BRA R3 ;cuando se ponga a 1 la bandera de interrupción
BCF PIR1,SSPIF,0 ;Borra la bandera de la interrupción
RETURN ;Retorna de la subrutina
Read_I2C BSF SSPCON2,RCEN,0 ;Habilita la recepción de datos mediante el bit RCEN
Rea2 BTFSC SSPCON2,RCEN,0 ;Espera a que se ponga a cero el bit RCEN
BRA Rea2
Rea3 BTFSS SSPSTAT,BF,0 ;Dato disponible en SSPBUF para ser leidos?
BRA Rea3 ;No, esperar
Rea4 BTFSS PIR1,SSPIF,0 ;Espera a que la condicion de Lectura haya sido completada
BRA Rea4 ;cuando se ponga a 1 la bandera de interrupción
BCF PIR1,SSPIF,0 ;Borra la bandera de la interrupción
RETURN ;Retorna de la subrutina
Send_I2C_Ack BCF SSPCON2,ACKDT,0 ;Pone a cero el bit de ACKNOWLEDGE DATA
BSF SSPCON2,ACKEN,0 ;Genera la condición de ACKNOWLEDGE Poniendo a 1 el bit ACKEN
BTFSS PIR1,SSPIF,0 ;Espera a que la condicion de ACK haya sido completada
BRA Rea4 ;cuando se ponga a 1 la bandera de interrupción
BCF PIR1,SSPIF,0 ;Borra la bandera de la interrupción
RETURN ;Retorna de la subrutina
Send_I2C_NoAck BSF SSPCON2,ACKDT,0 ;Pone a 1 el bit de ACKNOWLEDGE DATA
BSF SSPCON2,ACKEN,0 ;Genera la condición de NO ACKNOWLEDGE Poniendo a 1 el bit ACKEN
BTFSS PIR1,SSPIF,0 ;Espera a que la condicion de No ACK haya sido completada
BRA Rea4 ;cuando se ponga a 1 la bandera de interrupción
BCF PIR1,SSPIF,0 ;Borra la bandera de la interrupción
RETURN ;Retorna de la subrutina
Stop_I2C BSF SSPCON2,PEN,0 ;Genera la condición de STOP poniendo a 1 el bit PEN
P2 BTFSC SSPCON2,PEN,0 ;Espera a que se ponga a cero el bit PEN
BRA P2
BTFSS PIR1,SSPIF,0 ;Espera a que la condicion de Stop haya sido completada
BRA Rea4 ;cuando se ponga a 1 la bandera de interrupción
BCF PIR1,SSPIF,0 ;Borra la bandera de la interrupción
RETURN
LIST
;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : teclado_LCD_v1.asm
; Funcion : pruevas con teclado y lcd
;
;
; Revision : 1.0 9/9/2011 Programa para : PIC18F2550
; CPU Clock : 48 MHz Reloj instruccion :
; WDT : Deshabilitado Tipo de reloj : XT
; Code Prot : OFF
;************************************************* www.ingeniopic.com **************************************************
;
;NOTA: se han activado las resistencias pull-up de PORTB.debido a que se producia un error al leer el bit BUSY de la LCD.
; ya que las salidas de la lcd se quedan en alta impedancia.y el pic no leia correctamente D7.
; LIST P=18F2550 ; Se emplea el PIC 18F2550
; RADIX HEX ; Sistema de numeraci¢n hexadecimal
; INCLUDE "P18F2550.INC"
; CONFIG FOSC = HS ;Osc por XTAL 20mhz
; CONFIG DEBUG = OFF
; CONFIG PWRT = OFF
; CONFIG BOR = OFF
; CONFIG WDT = OFF
; CONFIG MCLRE = ON
; CONFIG PBADEN = OFF
; CONFIG LVP = OFF
; CONFIG CP0 = OFF
; CONFIG CP1 = OFF
; CONFIG CP2 = OFF
; CONFIG CP3 = OFF
; CONFIG CPB = OFF
; CONFIG CPD = OFF
;
; ;CONFIG OSCS = OFF, OSC = HS, BORV = 42, BOR = ON, PWRT = ON, WDTPS = 128, WDT = OFF, CCP2MUX = OFF, DEBUG = OFF, LVP = OFF, STVR = ON
; CONFIG CP3 = OFF, CP2 = OFF, CP1 = OFF, CP0 = OFF, CPD = OFF, CPB = OFF, WRT3 = OFF, WRT2 = OFF, WRT1 = OFF, WRT0 = OFF
; CONFIG WRTD = OFF, WRTB = OFF, WRTC = OFF, EBTR3 = OFF, EBTR2 = OFF, EBTR1 = OFF, EBTR0 = OFF, EBTRB = OFF
;
;
; ERRORLEVEL -302
;res 2
;ZONA DE ETIQUETAS
; CBLOCK 0X22
; FALLA
; CONTENIDO
; DIRECCION
; EEADDR
; EEDATO
; EESLAVE
; DelayCtr1
; DelayCtr2
; SlaveAddr
; PULSO
; ENDC
;
;0X50
CBLOCK DS1307_VAR
tiempo ;equ 0x08 ;variable temporal para los bucles de demora
tiempo1 ;equ 0x09 ;variable temporal para los bucles de demora
Dato_LCD ;equ 0x0A ;Varible temporal del byte a sacar por el LCD
Variable_temp ;equ 0x0B ;Banderas
Menu ;equ 0x0C ;Variable con el número de menú de ajuste
Limites ;equ 0x0D ;límite de la variable a ajustar
Puntero ;equ 0x0E ;puntero del límite
Flags ;equ 0x0F ;Variable temporal
Flags2
;POSTINC0
FALLA
CONTENIDO
DIRECCION
EEADDR
EEDATO
EESLAVE
DelayCtr1
DelayCtr2
SlaveAddr
PULSO
FSR2L_OR
ENDC
CBLOCK RELOJ_VAR
Segundos ;equ 0x00 ;posición 0x00 de la memoria del 1307
Minutos ;equ 0x01 ;posición 0x01
Horas ;equ 0x02 ;posición 0x02
DiaSemana ;equ 0x03 ;posición 0x03
Dia ;equ 0x04 ;posición 0x04
Mes ;equ 0x05 ;posición 0x05
Año ;equ 0x06 ;posición 0x06
Control ;equ 0x07 ;posición 0x07
ENDC
Ajustar equ 0X00 ;Bit del registro Flags
#define RTC_ON bsf Flags2,0
;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
; ORG 0x00 ;Inicio en el Vector de Reset
; goto INICIO ;ir a la primera instruccion del programa
;;<<<<<<---------------------- VECTOR DE INTERRUPCIONES ALTA PRIORIDAD ---------------->>>>>>>>>>
; ORG 0X08
; goto INTERRUP
;;<<<<<<---------------------- VECTOR DE INTERRUPCIONES BAJA PRIORIDAD ---------------->>>>>>>>>>
; ORG 0X18
; goto INTERRUP
;
;
; ORG 0X001C
;;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
;INICIO
;
; CLRF INTCON
; movlw B'01100000';b'01101000' ;interrupciones perifericas y tmr0
; movwf INTCON
;
;
; clrf T0CON
;
;
; movlw b'01111001'
; movwf T1CON
; clrf UCON,1
;
; movlw b'00001000'
; movwf PIE1
; clrf TMR1L
; clrf TMR1H
;
;
; CLRF PORTB
; CLRF LATB
; MOVLW 0Eh
; MOVWF ADCON1
;
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
;PRINCIPAL
; MOVLW b'00000011';0X18
; MOVWF TRISB;SDA Y SCL CMO ENTRADAS
; movlw b'11000000' ;configurar pin tx y rx como entradas para el correco funcionamiento
; movwf TRISC
;
; MOVLW 0X80
; MOVWF SSPSTAT
; movlw 0x31 ;eusart
; MOVWF SSPCON1
; CLRF SSPCON2
; MOVLW 0X01
; MOVWF BSR
; movlw 0x09 ; set I2C clock rate to 100kHz
; movwf SSPADD
; movlw b'11110000'
; movwf INTCON2
; movlw b'10000000'
; movwf INTCON3
; movlw b'00100000'
; movwf PIE1,0
;<<<<<<<<<<<<<<<<<<<<<----------------------------- RELOJ --------------------------->>>>>>>>>>>>>>>>>>>>>>>>>>>
; ubicacion de los datos del RTC en la direccion 0x100h de la ram del pic
RELOJ movlb 0X01 ;banco donde se ubicaran los datos del reloj
lfsr FSR2,0X101 ;selecciona direccion 101h de la ram
clrf TMR0H ;reinicia TMR0
clrf TMR0L
call Leer_RTC ;salta a subprograma de lectura del RTC
call HEX_DAC
call ALARMAS
;return
;CALL HEX
movlw 0xff
xorwf 0xff,w
btfss STATUS,Z
return
rcall Start_I2C ;Llama a la subrutina de START
movlw 0xD0 ;Carga en W el Address del DS1307 y el bit de escritura
movwf SSPBUF,0 ;Lo carga en el Buffer de salida
rcall Write_I2C ;Llama a la subrutina de escritura
movlw 0x00 ;Carga en W la primer posición de memoria
MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
RCALL Write_I2C ;Llama a la subrutina de escritura
RCALL Restart_I2C ;Llama a la subrutina de RESTART
MOVLW 0xD0 ;Carga en W el Address del DS1307 y el bit de lectura
MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
RCALL Write_I2C ;Llama a la subrutina de escritura
;LFSR FSR0,0x000 ;Limpia el puntero
BANK1
; movlw 0x01
; movwf FSR2H
; movlw 0x0f
; movwf FSR2L
lfsr FSR2,0X10F
set_rtc incf FSR2L
movf INDF2,w
call DEC_HEX
movff Resultado,SSPBUF
rcall Write_I2C;Read_I2C ;Llama a la subrutina de lectura
movlw 0x16
xorwf FSR2L,w
btfss STATUS,Z
goto set_rtc
rcall Stop_I2C ;Llama a la subrutina de STOP;rcall Send_I2C_Ack ;Llama a la subrutina de ACKNOWLEDGE
BANK0
clrf 0XFF ;borra coil de cambio de hora.
return
HEX_DAC lfsr FSR1,0x100
lfsr FSR2,0x108
rep_mem ;movlb 0x01
movf INDF1,W
call HEX_DEC
movwf POSTINC2
incf FSR1L
btfss FSR1L,3
goto rep_mem
return
;*********************************** CONVERTIR VALOR HEX EN DECIMAL ******************************************************
HEX_DEC BANK7 ;selecciona banco 7 de ram
movwf ByteL ;carga valor a convertir contenido en W
movwf ByteH ;carga valor a convertir contenido en W
movlw 0x0f ;selecciona el nibble bajo de W
andwf ByteL,f ;introducelo en el registro ByteL
movlw 0xf0 ;selecciona el nibble alto de W
andwf ByteH,f ;introducelo en el registro ByteH
swapf ByteH,w ;invierte los nibles de ByteH e introduce el resultado en W
mullw .10 ;multiplica el contenido de W por 10d
movf PRODL,w ;caga el resultado en W
addwf ByteL,w ;suma el contenido de ByteL a W
return
;*********************************** CONVERTIR VALOR DECIMAL EN HEX ******************************************************
DEC_HEX BANK7 ;selecciona el banco 7 de ram
movwf reg1 ;carga valor a convertir contenido en W
setf Resultado ;pon a 1 todos los bits del registro Resultado.
movlw .10 ;carga el valor 10d en W
div incf Resultado,f ;incrementa el registro Resultado
subwf reg1,F ;restar a reg1 el valor .10
btfsc STATUS,C ;comprueba si ha habido acarreo
goto div ;repite div
movlw .10 ;
addwf reg1,W
movwf Resto
swapf Resultado
addwf Resultado
return
;************************************************ ALARMAS ****************************************
ALARMAS
; movlw 0x10
; movwf FSR2L
; movlw 0x01
; movwf FSR2H
lfsr FSR2,0x110
pri_al clrf TEMP_ALARM
clrf FLAGS_RTC
bsf FLAGS_RTC,7
; movlw 0x08
; movwf FSR1L
; movlw 0x01
; movwf FSR1H
lfsr FSR1,0x108
rep_alrm rlncf FLAGS_RTC ;rota hacia la izquierda registro de comparacion de coincidencias
movf POSTINC2,W ;carga en W contenido de la posicion de memoria direccionada por FSR2
xorwf POSTINC1,W ;comparalo con contenido de la direccion de FSR1
btfsc STATUS,Z ;si es igual,salta a incre
call incre
btfss FLAGS_RTC,6 ;comprueba si se llego al final de las comparaciones de la alarma actual
goto rep_alrm ;si no es asi,repite proceso de comparaciones
;se comprueba que las coincidencias sean exactas.
movf INDF2,W ;carga en w el contenido del registro de coincidencias
andwf TEMP_ALARM,W ;comprueba si los bits coinciden con logico 1
xorwf INDF2,W ;descarta coincidencias con logico 0.
btfsc STATUS,Z ;comprueba si todas las comparaciones coinciden
call ACTIVAC ;si es asi,activa dispositivo
incf FSR2L,F ;incrementa direccion de siguente alarma a comprobar
movlw 0x90 ;ultima direccion a comprobar
xorwf FSR2L,W ;compara la direccion actual
btfss STATUS,Z ;si no se a llegado a la ultima alarama,
goto pri_al ;salta a comprobacion de siguiente alarma.
call SALIDA_OR
lfsr FSR2,0x1fe
movlw 0xff
xorwf 0xfe,w
btfsc STATUS,Z
;return
call GRABA_ALARM
clrf 0xfe ;poner a 0 el coil de la direccion 0x0fe (desactivar grabacion de alarmas en eeprom)
return
incre movf FLAGS_RTC,W
addwf TEMP_ALARM
return
ACTIVAC movlw 0x00
xorwf INDF2,W ;comprueba que el egistro de comparaciones no se 0x00
btfsc STATUS,Z
return
movlb 0x00
movlw 0x17
xorwf FSR2L,W
btfsc STATUS,Z
bsf 0x0f,0
movlw 0x1F
xorwf FSR2L,W
btfsc STATUS,Z
bcf 0x0f,0
movlw 0x27
xorwf FSR2L,W
btfsc STATUS,Z
bsf 0x0f,1
movlw 0x2F
xorwf FSR2L,W
btfsc STATUS,Z
bcf 0x0f,1
movlw 0x37
xorwf FSR2L,W
btfsc STATUS,Z
bsf 0x0f,2
movlw 0x3F
xorwf FSR2L,W
btfsc STATUS,Z
bcf 0x0f,2
movlw 0x47
xorwf FSR2L,W
btfsc STATUS,Z
bsf 0x0f,3
movlw 0x4F
xorwf FSR2L,W
btfsc STATUS,Z
bcf 0x0f,3
movlw 0x57
xorwf FSR2L,W
btfsc STATUS,Z
bsf 0x0f,4
movlw 0x5F
xorwf FSR2L,W
btfsc STATUS,Z
bcf 0x0f,4
movlw 0x67
xorwf FSR2L,W
btfsc STATUS,Z
bsf 0x0f,5
movlw 0x6F
xorwf FSR2L,W
btfsc STATUS,Z
bcf 0x0f,5
movlw 0x77
xorwf FSR2L,W
btfsc STATUS,Z
bsf 0x0f,6
movlw 0x7F
xorwf FSR2L,W
btfsc STATUS,Z
bcf 0x0f,6
movlw 0x87
xorwf FSR2L,W
btfsc STATUS,Z
bsf 0x0f,7
movlw 0x8F
xorwf FSR2L,W
btfsc STATUS,Z
bcf 0x0f,7
movlb 0x07
return
;************************************************ SALIDA OR *************************************************
; Activa salida OR cuando cualquier salida este a 1
SALIDA_OR BANK7
movff FSR2L,FSR2L_OR
lfsr FSR2,0x0f
movlw 0X00
xorwf INDF2,W
btfss STATUS,Z
bsf 0X10,0
btfsc STATUS,Z
bcf 0X10,0
lfsr FSR2,0x100
movff FSR2L_OR,FSR2L
BANK0
return
;*********************************************** GRABA_ALARM ******************************************
GRABA_ALARM
lfsr FSR2,0X110
clrf EEADR;DIR_EEPROM
rep_gra movff POSTINC2,EEDATA;DATO_EEPROM
;movlb 0x07
call ESCRIBIR_DATO
incf EEADR,F;DIR_EEPROM,F
movlw 0x90 ;ultima direccion a comprobar
xorwf EEADR,w;DIR_EEPROM,W ;compara la direccion actual
btfss STATUS,Z ;si no se a llegado a la ultima
goto rep_gra ;salta a comprobacion de
return
;Escribir_I2C RCALL Start_I2C ;Llama a la subrutina de START
; MOVLW 0xD0 ;Carga en W el Address del DS1307 y el bit de escritura
; MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
; RCALL Write_I2C ;Llama a la subrutina de escritura
; MOVLW 0x00 ;Carga en W la primer posición de memoria
; MOVWF SSPBUF,0 ;Lo carga en el Buffer de salida
; RCALL Write_I2C ;Llama a la subrutina de escritura
; LFSR FSR0,0x000 ;Limpia el puntero
;Bucle_Escribir MOVFF POSTINC0,SSPBUF ;Carga el dato de la Ram en SSPBUF e incrementa el puntero
; RCALL Write_I2C ;Llama a la subrutina de escritura
; BTFSS FSR0L,3,0 ;Si FSR0L no llegó a 0x08
; BRA Bucle_Escribir ;continúa enviando datos
; RCALL Stop_I2C ;Llama a la subrutina de STOP
; RETURN
;Retorna de la subrutina