TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: JOSEMP en 05 de Septiembre de 2014, 00:19:47
-
Saludos Amigos.
Aquí vengo otra vez con unas de mis dudas, un poco alejado del foro por falta de tiempo, pero retomo nuevamente la programación, acudo a ustedes por que siempre me han ayudado de buena manera y he logrado aprender bastante.. Agradecido :-/
Para este caso quiero hacer un timbre automático que se encienda solo a la hora que yo quiera. Investigando di con el ds1307 para poder trabajar con las fechas, pero me tope que utiliza la comunicación de i2C, que en mi poca experiencia programando nunca he trabajo con ella. Como dispongo el pic 16f877a me puse a investigar para poder hacer el i2c en asm, pero aun no he logrado entender muy bien como configurar y arrancar esta comunicacion.
Ya he buscado bastante en google y en el buscador del foro y no encuentro una buena explicacion ( muchas son en ingles y no lo manejo mucho) sobre como hacer la comunicacion. Espero que alguien me pueda ayudar con algún manual, explicación o código explicativo para analizar y asi poder culminar mi proyecto.
Espero que me puedan ayudar y gracias de antemano.. Espero poder culminar este proyecto y así compartirlo..
-
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
-
Gracias por la ayuda perdon por no responder es que ando trabajando en ese codigo, pero estoy bastante enrredado es primera vez que trabajo con el i2c y este ds1307
una pregunta tonta.. cuando configuro en rtc, para escribir en el los los segundos, minutos y eso tengo que enviarselos en binario y cuando los leo estan en bcd???... o yo le envio bcd(pic) y el me envia bcd(ds1307).. ???????
tengo ya bastantes dias leyendo tus codigos y varios del foro como un post de BrunoF que me ah aclarado bastante cosas.. pero aun no concluyo mi código con lo que quiero
Mi programa consiste en configurar un ds1307 con un pic16f877a, configuro la hora actual por medio de programacion... sin lcd ni teclado ni nada... teniendo el pic ubicado en el tiempo.. hora actual dia mes año dia y todo eso... quiero hacer unas alarmas para encender un timbre escolar... el timbre lograra encenderse por lo menos 5 segundos.. esta se ubicara en el puerto C,1. Este se encender todo el año.. menos los dias sabado y domingo y en el mes de agosto que es seguro que el colegio esta de vacaciones.. por que el inicio y final de clases varia cada año asi que pense que cuando se fuera de vacaciones solo desconectaran el pic y que siga trabajando el ds1307, y cuando regresen conecten el pic(por medio de un switc) y asi pueda encender el timbre normal mente...
El led que coloque es para checar a cada rato si el reloj esta activo(funcionando) si no esta el led en portc,0 encenderá, por si deja de funcionar la cosa.. se que es el ds1307.
Tambien mi duda es como hacer para cuando enciendan el pic saber si el reloj ya esta trabajando(ya configurado) por que si hay un apagon el pic configurara una hora que no es... bueno les adjunto mi codigo que es lo que llevo y el circuito en proteus. Espero algunas recomendaciones que puedan ayudarme...
Gracias de atemano... agradecere mucho si alguien puede ayudarme....
;******************************************************************************************************************************************
; PRACTICA PARA EL MANEJOY CONFIGURACION DEL I2C UTILIZANDO UN RTC DS1307
;
;
;
;******************************************************************************************************************************************
INCLUDE <P16F877A.INC>
LIST P=16F877A
__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BOREN_ON & _LVP_OFF
ERRORLEVEL -302
;REDIFINICION DE NOMBRE
#DEFINE PUERTO_A PORTA
#DEFINE PUERTO_B PORTB
#DEFINE PUERTO_C PORTC
R_SEGUNDOS EQU 0X00 ;POSICIÓN 0X00 DE LA MEMORIA DEL 1307
R_MINUTOS EQU 0X01 ;POSICIÓN 0X01
R_HORAS EQU 0X02 ;POSICIÓN 0X02
R_DIASEMANA EQU 0X03 ;POSICIÓN 0X03
R_FECHA EQU 0X04 ;POSICIÓN 0X04
R_MES EQU 0X05 ;POSICIÓN 0X05
R_AÑO EQU 0X06 ;POSICIÓN 0X06
R_CONTROL EQU 0X07 ;POSICIÓN 0X07
CBLOCK H'20' ;BLOQUE DE VARIABLES O REGISTROS
D1
D2
D3
CONTADOR
BUFFER ;VARIABLE PARA CARGAR EN EL BUFFER Y ENVIAR Y RECIBIR
CONT_VAR
CONT_D
;VARIABLES PARA EL TIEMPO RTC
SEG
MIN
HORA
DIA
FECHA
MES
AÑO
CH ;BANDERA PARA SABER SI EL RTC ESTA ENCENDIDO O NO
PUNTERO ;VARIABLE PARA EL BARRIDO Y LECTIRA DE LA MEMORIA DEL DS1307
ENDC
ORG H'00'
GOTO COMIENZO
ORG H'100'
COMIENZO CALL PUERTO ;LLAMDA A PUERTO.(TAMBIEN CONFIGURO EL I2C)
CALL CONFIG_I2C ;CONFIGURO Y ENCUENDO I2C
CALL CONFIG_RTC ;RELOJ DESACTIVADO ASI QUE LO VOY A CONFIGURAR CON LA HORA Y FECHA ACTUAL
BUCLE_LEER CALL START ;REINICION LA CONDICION DE INICIO
MOVLW B'11010000' ;CARGO LA DIRECCION DE ESCLAVO MAS EL BIT ESCRIBIR
CALL ENVIAR ;ENVIO LOS DATOS
MOVF PUNTERO,W
CALL ENVIAR ;POSICIONO EL PUNTERO EN EL REGISTRO DESEADO
CALL RESTART ;REINICION LA CONDICION DE INCIO PARA LEER EL REGISTRO
MOVLW B'11010001' ;CARGO LA DIRECCION DE ESCLAVO MAS EL BIT ESCRIBIR
CALL ENVIAR ;ENVIO LOS DATOS
;
CALL RECIBIR ;VOY A LA SUBRUTINA PARA LEER EL REGISTRO
CALL I2C_SENDACK ;ENVIO EL ACK
CALL GUARDAR ;VARIABLE LEIDA
INCF PUNTERO,F ;INCREMENTO EL VALOR DE PUNTERO
MOVLW 0X06 ;W=6
SUBWF PUNTERO,W ;RESTO W=6-PUNTERO
BTFSS STATUS,Z ;
GOTO BUCLE_LEER ;PUNTERO NO AH LLEGO A 6 SIGO LEYENDO LOS REGISTROS
CLRF PUNTERO ;LLEGO A 6 BORRO EL VALOR DE PUNTERO RETOR PARA HACER EL BARRIDO NUEVAMENTE
CALL ALARMA ;VERIFICO SI ES EL DIA Y LA HORA PARA ENCENDER EL TIMBRE
GOTO BUCLE_LEER
TIMBRE BCF PORTC,1 ;ENCIENDO EL TIMBRE
CALL RETARDO ;ESPERO 5 SEGUNDOS
BSF PORTC,1 ;APAGO Y RETORNO
RETURN
ERROR_1 BCF PORTC,0 ;ENCIENDO UN LED PARA INDICAR QUE EL RELOJ NO ESTA TRABAJANDO
NOP
GOTO ERROR_1 ;BUCLE INFINITO
;*****************************************************************************************************************************************
GUARDAR MOVLW 0X00
SUBWF PUNTERO,W
BTFSC STATUS,Z
GOTO SEGUNDOS_1
MOVLW 0X01
SUBWF PUNTERO,W
BTFSC STATUS,Z
GOTO MINUTOS_1
MOVLW 0X02
SUBWF PUNTERO,W
BTFSC STATUS,Z
GOTO HORAS_1
MOVLW 0X03
SUBWF PUNTERO,W
BTFSC STATUS,Z
GOTO DIAS_SEMA
MOVLW 0X04
SUBWF PUNTERO,W
BTFSC STATUS,Z
GOTO DATE_1
MOVLW 0X05
SUBWF PUNTERO,W
BTFSC STATUS,Z
GOTO MESES_1
SEGUNDOS_1 BTFSC BUFFER,7 ;CHEO EL BIT CH PARA VER SI EL RELOJ ESTA ACTIVADO O DESACTIVADO
GOTO ERROR_1
RETURN
MINUTOS_1 MOVF BUFFER,W ;MUEVO EL VALOR DE BUFFER A W
MOVWF MIN ;GUARDO EL VALOR LEIDO DE MINUTOS
RETURN
HORAS_1 MOVF BUFFER,W ;MUEVO EL VALOR DE BUFFER A W
MOVWF HORA ;GUARDO EL VALOR LEIDO DE HORA
RETURN
DIAS_SEMA MOVF BUFFER,W ;MUEVO EL VALOR DE BUFFER A W
MOVWF DIA ;GUARDO EL VALOR LEIDO DE HORA
RETURN
DATE_1 MOVF BUFFER,W ;MUEVO EL VALOR DE BUFFER A W
MOVWF FECHA ;GUARDO EL VALOR LEIDO DEL DIA DEL MES
RETURN
MESES_1 MOVF BUFFER,W ;MUEVO EL VALOR DE BUFFER A W
MOVWF MES ;GUARDO EL VALOR LEIDO DE LOS MESES
RETURN
;*****************************************************************************************************************************************
; BLOQUE DE RUTINAS BLOQUE DE RUTINAS
;*****************************************************************************************************************************************
PUERTO CALL BANCO_1
MOVLW B'00000110' ;PINES DEL PUERTO A Y E COMO DIGITALES
MOVWF ADCON1
CLRW
MOVWF TRISA ;COMO SALIDAS
CALL BANCO_0 ;
CLRF PORTA
CALL BANCO_1
MOVLW 0X00
MOVWF TRISB ;COMO SALIDAS
CALL BANCO_0
CLRF PORTB
CALL BANCO_1
MOVLW B'00011000'
MOVWF TRISC
CALL BANCO_0
MOVLW B'00010000'
MOVWF PORTC
CALL BANCO_1
MOVLW 0X00
MOVWF TRISD
CALL BANCO_0
CLRF PORTD
CALL BANCO_1
MOVLW 0X00
MOVWF TRISE
CALL BANCO_0
CLRF PORTE
RETURN
;******************************************************************************************************************************************
CONFIG_I2C MOVLW B'00011000'
BANKSEL TRISC ;BANCO 1
IORWF TRISC,F
MOVLW B'00001001' ;.9 PARA 100KHZ FOSC= 4 MHZ
MOVWF SSPADD ;
MOVLW B'10000000' ;VELOCIDAD ESTANDAR
MOVWF SSPSTAT
MOVLW B'00101000'
CALL BANCO_0 ;BANCO 0
MOVWF SSPCON
CLRF PIR1
CALL I2C_IDLE
RETURN
;******************************************************************************************************************************************
I2C_IDLE
CALL BANCO_1 ;BANCO 1
BTFSC SSPSTAT,R_W ;ESPERO A QUE SE TERMINE LA TRANSMISION
GOTO $-1
MOVF SSPCON2,W
ANDLW 0X1F
BTFSS STATUS,Z ;
GOTO $-3
BCF STATUS,RP0 ;BANCO 0
RETURN
;******************************************************************************************************************************************
;CONFIGURANDO EL RELOJ
CONFIG_RTC
CALL START ;ENVIO LA CONDICION DE INICIO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_SEGUNDOS ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X00
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW B'0000000' ;CH=0 RELOJ ACTIVADO, SEGUNDOS IGUAL A 00S, PARA QUE COMIENCE EL CONTEO DESDE 0
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
CALL RESTART ;VOY A REINICIAR LA CONDICION DE INICIO PARA MOVER EL PUNTERO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_MINUTOS ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X01
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW B'0000000' ;PARA ESTE CASO MINUTOS 00, ESPECIFICAR LOS MINUTOS EN EL HORARIO ACTUAL
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
CALL RESTART ;VOY A REINICIAR LA CONDICION DE INICIO PARA MOVER EL PUNTERO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA(0)
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_HORAS ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X02
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW B'01001000' ;MODO 12H, AM, 08:00AM PARA ESTE CASO.. ESPECIFICAR LA HORA ACTUAL**
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
CALL RESTART ;VOY A REINICIAR LA CONDICION DE INICIO PARA MOVER EL PUNTERO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA(0)
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_DIASEMANA ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X03
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW B'00000011' ;HOY ES MARTES, D=1 L=2 M=3 M=4 J=5 V=6 S=7
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
CALL RESTART ;VOY A REINICIAR LA CONDICION DE INICIO PARA MOVER EL PUNTERO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA(0)
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_FECHA ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X04
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW B'00001001' ;DIA 9º DEL MES.. ESPECIFICAR MES ACTUAL
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
CALL RESTART ;VOY A REINICIAR LA CONDICION DE INICIO PARA MOVER EL PUNTERO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA(0)
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_MES ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X05
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW B'00001001' ;MES 9.. AGOSTO
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
CALL RESTART ;VOY A REINICIAR LA CONDICION DE INICIO PARA MOVER EL PUNTERO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA(0)
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_AÑO ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X06
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW B'00010100' ;AÑO 2014.. 14
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
CALL RESTART ;VOY A REINICIAR LA CONDICION DE INICIO PARA MOVER EL PUNTERO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA(0)
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_CONTROL ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X07
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW B'10010011' ;OUT=1 SALIDA=0 SQWE=1 OSCILADOR ACTIVADO, RS1=1 RS0=1 OSC 32.768KhZ
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
;PARA DEJAR EL PUNTERO EN LA POSICION 0X00
CALL RESTART ;ENVIO LA CONDICION DE INICIO
MOVLW B'11010000' ;ENVIO LA DIRECCION DE ESCLAVO + EL BIT DE ESCRITURA
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
MOVLW R_SEGUNDOS ;POSICIONO EL PUNTERO DE LA RAM ESCLAVA EN 0X00
CALL ENVIAR ;VOY A LA SUBRUTINA ENVIAR
CALL STOP
GOTO BUCLE_LEER
;******************************************************************************************************************************************
;BANCOS
BANCO_0 BCF STATUS,RP0
BCF STATUS,RP1
RETURN
BANCO_1 BSF STATUS,RP0
BCF STATUS,RP1
RETURN
BANCO_2 BCF STATUS,RP0
BSF STATUS,RP1
RETURN
BANCO_3 BSF STATUS,RP0
BSF STATUS,RP1
RETURN
;******************************************************************************************************************************************
;RUTINA PARA EL I2C
START CALL I2C_IDLE
CALL BANCO_1
BSF SSPCON2,SEN ;INICIO EL ARRANQUE
BTFSC SSPCON2,SEN ;ESPERO SI ESTAN LISTOS
GOTO $-1
;START LISTO
CALL BANCO_0 ;BANCO 0
BTFSS PIR1,SSPIF ;
GOTO $-1
BCF PIR1,SSPIF
RETURN
;******************************************************************************************************************************************
RESTART CALL BANCO_1 ;BANCO 1
BSF SSPCON2,RSEN
BTFSC SSPCON2,RSEN
GOTO $-1
CALL BANCO_0 ;BANCO 0
RETURN
;******************************************************************************************************************************************
STOP CALL BANCO_1
BSF SSPCON2,PEN ;ENVIAR STOP
BTFSC SSPCON2,PEN
GOTO $-1
CALL BANCO_0
RETURN
;******************************************************************************************************************************************
ENVIAR MOVWF BUFFER ;CARGO LO QUE ESTA EN W A ENVIAR EN DATO
CALL I2C_IDLE
MOVF BUFFER,W ;LO QUE ESTA EN DATO A W PARA CARGARLO EN EL BUFFER
MOVWF SSPBUF ;CARGAR DATO EN BUFFER I2C
CALL BANCO_1 ;BANCO 1
BTFSC SSPSTAT,R_W ;ESPERAR A QUE TERMINE EL ENVIO
GOTO $-1
BTFSS SSPCON2,ACKSTAT ;CHECKEAR ACK
GOTO OKACK
;ERROR
;BSF SSPCON2,PEN ;ERROR ACK. ENVIAR STOP
;BCF STATUS,RP0 ;BANCO 0
RETURN ;VOLVER CON ERROR
OKACK CALL BANCO_0 ;BANCO 0
BTFSS PIR1,SSPIF ;ESPERAR FINALIZACION DEL NOVENO CLOCK
GOTO $-1
BCF PIR1,SSPIF
RETURN
;******************************************************************************************************************************************
RECIBIR CALL I2C_IDLE
CALL BANCO_1 ;BANCO 1
BSF SSPCON2,RCEN ;ACTIVAR MODO LECTURA
BTFSC SSPCON2,RCEN ;TERMINO LA RECEPCION?
GOTO $-1 ;NO, ESPERAR
BTFSS SSPSTAT,BF ;DATO DISPONIBLE EN SSPBUF PARA SER LEIDOS?
GOTO $-1 ;NO, ESPERAR
CALL BANCO_0 ;BANCO 0
MOVF SSPBUF,W
MOVWF BUFFER ;CARGO LO QUE LLEGO EN MI VARIABLE
RETURN
;******************************************************************************************************************************************
I2C_SENDACK
BSF STATUS,RP0 ;BANCO 1
BCF SSPCON2,ACKDT
BSF SSPCON2,ACKEN
BCF STATUS,RP0 ;BANCO 0
RETURN
;******************************************************************************************************************************************
I2C_SENDNACK
BSF STATUS,RP0 ;BANCO 1
BSF SSPCON2,ACKDT
BSF SSPCON2,ACKEN
BCF STATUS,RP0 ;BANCO 0
RETURN
;******************************************************************************************************************************************
ALARMA MOVLW B'00001000' ;VERIFICO SI ES AGOSTO
SUBWF MES,W
BTFSC STATUS,Z
RETURN
CHEQUEO_S_D MOVLW B'000000001' ;COMPUEBO SI ES DOMINGO.. DOMINGO =1
SUBWF DIA,W ;
BTFSC STATUS,Z ;COMPRUEBO EL Z
RETURN
MOVLW B'00000111' ;COMPUEBO SI ES SABADO... SABADO=7
SUBWF DIA,W ;
BTFSC STATUS,Z ;COMPRUEBO EL Z
RETURN
;AHORA CHEQUELO LA HORA POR QUE SE QUE NO ES DOMINGO NI SABADO
MOVLW B'01001000' ;CHEQUEO SI SON LAS 8:00 AM
SUBWF HORA,W ;COPRUEBO SI ES LA HORA CORRECTA 8:00 AM
BTFSS STATUS,Z
GOTO LAS10 ;VOY A COMPROBAR SI SON LAS 10 AM****************
MOVLW 0X00 ;
SUBWF MIN,W ;COMPRUEBO SI SON LAS 8 CON 0 MINUTOS
BTFSC STATUS,Z
GOTO TIMBRE ;SI SON LAS 8:AM ENCIENDO EL TIMBRE
LAS10 MOVLW B'01010000' ;CHEQUEO SI SON LAS 10:00 AM ... (BCD)
SUBWF HORA,W ;COPRUEBO SI ES LA HORA CORRECTA 10:00 AM
BTFSS STATUS,Z
GOTO LAS4 ;VOY A COMPROBAR SI SON LAS 4PM****************
MOVLW 0X00 ;
SUBWF MIN,W ;COMPRUEBO SI SON LAS 10 CON 0 MINUTOS
BTFSC STATUS,Z
GOTO TIMBRE ;SI SON LAS 10:AM ENCIENDO EL TIMBRE
LAS4 MOVLW B'01100100' ;CHEQUEO SI SON LAS 4:00 PM
SUBWF HORA,W ;COPRUEBO SI ES LA HORA CORRECTA 4:00 PM
BTFSS STATUS,Z
RETURN ;NO HAY MAS HORAS EN EL DIA QUE TENGA QUE ENCENDER
MOVLW 0X00 ;
SUBWF MIN,W ;COMPRUEBO SI SON LAS 4 CON 0 MINUTOS
BTFSC STATUS,Z
GOTO TIMBRE ;SI SON LAS 4:PM ENCIENDO EL TIMBRE
RETURN
;******************************************************************************************************************************************
RETARDO MOVLW 0X2D ;RETARDO DE 5 SEGUNDOS
MOVWF D1
MOVLW 0XE7
MOVWF D2
MOVLW 0X0B
MOVWF D3
DELAY_0
DECFSZ D1, F
GOTO $+2
DECFSZ D2, F
GOTO $+2
DECFSZ D3, F
GOTO DELAY_0
RETURN
;******************************************************************************************************************************************
END
-
hola JOSEMP.ya hace tiempo que no menejo este chip.y no me acuerdo de todo.pero que yo sepa,se escribe y lee en BCD.
en mi codigo hay varias rutinas que lo utilizan.aunque este codigo funcionaba conjuntamente con un programa en LabView.el cual necesitaba de estas
correcciones para poder visualizar los datos.y hacia falta pasar de BCD a bin.