Hola a todos:
Tengo un problemilla con la conexión i2c de la memoria externa (24lc02b) y el pic16f873. Estoy haciendo un proyecto y lo que quiero es guardar una serie de muestras en la EEPROM y poder verlas en la LCD para saber si lo estoy haciendo correctamente. Cuando guardo dos datos en la memoria, lo conecto mediante i2c al pic, y esos datos se ven perfectamente en la pantalla de la LCD. Pero cuando intento guardar más de dos datos, no lo consigo. No se si lo que hago es escribir mal en la EEPROM o leerla mal. ¿Alguien me podría ayudar?
Muchas gracias.
Aquí os pongo el programa en el que consigo guardar dos valores y se ve en la LCD correctamente, por si me podríais decir que cambios necesito hacer para guardar una serie de ellos y visualizarlos:
List p=16F873 ;Tipo de procesador
include "P16F873.INC" ;Definiciones de registros internos
Temporal equ 0x20 ;Temporal de propósito general
Minutos equ 0x21 ;Variable de minutos.
Horas equ 0x22 ;Variable de horas.
Delay equ 0x23 ;Temporal de temporización
DP_Status equ 0x24 ;Flag de estado del punto decimal del segundero
ACK equ 0x25 ;Flag de enviar o no NACK
Temp_1 equ 0x26
Lcd_var equ 0x27
org 0x00 ;Vector de Reset
goto Inicio
org 0x05 ;Salva el vector de interrupción
;********************************************************************************************
;Leer_Clock: Lee desde el dispositivo PCF8583 los minutos y las horas
;
Leer_EEPROM call Send_Start ;Envía secuencia de inicio
movlw b'10100010' ;Modo escritura
call Send_Byte ;Dirección del dispositivo PCF8583 en la PLUS
movlw .1
call Send_Byte ;Dirección interna a leer (la 3, minutos)
call Send_Stop
call Send_Start ;Envía secuencia de inicio
movlw b'10100011' ;Modo lectura
call Send_Byte ;Dirección del dispositivo PCF8583 en la PLUS
bcf ACK,0 ;Enviar ACK tras la lectura del byte
call Read_Byte ;Lee el byte de minutos
movwf Minutos
bsf ACK,0 ;Enviar NACK trás la lectura del byte
call Read_Byte ;Lee el byte de horas (dirección interna 4)
movwf Horas
call Send_Stop ;Envía secuencia de Stop
return
;********************************************************************************************
;Esc_Clock: Escribe el contenido de las variables Minutos y Horas sobre las posiciones 3 y 4
;del dispositivo PCF8583. De esta forma se ajusta a una nueva hora.
;
Esc_EEPROM call Send_Start ;Envía secuencia de inicio
movlw b'10100010' ;Modo escritura
call Send_Byte ;Dirección del dispositivo PCF8583 en la PLUS
movlw .1
call Send_Byte ;Direcciona posición interna 3 (minutos)
movf Minutos,W
call Send_Byte ;Escribe los minutos
movf Horas,W
call Send_Byte ;Escribe las horas
call Send_Stop ;Envía secuencia de stop
return
;********************************************************************************************
;Visualiza: Recoge el valor actual de las variables Horas y Minutos, desempaqueta en dígitos
;individuales, convierte a ASCII y lo envia a la LCD.
include "LCD_SCHOOL_CXX.inc"
Visualiza clrf PORTB
bsf STATUS,RP0
clrf TRISB
movlw 0x06
movwf ADCON1
movlw b'00010001'
movwf TRISA
bcf STATUS, RP0
call UP_LCD
call LCD_INI
movlw 0x0F
call LCD_REG
movlw 'E'
call LCD_DATO
movlw 'E'
call LCD_DATO
movlw 'P'
call LCD_DATO
movlw 'R'
call LCD_DATO
movlw 'O'
call LCD_DATO
movlw 'M'
call LCD_DATO
movlw '1'
call LCD_DATO
movlw ':'
call LCD_DATO
movf Minutos,0 ; Horas -> W.
call LCD_DATO
bcf PORTA,1
bcf PORTA,2
movlw b'11000000' ; Cambia de línea.
call LCD_REG
movlw 'E'
call LCD_DATO
movlw 'E'
call LCD_DATO
movlw 'P'
call LCD_DATO
movlw 'R'
call LCD_DATO
movlw 'O'
call LCD_DATO
movlw 'M'
call LCD_DATO
movlw '2'
call LCD_DATO
movlw ':'
call LCD_DATO
movf Horas,0 ; Minutos -> W.
call LCD_DATO
return
;*******************************************************************************************
;Send_Start: Envía la condición de inicio
Send_Start bcf PIR1,SSPIF ;Restaura el flag del módulo MSSP
bsf STATUS,RP0 ;Seleciona página 1
bsf SSPCON2,SEN ;Activa secuencia de inicio
bcf STATUS,RP0
Start_Wait btfss PIR1,SSPIF ;Fin de secuencia de inicio ??
goto Start_Wait ;No, esperar
return
;*******************************************************************************************
;Send_Stop: Envía la secuencia de stop
Send_Stop bcf PIR1,SSPIF ;Restaura el flag del módulo MSSP
bsf STATUS,RP0 ;Seleciona página 1
bsf SSPCON2,PEN ;Activa secuencia de stop
bcf STATUS,RP0
Stop_Wait btfss PIR1,SSPIF ;Fin de secuencia de Stop ??
goto Stop_Wait ;No, esperar
return
;*******************************************************************************************
;Send_Byte: Transmite el byte del W vía I2C. La rutina finaliza cuando se recibe /ACK
Send_Byte bcf PIR1,SSPIF ;Restaura el flag del módulo MSSP
movwf SSPBUF ;Byte a transmitir pasa al buffer de salida
Send_Byte_Wait btfss PIR1,SSPIF ;Recibido el bit /ACK ??
goto Send_Byte_Wait ;No, esperar
return
;*******************************************************************************************
;Read_Byte: Lee un byte procedente del dispositivo I2C selecionado y lo devuelve en W
;Seguidamente se genera y transmite el bit /ACK
Read_Byte bcf PIR1,SSPIF ;Restaura el flag del módulo MSSP
bsf STATUS,RP0 ;Selecciona página 1
bsf SSPCON2,RCEN ;Activa el modo receptor
bcf STATUS,RP0 ;Selecciona página 0
Read_Wait btfss PIR1,SSPIF ;Recibidos los 8 bits ??
goto Read_Wait ;No, esperar
bcf PIR1,SSPIF ;Restaura el flag del módulo MSSP
btfsc ACK,0 ;Enviar ACK ??
goto No_ACK ;No, enviar NACK
bsf STATUS,RP0 ;Si, selecciona página 1
bcf SSPCON2,ACKDT ;Pone bit ACK a "0"
bsf SSPCON2,ACKEN ;Aciva la secuencia de generación del bit ACK
bcf STATUS,RP0 ;Selecciona página 0
ACK_Wait btfss PIR1,SSPIF ;Secuencia ACK finalizada ??
goto ACK_Wait ;No, esperar
movf SSPBUF,W ;Lee el byte recibido
return
;Algunos dispositivos precisan que el master envíe un NACK tras recibir el último byte
No_ACK bsf STATUS,RP0 ;Selecciona página 1
bsf SSPCON2,ACKDT ;Pone bit ACK a "1"
bsf SSPCON2,ACKEN ;Aciva la secuencia de generación del bit NACK
bcf STATUS,RP0 ;Selecciona página 0
NACK_Wait btfss PIR1,SSPIF ;Secuencia NACK finalizada ??
goto NACK_Wait ;No, esperar
movf SSPBUF,W ;Lee el byte recibido
return
;*******************************************************************************************
;Programa principal
Inicio clrwdt
clrf PORTA
clrf PORTC
bsf STATUS,RP0 ;Selecciona banco 1
movlw b'00000110'
movwf ADCON1 ;Puerta A DIGITAL
movlw b'11111111'
movwf TRISA ;RA0 y RA1 entradas digitales
movwf TRISC ;RC3/SCL y RC4/SDA entradas
movlw b'11000111'
movwf OPTION_REG ;Preescaler de 256 asociado al TMR0
movlw b'10000000'
movwf SSPSTAT ;Velocidad estándar con niveles I2C
movlw .9
movwf SSPADD ;Velocidad del bus I2C 100KHz
bcf STATUS,RP0 ;Selecciona banco 0
;Módulo MSSP en el modo Master I2C
movlw b'00101000'
movwf SSPCON ;Módulo MSSP en On
clrf ACK
movlw 0x40
movwf Horas
movlw 0x2A
movwf Minutos
call Esc_EEPROM
clrf Horas
clrf Minutos
Loop clrwdt
call Leer_EEPROM ;Lee hora actual
call Visualiza ;Visualiza la hora actual
goto Loop ;No
end ;Fin del programa fuente