Hola a todos.
Tengo el siguiente problema:
Quiero leer los datos de una eeprom (24LC512) y almacenarlos en el pic (16F876) a traves del i2c.
La rutina para escribir_i2c la tengo y funciona bien. La de lectura es la siguiente(debe leer de la direccion 0005 y guardar el byte en dato1)
Creo que el problema debe ser del restart. Lo estoy simulando en Proteus, igual está ahi el problema.
#define control_in_eeprom 0xA0
#define control_out_eeprom 0xA1
#define baud D"100"
#define fosc D"4000"
org 0x0000
goto inicio
org 0x0004
int:nop
retfie
inicio:
;Inicializo I2C
bsf status, rp0 ; banco 1
movlw b"00011000" ; RC3, RC4 son entradas
movwf trisc
bcf status, rp0
movlw b"00101000" ; habilito mssp
; habilito sspen y el modo i2c Master sspm
movwf sspcon
bsf status, rp0
movlw B"10000000" ; smp configurado a 100 KHz
movwf sspstat
bcf status, rp0
; configuro el baud rate
bsf status, rp0
movlw (fosc / (4 * baud)) - 1
movwf sspadd
bcf status, rp0 ; Fin de la configuracion del i2c
I2CRead:
; Send RESTART condition and wait for it to complete
bsf status, rp0
bsf sspcon2, rsen ; Generate RESTART Condition
bcf status, rp0
call WaitMSSP ; Wait for I2C operation to complete
; Send and Check CONTROL BYTE, wait for it to complete
movlw control_in_eeprom ; Load CONTROL BYTE (input mode)
call Send_I2C_Byte ; Send Byte
call WaitMSSP ; Wait for I2C operation to complete
bsf status, rp0
btfsc sspcon2, ackstat ; Check ACK Status bit to see if I2C
goto I2CFail ; failed, skipped if successful
; Send and Check ADDRESS BYTE, wait for it to complete
bcf status, rp0
movlw 0x00 ; Load Address Byte
call Send_I2C_Byte ; Send Byte
call WaitMSSP ; Wait for I2C operation to complete
bsf status, rp0
btfsc sspcon2, ackstat ; Check ACK Status bit to see if I2C
goto I2CFail ; failed, skipped if successful
bcf status, rp0
movlw 0x05 ; Load Address Byte
call Send_I2C_Byte ; Send Byte
call WaitMSSP ; Wait for I2C operation to complete
bsf status, rp0
btfsc sspcon2, ackstat ; Check ACK Status bit to see if I2C
goto I2CFail ; failed, skipped if successful
; Send and Check DATA BYTE, wait for it to complete
; Send RESTART condition and wait for it to complete
bsf status, rp0
bsf sspcon2, rsen ; Generate RESTART Condition
bcf status, rp0
call WaitMSSP ; Wait for I2C operation to complete
bsf status, rp0
btfsc sspcon2, ackstat ; Check ACK Status bit to see if I2C
goto I2CFail ; failed, skipped if successful
bsf status, rp0
movlw control_in_eeprom
call Send_I2C_Byte
call WaitMSSP
bsf status, rp0
btfsc sspcon2, ackstat
goto I2CFail
bcf status, rp0
; Get the DATA BYTE and wait for it to complete. Data is in SSPBUF when done.
bcf status, rp0
call WaitMSSP ; Wait for I2C operation to complete
; Send NACK bit for Acknowledge Sequence
bsf status, rp0
bsf sspcon2, ackdt ; ACK DATA to send is 1, which is NACK.
bsf sspcon2, acken ; Send ACK DATA now.
bsf sspcon2, pen ; Send STOP condition
bcf status, rp0
call WaitMSSP ; Wait for I2C operation to complete
movf sspbuf, w ; Get data from SSPBUF into W register
movwf dato1
mandar_direcc: ; Mandar la direccion
movf fin_eeprom_h, w ;Mando la parte alta de la direccion
call Send_I2C_Byte
call WaitMSSP
bsf status, rp0
btfsc sspcon2, ackstat ;Chequeo el ack
goto I2CFail
bcf status, rp0
movf fin_eeprom_l, w ;Mando la parte baja de la direccion
call Send_I2C_Byte
call WaitMSSP
bsf status, rp0
btfsc sspcon2, ackstat ;Chequeo el ack
goto I2CFail
bcf status, rp0
return
I2CFail:
bcf status, rp0
nop
retlw 0
i2c_write:
call Send_I2C_Byte ; Mando byte
call WaitMSSP ;Espero a que la operacion i2c termine
bsf status, rp0
btfsc sspcon2, ackstat ;Chequeo el ack
goto I2CFail ; Si falla
bcf status, rp0 ;Si es correcto, incremento las dirrecciones para la proxima escritura
incfsz fin_eeprom_l
return
incfsz fin_eeprom_h
return
Send_I2C_Byte:
movwf sspbuf ; coge el valor a mandar del acumulador y lo almacena en el sspbuf
retlw 0
WaitMSSP:
;Para ver si una operacion i2c esta terminada miro la bandera sspif del pir1
btfss pir1, sspif
goto $-1 ;no ha finalizado
bcf pir1, sspif ; comunicacion acabada
retlw 0