Hi there,
        I am currently trying to connect up a 24C16 EEPROM to a 16C74 in a
project I am building. I have been trying to find information on how to
connect up this chip but have had little luck. The only thing I found was
a data sheet on the chip by National Semi.. Judging by the data sheet I
came up with the following connections.





          _________            __________
          |       |            |        |1 A0 NC
          | 74    |     sclk  6|  EE    |2 A1 NC
          |       |18----------|        |3 A2 NC
          |       |            |        |
          |       |     sda   5|        |4 VSS
          |       |23----------|        |
          |       |            |        |5 VDD
          |       |            |        |
          ---------            ----------

A0 |
A1 |----- Device Address inputs  datasheet gives value as X for 24C16
A2 |

VSS - GND
VDD - +5

pin 6 SCL       Clock
pin 5 SDA       Data



The software I am using is the example given with the PICDEM board..
which is supposed to work with 24CXX range ?? My problem is my program
never leaves the errorstate loop.. Its exactly as if my EEPROM isn't
there. Personally I think that it may be the Slave address line in the
code.. But I can find no infomation on how this is calculated! or how I
set my EEPROM to match it ?
        I'm enclosing the entire code( the only change I made is swaping
each reference to PORTB with PORTD. I doubt if that could be the problem??
Anyway my appologies if this code is a bit much to be enclosing but at the
moment I'm getting pretty desperate and I couldn't isolate the problem to
any section of the code. My project deadline is VERY soon..

                                Thanks

                                        David.


The CODE :


        TITLE "I2C interface PIC16C74 to serial EEPROM"
;
                LIST P=16C74, F=INHX8M
;
;*****************************************************************************
;**  Two wire/I2C Bus READ/WRITE Sample Routines of Microchip's
;**  24Cxx / 85Cxx serial CMOS EEPROM interfacing to a
;**  PIC16C74 8-bit CMOS single chip microcomputer
;**  Revised Version  (3/1/94).
;**
;**  Note:  1) All timing is based on a reference crystal frequency of
4MHz
;**            which is equivalent to an instruction cycle time of 1 usec.
;**         2) Address and literal values are read in hexidecimal unless
;**            otherwise specified.
;*****************************************************************************
;
;-----------------------------------------------------------------------------
;       Register File Assignment
;-----------------------------------------------------------------------------
;
        include "picreg.equ"
;
FLAG    equ     20              ; Common flag bits register
EEPROM  equ     21              ; Bit buffer
ERCODE  equ     22              ; Error code (to indicate bus status)
ADDR    equ     23              ; Address register
DATAI   equ     24              ; Stored data input register
DATAO   equ     25              ; Stored data output register
SLAVE   equ     26              ; Device address (1010xxx0)
TXBUF   equ     27              ; TX buffer
RXBUF   equ     28              ; RX buffer
COUNT   equ     29              ; Bit counter
TEMP    equ     2A              ; Temporary storage
TEMP1   equ     2B              ; More Temporary storage
;
;-----------------------------------------------------------------------------
;                     Bit Assignments
;-----------------------------------------------------------------------------
;
; FLAG Bits
;
ERRORFLG EQU     0               ; Error flag
;
; EEPROM Bits
;
DI      EQU     7               ; EEPROM input
DO      EQU     6               ; EEPROM output
;
; I2C Device Bits
;
SDA     EQU     4               ; RB7, data in/out
SCL     EQU     3               ; RB6, serial clock

;------------------------------------------------------------------------------
;                       Vector Assignment
;------------------------------------------------------------------------------

        ORG     00h             ; Reset Vector
        goto    Start
;
        ORG     04h             ; Interrupt Vector
        goto    Service_int     ; Not actually used by this program
;
        ORG     10h             ; Begining of Program space

;------------------------------------------------------------------------------
;                       Main Program
;------------------------------------------------------------------------------
Start
        clrf    FLAG
        clrf    ERCODE
        bsf     STATUS,RP0      ; Select Page 1
        clrf    TRIS_D          ; Set PORT_D as all outputs
        movlw   0FFh            ; Set PORT_C as all inputs
        movwf   TRIS_C
        bcf     STATUS,RP0      ; Select Page 0
        movlw   01h
        movwf   PORT_D          ; Light first LED
        movlw   B'00111011'     ; I2C master mode enabled
        movwf   SSPCON
        movlw   B'00000000'     ; Disable interrupts
        movwf   INTCON
        movlw   B'00000000'     ; Disable all interrupts
        movwf   PIE1
        clrf    PORT_C          ; Set SCL, SDA to low when not in
tri-state
Bigloop
        movf    PORT_D,W
        movwf   DATAO           ; Output Data
        movlw   00h             ; EEPROM data address
        movwf   ADDR
        movlw   B'10100000'     ; EEPROM I2C address
        movwf   SLAVE
Wrtloop
        call    WRBYTE          ; Output byte to EEPROM
        btfsc   FLAG,ERRORFLG   ; Check for error
        goto    Errorloop
        call    Delay           ; 10mS Delay for 24LC01 EEPROM write delay
        incf    ADDR            ; Point to next address
        btfss   ADDR,7          ; Check if at end of EEPROM
        goto    Wrtloop

        bcf     STATUS,RP0      ; Address page 1
        movlw   00h             ; EEPROM data address
        movwf   ADDR
        movlw   B'10100000'     ; EEPROM I2C address
        movwf   SLAVE
Rdloop
        call    RDBYTE          ; Input byte from EEPROM
        btfsc   FLAG,ERRORFLG   ; Check for error
        goto    Errorloop
        movf    DATAI,W         ; Get received byte
        subwf   PORT_D,W        ; Make sure correct data read
        btfss   STATUS,Z
        goto    Errorloop
        incf    ADDR            ; Point to next address
        btfss   ADDR,7          ; Check if at end of EEPROM
        goto    Rdloop
        incf    PORT_D          ; Increment value displayed on LEDs
        goto    Bigloop

Errorloop
        clrf    PORT_D          ; Turn off all LEDs
Errloop1
        call    Delay           ; Delay so that flashing of LEDs
        call    Delay           ;       is apparent
        call    Delay
        call    Delay
        call    Delay
        call    Delay
        comf    PORT_D          ; Change state of all LEDs
        goto    Errloop1

Service_int                     ; Interrupts are not used
        return


;-----------------------------------------------------------------------------
;       BYTE-WRITE, write one byte to EEPROM device
;-----------------------------------------------------------------------------
;       Input   :       DATAO   = data to be written
;                       ADDR    = EEPROM data address
;                       SLAVE   = device address (1010xxx0)
;       Output  :       Data written to EEPROM device
;-----------------------------------------------------------------------------

WRBYTE
        bcf     STATUS,RP0
        movf    SLAVE,W         ; Put SLAVE address
        movwf   TXBUF           ;  in xmit buffer
        call    BSTART          ; Generate START bit
        call    TX              ; Output SLAVE address
        bcf     STATUS,RP0
        movf    ADDR,W          ; Put WORD address
        movwf   TXBUF           ;  in xmit buffer
        call    TX              ; Output WORD address
        bcf     STATUS,RP0
        movf    DATAO,W         ; Move DATA
        movwf   TXBUF           ; into buffer
        call    TX              ; Output DATA and detect acknowledgement
        call    BSTOP           ; Generate STOP bit
        return

;-----------------------------------------------------------------------------
;       TRANSMIT 8 data bits subroutine
;-----------------------------------------------------------------------------
;       Input   :       TXBUF
;       Output  :       Data transmitted to EEPROM device
;-----------------------------------------------------------------------------

TX
        bcf     STATUS,RP0
        movlw   .8              ; Set counter for eight bits
        movwf   COUNT

TXLP
        bcf     EEPROM,DO       ; Default 0 bit out
        btfsc   TXBUF,7         ; If shifted bit = 0, data bit = 0
        bsf     EEPROM,DO       ;  otherwise data bit = 1
        call    BITOUT          ; Send bit
        bcf     STATUS,RP0
        rlf     TXBUF           ; Rotate TXBUF left
        skpc                    ; f(6) ---> f(7)
        bcf     TXBUF,0         ; f(7) ---> carry
        skpnc                   ; carry ---> f(0)
        bsf     TXBUF,0
        decfsz  COUNT           ; 8 bits done?
        goto    TXLP            ; No.
        call    BITIN           ; Read acknowledge bit
        bcf     STATUS,RP0
        movlw   3
        btfsc   EEPROM,DI       ; Check for acknowledgement
        call    ERR             ; No acknowledge from device
        bcf     STATUS,RP0
        retlw   0


;-----------------------------------------------------------------------------
;       Single bit data transmit from PIC to serial EEPROM
;-----------------------------------------------------------------------------
;       Input   :       EEPROM register, bit DO
;       Output  :       Bit transmitted over I2C
;                       Error bits set as necessary
;-----------------------------------------------------------------------------

BITOUT
        btfss   EEPROM,DO
        goto    BIT0
        bsf     STATUS,RP0
        bsf     TRIS_C,SDA      ; Output bit 0
        movlw   2
        bcf     STATUS,RP0
        btfsc   PORT_C,SDA      ; Check for error code 2
        goto    CLK1
        call    ERR
        goto    CLK1            ; SDA locked low by device

BIT0
        bsf     STATUS,RP0
        bcf     TRIS_C,SDA      ; Output bit 0
        nop                     ; Delay
CLK1
        bsf     STATUS,RP0
        bsf     TRIS_C,SCL      ; Attempt to set SCL high
        movlw   1               ; Error code 1
        bcf     STATUS,RP0
        btfsc   PORT_C,SCL      ; SCL locked low?
        goto    BIT2            ; No.
        call    ERR             ; Yes, set error
BIT2
        nop                     ; Timing delay
        nop
        bsf     STATUS,RP0
        bcf     TRIS_C,SCL      ; Return SCL to low
        bcf     STATUS,RP0
        retlw   0

;-----------------------------------------------------------------------------
;       BYTE-READ, read one byte from serial EEPROM device
;-----------------------------------------------------------------------------
;       Input   :       ADDR    = source address
;                       SLAVE   = device address (1010xxx0)
;       Output  :       DATAI   = data read from serial EEPROM
;-----------------------------------------------------------------------------
;
RDBYTE
        bcf     STATUS,RP0
        movf    SLAVE,W         ; Move SLAVE address
        movwf   TXBUF           ;  into xmit buffer (R/W = 0)
        call    BSTART          ; Generate START bit
        call    TX              ; Output SLAVE address. Check ACK.
        bcf     STATUS,RP0
        movf    ADDR,W          ; Move WORD address
        movwf   TXBUF           ;  into xmit buffer
        call    TX              ; Output WORD address. Check ACK.
        call    BSTART          ; START READ (if only one device is
        bcf     STATUS,RP0      ; connected to the I2C bus)
        movf    SLAVE,W
        movwf   TXBUF
        bsf     TXBUF,0         ; Specify READ mode (R/W = 1)
        call    TX              ; Output SLAVE address
        call    RX              ; READ in data and acknowledge
        call    BSTOP           ; Generate STOP bit
        bcf     STATUS,RP0
        movf    RXBUF,W         ; Save data from buffer
        movwf   DATAI           ; to DATAI file register.
        return

;
;-----------------------------------------------------------------------------
;       RECEIVE eight data bits subroutine
;-----------------------------------------------------------------------------
;       Input   :       None
;       Output  :       RXBUF = 8-bit data received
;-----------------------------------------------------------------------------
;
RX
        bcf     STATUS,RP0
        movlw   .8              ; 8 bits of data
        movwf   COUNT
        clrf    RXBUF
;
RXLP
        rlf     RXBUF           ; Shift data to buffer
        skpc
        bcf     RXBUF,0         ; carry ---> f(0)
        skpnc
        bsf     RXBUF,0
        call    BITIN
        bcf     STATUS,RP0
        btfsc   EEPROM,DI
        bsf     RXBUF,0         ; Input bit =1
        decfsz  COUNT           ; 8 bits?
        goto    RXLP
        bsf     EEPROM,DO       ; Set acknowledge bit = 1
        call    BITOUT          ; to STOP further input
        retlw   0

;
;-----------------------------------------------------------------------------
;       Single bit receive from serial EEPROM to PIC
;-----------------------------------------------------------------------------
;       Input   :       None
;       Output  :       Data bit received
;-----------------------------------------------------------------------------
;
BITIN
        bsf     STATUS,RP0
        bsf     TRIS_C,SDA      ; Set SDA for input
        bcf     STATUS,RP0
        bcf     EEPROM,DI
        bsf     STATUS,RP0
        bsf     TRIS_C,SCL      ; Clock high
        movlw   1
        bcf     STATUS,RP0
        btfsc   PORT_C,SCL      ; Skip if SCL  is high
        goto    BIT1
        call    ERR
BIT1
        bcf     STATUS,RP0
        btfss   PORT_C,SDA      ; Read SDA pin, for ACK low
        goto    ACKOK
        bsf     EEPROM,DI       ; DI = 1
ACKOK
        bsf     STATUS,RP0
        nop                     ; Delay
        bcf     TRIS_C,SCL      ; Return SCL to low
        bcf     STATUS,RP0
        retlw   0

;-----------------------------------------------------------------------------
;       DELAY, Provide a 10.78mS delay
;-----------------------------------------------------------------------------
;       Input   :       None
;       Output  :       None
;-----------------------------------------------------------------------------

Delay
        bcf     STATUS,RP0
        movlw   7
        movwf   TEMP1
        clrf    TEMP            ;clear last location
dly1
        nop
        nop
        nop
        decfsz  TEMP            ;reduce count
        goto    dly1            ;Inner loop time = 1.54mS
        decfsz  TEMP1
        goto    dly1            ;Total time = 10.78mS
        retlw   0

;-----------------------------------------------------------------------------
;       START bit generation routine
;-----------------------------------------------------------------------------
;       input   : none
;       output  : initialize bus communication
;-----------------------------------------------------------------------------
;
;Generate START bit (SCL is high while SDA goes from high to low
transition)
;and check status of the serial clock.
BSTART
        bsf     STATUS,RP0
        bsf     TRIS_C,SDA      ; Make sure SDA is high
        bsf     TRIS_C,SCL      ; Set clock high
        movlw   1               ; Ready error status code 1
        bcf     STATUS,RP0
        btfss   PORT_C,SCL      ; Locked?
        call    ERR             ; SCL locked low by device, flag error
        bsf     STATUS,RP0
        bcf     TRIS_C,SDA      ; SDA goes low during SCL high
        nop                     ; Timing adjustment, 1uS @4MHz
        bcf     TRIS_C,SCL      ; Start clock train
        bcf     STATUS,RP0
        RETLW   0

;-----------------------------------------------------------------------------
;       STOP bit generation routine
;-----------------------------------------------------------------------------
;       Input   :       None
;       Output  :       Bus communication, STOP condition
;-----------------------------------------------------------------------------
;
;Generate STOP bit (SDA goes from low to high during SCL high state)
;and check bus conditions.

BSTOP
        bsf     STATUS,RP0
        bcf     TRIS_C,SDA      ; Return SDA to low
        bsf     TRIS_C,SCL      ; Set SCL high
        nop
        movlw   1               ; Ready error code 1
        bcf     STATUS,RP0
        btfss   PORT_C,SCL      ; High?
        call    ERR             ; No, SCL locked low by device
        bsf     STATUS,RP0
        bsf     TRIS_C,SDA      ; SDA goes from low to high during SCL
high
        movlw   4               ; Ready error code 4
        btfss   TRIS_C,SDA      ; High?
        call    ERR             ; No, SDA bus not release for STOP
        bcf     STATUS,RP0
        retlw   0
;
;-----------------------------------------------------------------------------
;       Two wire/I2C - CPU communication error status table and subroutine
;-----------------------------------------------------------------------------
;  input  :     W-reg   = error code
;  output :     ERCODE  = error code
;           FLAG(ERROR) = 1
;
;         code          error status mode
;       -------
------------------------------------------------------
;           1   :       SCL locked low by device (bus is still busy)
;           2   :       SDA locked low by device (bus is still busy)
;           3   :       No acknowledge from device (no handshake)
;           4   :       SDA bus not released for master to generate STOP
bit
;-----------------------------------------------------------------------------
;
;Subroutine to identify the status of the serial clock (SCL) and serial
data
;(SDA) condition according to the error status table. Codes generated are
;useful for bus/device diagnosis.
;
ERR
        bcf     STATUS,RP0
        btfss   FLAG,ERRORFLG   ; If not first error, do not change code
        movwf   ERCODE          ; Save error code
        bsf     FLAG,ERRORFLG   ; Set error flag
        retlw   0

        END