sda equ P0.0 ; set a pin for SDA
scl equ P0.1 ; set a pin for SCL
; remember to use pullups on these pins
org 0
sjmp start
start: acall i2cinit
mov R2,#20h ; byte address
mov R1,#55h ; data to test
start2: acall writeEEprom ; write 0x55 to eeprom
acall delay
mov R1,#0 ; clear R1
acall readEEprom ; read back for loop test
dec R2 ; new location
sjmp start2
writeEEprom: ; R2 = byte address.. R1 = data to write
acall startc
mov a,#0A0h ; eeprom addess
acall Send
acall ack
mov a,#0 ; internal high byte address
acall Send
acall ack
mov a,R2 ; internal low byte address
acall Send
acall ack
mov a,R1
acall Send
acall ack
acall stop
ret
readEEprom: ; R2 = byte address.. R1 = data read
acall startc
mov a,#0A0h ; eeprom address
acall Send
acall ack
mov a,#0 ; high byte
acall Send
acall ack
mov a,R2 ; low byte
acall Send
acall ack
acall rstart
mov a,#0A1h ; Read command
acall Send
acall ack
acall recv
mov R1,a
acall nak
acall stop
ret
i2cinit: ;Init I2C ( prepare for I2C transactions )
setb sda
setb scl
ret
rstart: ;ReStart I2C (for reads )
clr scl
setb sda
setb scl
clr sda
ret
startc: ;Start I2C bus transaction
setb scl
clr sda
clr scl
ret
stop: ;Stop I2C bus transaction
clr scl
clr sda
setb scl
setb sda
ret
Send: ;Send I2C data
mov r7,#08
back: clr scl
rlc a
mov sda,c
setb scl
djnz r7,back
clr scl
setb sda
ret
ack: ;ACK receive acknowlegde
clr sda
setb scl
clr scl
setb sda
ret
nak: ;NAK send acknowledge
setb sda
setb scl
clr scl
setb scl
ret
recv: ;Receive I2C data
mov r7,#08
back2: clr scl
setb scl
mov c,sda
rlc a
djnz r7,back2
clr scl
setb sda
ret
delay: mov R0,#0ffh ; works out about 10mS for write delay
mov R3,#0f4h ; a write delay for eeproms IS required
loop: djnz R0,loop
djnz R3,loop
ret
end