Hola de nuevo.
Bueno después de un día completo de leer la teoría de I2C, el datasheet de la 24LC256, y el código ejemplo de BrunoF, me lancé hacer el código para implementarlo en este pasamensajes, inicialmente programe con código ascii los primeros bytes, con el PIckitV2 el programa, luego implementé la rutina para que fueran leídos aleatoriamente por el uC tal y como muestra la sigueinte imagen del datasheet de la 24LC256:
Entonces hice lo siguiente:
1. llamo la rutina del Bit Start
2. cargo el registro I2C_data con la configuración, en mi caso sería "10100000" como el acceso es aleatorio el último bit debe ser 0
3. Envío el dato por el puerto I2C
4. Luego el ACK
5. Envío la Dirección alta de la memoria, en mi caso hice un CLRF Haddeeprom
6. Luego de enviar hago un ACK con SENDACK
7. Repito pasos 5 y 6 para la direccion baja de la memoria osea hago un CLRF Laddeeprom y envío
7. Vuelvo y envío el BIT DE START
8. Envió el byte de control pero el primer bit está en 1 osea "10100001"
9. Envío ese byte por el puerto serial
10. Luego ACK
11. Recibo el dato
12. Y doy el bit de stop.
13. El byte leído lo grabo en un registro buffer y lo llevo a la pantalla
me guié por la imagen que está en el datasheet.
Se supone que debería mostrarme el caracter del hexadecimal que está en la eeprom, pero se me queda bloqueado el PIC, si lo reinicio me muestra otra cosa, o pasan cosas raras en los leds, como el programa no esta depurado pues ya voy por encima de las 2K de memoria por eso he usado PAGESELW para evitar porblemas con el PClath, pero no se si debo hacerlo asi o de otra forma..o si el problema está en el modo de usar el I2C por que si pongo el buffer con un valor constante y me salto los pasos para la lectura de la memoria I2C me muestra el caracter bien...
Este es el bloque donde hago los pasos para leer aleatoriamente los datos de la memoria 24LC256
LEER_EEPROM
CLRF HADDEEPROM
CLRF LADDEEPROM
LOOP_EE
CLRF IC2DATA ;BUFFER 1
CLRF PALABRA ;BUFFER 2 QUE ES EL LEE LA RUTINA DE PANTALLA
PAGESELW CONFIG_TRANSMISION_I2C
CALL CONFIG_TRANSMISION_I2C
PAGESELW BIT_START_I2C
CALL BIT_START_I2C
MOVLW B'10100000' ;BYTE CONTROL
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW I2C_SENDACK
CALL I2C_SENDACK
MOVF HADDEEPROM,W ;DIRECCION ALTA
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW I2C_SENDACK
CALL I2C_SENDACK
MOVF LADDEEPROM,W
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW I2C_SENDACK
CALL I2C_SENDACK
PAGESELW RESTART_I2C
CALL RESTART_I2C
PAGESELW BIT_START_I2C
CALL BIT_START_I2C
MOVLW B'10100001' ;ENVÍO EL CONTROL BYTE PERO CON 1
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW I2C_SENDACK
CALL I2C_SENDACK
PAGESELW RECIBIR_DATO_I2C
CALL RECIBIR_DATO_I2C
PAGESELW BIT_STOP_I2C
CALL BIT_STOP_I2C
MOVF IC2DATA,W
;MOVLW .65 ;para hacer pruebas retiro el ";" y funciona bien
MOVWF PALABRA ;con el valor constante .65
MOVLW .32 ;esta resta es para la tabla con los hex en ascii
SUBWF PALABRA,F
NOP
PAGESELW SIGUIENTE_FASE
CALL SIGUIENTE_FASE ;siguiente fase es el bloque donde muestro PALABRA en pantalla
PAGESELW ESPACIOS_BLANCO
CALL ESPACIOS_BLANCO ;luego de mostrar la letra A le sumo espacios en blanco a la derecha
GOTO LEER_EEPROM
INCLUDE I2C.INC
Y este es el I2C.INC
CONFIG_TRANSMISION_I2C
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF TRISC,4
BSF TRISC,3
MOVLW .2
MOVWF SSPADD ; CARGAS 02H EN EL REGISTRO SSPADD LA VELOCIDAD DE
CLRF SSPSTAT ;TRANSMISION SERA DE 333 KHZ con 4MHZ en el X-tal
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
MOVLW B'00101000'
MOVWF SSPCON ; PERMITES LA CONFIGURACION SERIE DE LOS PINES SDA Y SCL.
CLRF PIR1
PAGESELW I2C_IDLE
CALL I2C_IDLE
RETURN
BIT_START_I2C
PAGESELW I2C_IDLE
CALL I2C_IDLE
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF SSPCON2,SEN
BTFSC SSPCON2,SEN
GOTO $-1 ; LANZAMOS EL BIT DE START.
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
BTFSS PIR1,SSPIF
GOTO $-1
BCF PIR1,SSPIF
RETURN
TRANSMITIR_DATO_I2C
MOVWF IC2DATA
BCF FLAGEE,0
;PAGESELW I2C_IDLE
CALL I2C_IDLE
MOVF IC2DATA,W
MOVWF SSPBUF ; TRANSMITIMOS EL DATO AL ESCLAVO
BSF STATUS,RP0 ;BANCO 1
BTFSC SSPSTAT,R_W ;ESPERAR A QUE TERMINE EL ENVIO
GOTO $-1
BTFSS SSPCON2,ACKSTAT ;CHECKEAR ACK
GOTO OKACK
BSF SSPCON2,PEN ;ERROR ACK. ENVIAR STOP
BCF STATUS,RP0 ;BANCO 0
RETURN ;VOLVER CON FLAG= 0 ERROR
OKACK
BCF STATUS,RP0 ;BANCO 0
BTFSS PIR1,SSPIF ;ESPERAR FINALIZACION DEL NOVENO CLOCK
GOTO $-1
BCF PIR1,SSPIF
BSF FLAGEE,0
RETURN
RECIBIR_DATO_I2C
PAGESELW I2C_IDLE
CALL I2C_IDLE
BCF PIR1,SSPIF
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF SSPCON2,RCEN
BTFSC SSPCON2,RCEN
GOTO $-1
BTFSS SSPSTAT,BF ;PERMITO LA RECEPCION DE DATOS
GOTO $-1
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
MOVF SSPBUF,W
MOVWF IC2DATA
RETURN
BIT_STOP_I2C
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF SSPCON2,PEN
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
RETURN
RESTART_I2C
BSF STATUS,RP0
BSF SSPCON2,RSEN
BTFSC SSPCON2,RSEN
GOTO $-1
BCF STATUS,RP0
VOLVER
RETURN
I2C_IDLE
BSF STATUS,RP0 ;BANCO 1
BTFSC SSPSTAT,R_W
GOTO $-1
MOVF SSPCON2,W
ANDLW 0X1F
BTFSS STATUS,Z
GOTO $-3
BCF STATUS,RP0 ;BANCO 0
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
La verdad es que ahora estoy muy agotado, y mi cabeza no quiere analizar muy bien en donde tengo el error, por eso recurro a los más expertos y me den una pista de ver que hago mal....una última cosita, estas lineas están por encima de las 2k de memoria, por si sirve de ayuda
Bueno muchas gracias y saludos.