Juan Abba wrote: > Is there anybody with experience on I2C type serial RAM, volatile equivalent to > the microchip I2C serial EEprom family???? Hi, Here is the code to drive an I2C RAM/EEPROM (PIC16C54..57), you can also use 93C46( or 06 or ...) EEPROM type, but the protocol is different. Be carrefull about timing, I2C application note said I2C Clock can run only at 100KHz ! ;***************************************************************************** ;************** RAM / EEProm ACCESS ROUTINE on I2C Bus ********************** ; HCK = PortA.0 ; SDA = PortA.1 (In/Out) ;***************************************************************************** I2C_Address equ %10100000 ; ITEM address on I2C Line ;---------------- REGISTERS Address equ $18 ; Address to Read/Write DataHi equ $19 ; Word DATA (16Bits) DataLo equ $1A Data1 equ $10 Data2 equ $11 TempTxRx equ $1B ; Temporary register I2CCnt equ $1C ; Counter to send/Receive bits ;---------------- CONST I2CSetOUT equ %0000 ; Value to configure SDA as OUTPUT I2CSetIN equ %0010 ; Value to configure SDA as INPUT I2CPort equ 5 ; PORT A is I2CPort HCK equ 0 ; PortA.0 SDA equ 1 ; PortA.1 I2CAckWait equ 20 ; WAIT time to check ACKNOWLEDGE I2CError equ 1 ; return value if error I2COk equ 0 ; return value if OK ;****************************************************************************** ;***************************************************************************** ; RAM / EEProm ACCESS ROUTINE on I2C Bus ; HCK = PortA.0 ; SDA = PortA.1 (In/Out) ;***************************************************************************** ; WRITE WORD Data to I2C-RAM/EPROM ; Address : Address of the 2 Byte to WRITE ; DataHi : Hi Data ; DataLo : Lo Data I2CWriteData call I2CStart ; START BIT movlw I2C_Address ; Put SLAVE address on I2C line iorlw %00000000 ; To WRITE a DATA at ADDRESS movwf TempTXRX ; TempTXRX = Address of I2C Item call TxData ; Transfert DATA on SDA Line call AckWait0 ; Wait for Acknowledge btfss STATUS,2 ; Skip if Z=1 goto I2CStop movf Address,W ; Address to Access in W movwf TempTXRX ; Address to Access in W call TxData ; Transfert DATA on SDA Line call AckWait0 ; Wait for Acknowledge iorlw 0 btfss STATUS,2 ; Skip if Z=1 goto I2CStop movf Data1,W ; DataLO to WRITE in W movwf TempTXRX call TxData ; Transfert DATA on SDA Line call AckWait0 ; Wait for Acknowledge iorlw 0 btfss STATUS,2 ; Skip if Z=1 goto I2CStop movf Data2,W ; DataHI to WRITE in W movwf TempTXRX call TxData ; Transfert DATA on SDA Line call AckWait0 ; Wait for Acknowledge iorlw 0 call I2CStop ; STOP BIT retlw I2COk ;***************************************************************************** ; Output TempTXRX on SDA Line TXData movlw I2CSetOut ; Set SDA as OUTPUT tris A bcf I2CPort,SDA ; SDA = 0 movlw 8 ; I2CCnt = 8 movwf I2CCnt TXDataLoop bcf I2CPort,SDA ; SDA = 0 rlf TempTXRX btfsc STATUS,CY ; Skip if CARRY=0 bsf I2CPort,SDA bsf I2CPort,HCK ; HCK = 1 nop nop nop nop bcf I2CPort,HCK ; HCK = 0 decfsz I2CCnt goto TXDataLoop nop nop retlw I2COk ;***************************************************************************** ; Read TempTXRX on SDA Line RXData movlw I2CSetIN ; Set SDA as INPUT tris A movlw 8 ; I2CCnt = 8 movwf I2CCnt clrf TempTXRX RXDataLoop bsf I2CPort,HCK ; HCK = 1 bcf STATUS,CY ; CARRY = 0 btfsc I2CPort,SDA ; Skip if SDA=0 bsf STATUS,CY rlf TempTXRX nop bcf I2CPort,HCK ; HCK = 0 nop nop nop decfsz I2CCnt goto RXDataLoop retlw I2COk ;***************************************************************************** ; Wait k Cycle for Acknowledge from slave ACKWait0 movlw I2CSetIN tris A bsf I2CPort,HCK ; HCK = 1 movlw I2CAckWait ; I2CCnt = I2CAckWait (Wait TIME) movf I2CCnt ACKLoop0 btfss I2CPort,SDA ; Skip if SDA = 1 goto AckOk0 decfsz I2CCnt goto AckLoop0 bcf I2CPort,HCK ; HCK = 0 retlw I2CError ACKOk0 bcf I2CPort,HCK ; HCK = 0 retlw I2COk ;***************************************************************************** ; Wait k Cycle for Acknowledge from MASTER, if SDA line goes down then, an ; error occur (because SLAVE want to interrupt transmission) ACKWait1 movlw I2CSetOut tris A bcf I2CPort,SDA ; HCK = 0 bsf I2CPort,HCK ; HCK = 1 nop nop nop nop bcf I2CPort,HCK ; HCK = 0 nop nop retlw I2COk ;***************************************************************************** ACKWaitEnd movlw I2CSetIN tris A bsf I2CPort,HCK ; HCK = 1 nop nop nop nop btfss I2CPort,SDA ; Skip if SDA = 1 goto AckEr1 bcf I2CPort,HCK ; HCK = 0 retlw I2COk ACKEr1 bcf I2CPort,HCK ; HCK = 0 retlw I2CError ;***************************************************************************** ; OutPut the Start CONDITION I2CStart movlw I2CSetOut tris A bsf I2CPort,SDA ; SDA = 1 bsf I2CPort,HCK ; HCK = 1 nop nop nop nop bcf I2CPort,SDA ; SDA = 0 nop nop nop nop bcf I2CPort,HCK ; HCK = 0 nop retlw 0 ;***************************************************************************** ; OutPut the Stop CONDITION I2CStop movlw I2CSetOut ; Set SDA as OUTPUT tris A bcf I2CPort,SDA ; SDA = 0 bsf I2CPort,HCK ; HCK = 1 nop nop nop nop bsf I2CPort,SDA ; SDA = 1 nop nop nop nop bcf I2CPort,HCK ; HCK = 0 nop retlw I2CError ; An ERROR is finishig by a STOP Condition ;***************************************************************************** ; END OF I2C CODE