Problem in reading the data from EEPROM with I2C interfaced PIC

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

       I have seen a topic regarding problem in reading the EEPROM
communicating with a PIC through I2C.
       I am trying for the same communication. I am writing a byte to
one of the locations of EEPROM and then after a delay, I am reading
from the same location and outputing the same data to PORTB of my
PIC16F873A. The problem I am facing is that the data is different each
time. i.e. it is not the same one I am sending..
       Here is my code. Please comment on the same.
       Thank you!


    include ""
    errorlevel -302

;    Macro definition

movlf    macro    literal,register
        movlw    literal
        movwf    register

;    equates

SDA            equ        4    ;I2C serial data bit of PORTC
SCL            equ        3    ;I2C serial clock bit of PORTC
Check        equ        1    ;check bit
SLAVEADD    equ        B'10100000' ;h'AO'
INTERNADD    equ        B'11110000'    ;h'f0'
INFO        equ        B'11110000'    ;h'f0'
;TRISC        equ        h'87'

;    variables

    cblock        H'20'
    DEVADD            ;Devices I2C address X2
    INTADD            ;Internal address
    Checkack        ;Check for the acknowledge bitt
    DATAOUT            ;Data to be written into the INTADD during ta write
    DATAIN            ;Data to be readfrom the INTADD during a read
    TXBUFF            ;Buffer for each byte sent by TX
    RXBUFF            ;Buffer for each byte received by RX

;I2Cout    Subroutine transfers out 3 bytes: DEVADD,INTADD, DATAOUT


    call    Start        ;Generate start condition
    movlf    SLAVEADD,DEVADD
    movf    DEVADD,W    ;Send peripheral address with R/W=0 (write)
    call    TX
    movwf    Checkack
    btfss    Checkack,0
    goto     Start1                ; if not acknowledged, send the address again

    call     ReStart
    movf    INTADD,W    ;Send peripheral's internal address
    call    TX
    movwf    Checkack
    btfss    Checkack,0
    goto     Start2

    call     ReStart
    movlf    INFO,DATAOUT
    movf    DATAOUT,W    ;send data to write to peripheral
    call    TX
    movwf    Checkack
    btfss    Checkack,0
    goto     Start3
    call    Stop        ;Generate Stop condition
    call    Wait        ;Puase while the EEPROM sends the data

;The I2Cin subroutine transfers out DEVADD (with R/W=0) and
;tranfers out DEVADD (with R/W=1) and reads one byte back into DATAIN.


    call    Start        ;Generate START condition
    movlf    SLAVEADD,DEVADD
    movf    DEVADD,W    ;send Peripherals address with R/W=0 (write)
    call    TX
    movwf    Checkack
    btfss    Checkack,0
    goto     Start11

    call     ReStart
    movf     INTADD,W    ;Send peripheral's internal address
    call    TX
    movwf    Checkack
    btfss    Checkack,0
    goto     Start21

    call    ReStart        ;ReStart
    movlf    SLAVEADD,DEVADD
    movf    DEVADD,W    ;send Peripherals address
    iorlw    B'00000001'    ;with R/W=1(read)
    call    TX
    movwf    Checkack
    btfss    Checkack,0
    goto     Start31
    bsf        TXBUFF,7    ;NOACK the following read of one byte
    call    RX            ;Read byte
    movwf    DATAIN        ;into DATAIN
    movf    DATAIN,PORTB        ;Send the data to check on the PORTB
    movlw    INFO        ;Recheck the data with the data sent
    subwf    INFO,w
    btfss    STATUS,Z    ;If the data received is different, switch off the LED
at RC2
    bsf        INDF,Check
    call    Stop        ;Generate Stop condition

    goto    noend        ;endless loop

;The Start subroutine initializes the I2C bus and then generate the
;condition on the I2C bus.
;The ReStart entry point bypasses the initializes of the I2C bus.

    movlw    TRISB
    movwf    FSR
    clrf    INDF
    movlw    TRISC
    movwf    FSR
    clrf    INDF
    bcf        INDF,SDA    ;Drive SDA low when it is an o/p
    bcf        INDF,SCL    ;Drive SDL low when it is an o/p
    movlw    B'00111011'    ;Enable I2C master mode
    movwf    SSPCON

    bsf        INDF,SDA    ;Make sure SDA is high
    bsf        INDF,SCL    ;Make sure SCL is high
    bcf        INDF,SDA
    bcf        INDF,SCL

;The Stop subroutine generates the STOP condition on the I2C bus

    bcf        INDF,SDA    ;Return SDA low
    bsf        INDF,SCL    ;Drive SCL high
    bsf        INDF,SDA    ;then drive SDA high

;The Tx subroutine sends out the byte passed to it in W.
;It returns with z=1 if ACK occurs
;It returns with z=0 if NOACK occurs.

    movwf    TXBUFF        ;Save parameter in TXBUFF
    bsf        STATUS,C    ;Rotate a one through TXBUFF to count bits

    rlf        TXBUFF,F    ;rotate TXBUFF left,through carry
    movf    TXBUFF,F    ;set z bit when all eight bits have been transfered
    btfss    STATUS,Z    ;Until z=1
    call    BitOut        ;send carry bit, then clear carry bit
    btfss    STATUS,Z
    goto    TX_1        ;then do it again
    call    BitIn        ;Read acknowledge bit into bit 0 of RXBUFF
    movlw    B'00000001'    ;check acknowldge bit
    andwf    RXBUFF,W    ;z=1 if ACK; Z=0 if NOACK

;The RX subroutine receives a byte form the I2C bus into W,using RXBUFF
;call RX with bit 7 of TXBUFF clear for ACK.
;call RX with bit 7 of TXBUFF set for NOACK.

    movlw    B'00000001'    ;Rotate a one through RXBUFF to the carry bit to
count bits
    movwf    RXBUFF

    rlf        RXBUFF,F    ;shift previous bits left
    call    BitIn         ;Read a bit from SDA into bit 0 of RXBUFF
    btfss    STATUS,C    ;C=1 yet
    goto     RX_1        ;No,do it again
    rlf        TXBUFF,F    ;Move bit 7 of TXBUFF to carry bit
    call    BitIn        ;and from there to SDA as acknowledgment
    movf    RXBUFF,W    ;Put received byte into W

;The BitOut subroutine transmits,then clears,the carry bit

    bcf        INDF,SDA    ;copy carry bit to SDA
    btfsc    STATUS,C    ;if C=1,make SDA=1
    bsf        INDF,SDA
    bsf        INDF,SCL    ;pulse clock line
    bcf        INDF,SCL
    bcf        STATUS,C    ;Clear Carry bit

;The BitIn subroutine receives one bit into bit 0 of RXBUFF

    bsf        INDF,SDA    ;Release SDA line
    bsf        INDF,SCL    ;Drive clock line high
    btfsc    PORTC,SDA
    bsf        RXBUFF,0
    bcf        INDF,SCL    ;Drive clock line low again

    movlw    H'80'        ; wait for 66ms
    movwf    COUNT2
    movlw    H'FF'
    movwf    COUNT1
    decfsz    COUNT1,F
    goto    Again3
    decfsz    COUNT2,F
    goto     Again4

Site Timeline