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