89c51 sda pin no
SCK BIT P3.6 ;I2C的时钟线
SDA BIT P3.7 ;I2C的数据线
;读写I2C总线器件要用到的寄存器
ERRFLAG BIT 00H
TEMP1 EQU 1AH
DELAYCOUNT EQU 1BH
ADDREHI EQU 1CH ;读写的地址
ADDRELO EQU 1DH
WRITE_DATA EQU 1EH ;单字节写入的数据
READ_DATA EQU 1FH ;单字节读出的数据
WRITE_BYTE: LCALL STARTI2C
JB ERRFLAG,WRITE_B_RE ;不是空闲返回
MOV A,#0A0H
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP ;出错停止
; MOV A,ADDREHI ;送高位地址
; LCALL SHOUT_DATA
; JB ERRFLAG,WRITE_B_STOP
MOV A,ADDRELO ;送低位地址
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP
MOV A,WRITE_DATA
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP
CLR ERRFLAG ;正常清出错位
WRITE_B_STOP: LCALL STOPI2C
MOV DELAYCOUNT,#0AH
LCALL DELAY
WRITE_B_RE: RET
READ_BYTE: LCALL STARTI2C
JB ERRFLAG,READ_RE
MOV A,#0A0H
LCALL SHOUT_DATA
JB ERRFLAG,READ_STOP
; MOV A,ADDREHI
; LCALL SHOUT_DATA
; JB ERRFLAG,READ_STOP
MOV A,ADDRELO
LCALL SHOUT_DATA
JB ERRFLAG,READ_STOP
LCALL READ_CURRENT
LJMP READ_RE
READ_STOP: LCALL STOPI2C
READ_RE: RET
READ_CURRENT: LCALL STARTI2C
JB ERRFLAG,RE_CURRENTRE
MOV A,#0A1H
LCALL SHOUT_DATA
JB ERRFLAG,RE_CURRENTST
LCALL SHIN_DATA
LCALL NAK
CLR ERRFLAG
RE_CURRENTST: LCALL STOPI2C
RE_CURRENTRE: RET
SHOUT_DATA: MOV R6,#08H
SHOUT_DATA1: RLC A
MOV SDA,C
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
DJNZ R6,SHOUT_DATA1
SETB SDA
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
MOV C,SDA
MOV ERRFLAG,C
CLR SCK
RET
SHIN_DATA: SETB SDA
MOV R6,#08H
SHIN_DATA1: NOP
NOP
NOP
SETB SCK
NOP
NOP
MOV C,SDA
RLC A
NOP
CLR SCK
DJNZ R6,SHIN_DATA1
MOV READ_DATA,A
RET
STARTI2C: SETB SDA
SETB SCK
NOP
JNB SDA,STARTI2C_ERR
JNB SCK,STARTI2C_ERR
NOP
CLR SDA
NOP
NOP
NOP
NOP
CLR SCK
CLR ERRFLAG
LJMP STARTI2C_RE
STARTI2C_ERR: SETB ERRFLAG
STARTI2C_RE: RET
STOPI2C: CLR SDA
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
SETB SDA
RET
ACK: CLR SDA
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
RET
NAK: SETB SDA
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
RET
END