📄 i2c.asm
字号:
;********************************************************
;名称: I2C软件模拟程序包 *
;语言: 51汇编 *
;日期: 2007-12-15 *
;描述: 适用于PHILIPS的LPC900,最高晶振频率为12MHz. *
; 符合100Kbit/S总线标准模式. *
;********************************************************
;需定义的:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;I2C_SDA BIT ;I2C数据线 <
;I2C_SCL BIT ;I2C时钟线 <
;I2C_ACK BIT ;应答标记(为“0”表示非应答,为“1”表示应答) <
;I2C_SLA DATA ;器件从地址 <
;I2C_SUBA DATA ;器件子地址 <
;I2C_NUM DATA ;读/写的字节数 <
;I2C_MTD DATA ;发送数据缓冲首地址 <
;I2C_MRD DATA ;接收数据缓冲首地址 <
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;可调用和增减的子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;I2C_SEND_NOSUB 无子地址器件发送1个字节子程序 >
;I2C_RCV_NOSUB 无子地址器件接收1个字节子程序 >
;I2C_SEND_NN0SUB 无子地址器件发送N字节数据子程序 >
;I2C_RCV_NN0SUB 无子地址器件接收N字节数据子程序 >
;I2C_SEND_STR 有子地址器件发送N字节数据子程序 >
;I2C_RCV_STR 有子地址器件接收N字节数据子程序 >
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;************
;外部子程序:*
;************
;无子地址器件发送1个字节子程序
;//////////////////////////////////////////////////////////////////////////////////
;描述:发送无子地址器件的1字节数据
I2C_SEND_NOSUB: PUSH ACC
LCALL I2C_START
MOV ACC,I2C_SLA
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,SNSUB_END
POP ACC
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
LCALL I2C_STOP
RET
SNSUB_END: POP ACC
LCALL I2C_STOP
RET
;//////////////////////////////////////////////////////////////////////////////
;无子地址器件接收1个字节子程序
;/////////////////////////////////////////////////////////////////////////////
;描述:接收无子地址器件的1个字节数据
I2C_RCV_NOSUB: LCALL IC2_START
MOV A,I2C_SLA
INC A
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,RNSUB_END
LCALL I2C_RCV_BYTE
LCALL I2C_MNACK
RNSUB_END: LCALL I2C_STOP
RET
;////////////////////////////////////////////////////////////////////////////
;无子地址器件发送N字节数据子程序
;////////////////////////////////////////////////////////////////////////////
;描述:向无子地址器件发送N字节数据
I2C_SEND_NN0SUB:MOV A,I2C_NUM
MOV R0,A
MOV A,I2C_SLA
LCALL I2C_START
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,SNNSUB_END
MOV R1,#I2C_MTD
SNNSUB1: MOV A,@R1
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,SNNSUB_END
INC R1
DJNZ R0,SNNSUB1
SNNSUB_END: LCALL I2C_STOP
RET
;////////////////////////////////////////////////////////////////////////
;无子地址器件接收N字节数据子程序
;//////////////////////////////////////////////////////////////////////////
;描述:接收无子地址器件的N字节数据。
I2C_RCV_NNOSUB: MOV A,I2C_NUM
MOV R0,A
MOV A,IC2_SLA
INC A
LCALL I2C_START
LCALL I2C_CACK
JNB I2C_ACK,RNNSUB_END
MOV R1,I2C_MDR
RNNSUB1: LCALL I2C_RCV_BYTE
MOV @R1,A
DJNZ R0,RNNSUB2
LCALL I2C_MNACK
LCALL I2C_STOP
RET
RNNSUB2: LCALL I2C_MACK
INC R1
SJMP RNNSUB1
;/////////////////////////////////////////////////////////////////////////
;有子地址器件发送N字节数据子程序
;////////////////////////////////////////////////////////////////////////
;描述:向有子地址器件的指定地址发送N字节数据
I2C_SEND_STR: MOV A,I2C_NUM
MOV R0,A
MOV A,I2C_SLA
LCALL I2C_START
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,SS_END
MOV A,I2C_SUBA
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,SS_END
MOV R1,I2C_MTD
SS1: MOV A,@R1
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,SS_END
INC R1
DJNZ R0,SS1
SS_END LCALL I2C_STOP
RET
;////////////////////////////////////////////////////////////////////////
;有子地址器件接收N字节数据子程序
;////////////////////////////////////////////////////////////////////////
;描述:接收有子地址器件指定的N字节数据
I2C_RCV_STR: MOV A,I2C_NUM
MOV R0,A
MOV A,I2C_SLA
LCALL I2C_START
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,RS_END
MOV A,I2C_SUBA
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
MOV A,I2C_SLA
INC A
LCALL I2C_START
LCALL I2C_SEND_BYTE
LCALL I2C_CACK
JNB I2C_ACK,RS_END
MOV R1,I2C_MRD
RS1: LCALL I2C_RCV_BYTE
MOV @R1,A
DJNZ R0,RS2
LCALL I2C_MNACK
RS_END: LCALL I2C_STOP
RET
RS2: INC R1
LCALL I2C_MACK
SJMP RS1
;////////////////////////////////////////////////////////////////////////
;************
;内部子程序 *
;************
;延时子程序(延时5uS)
;............................................................................
I2C_DELAY: MOV R0,#15
DJNZ R0,$
RET
;............................................................................
;启动I2C总线子程序
;............................................................................
;描述:SDA在SCL为高时由高到低跳变.
I2C_START: SETB I2C_SDA
NOP
SETB I2C_SCL
LCALL I2C_DELAY ;起始条件建立时间大于4.7uS
CLR I2C_SDA
LCALL I2C_DELAY ;起始条件锁定时间大于4uS
CLR I2C_SCL ;钳住总线,准备发送数据
NOP
RET
;............................................................................
;结束总线子程序
;............................................................................
;描述:SDA在SCL为高时由低向高跳变.
I2C_STOP: CLR I2C_SDA
NOP
SETB I2C_SCL
LCALL I2C_DELAY ;总线结束时间大于4uS
SETB I2C_SDA
LCALL I2C_DELAY ;保证结束信号和起始信号空闲时间大于4.7uS
RET
;...............................................................................
;发送应答信号子程序
;...............................................................................
;描述:应答信号由"接收器"产生;每成功接收到1个字节后,如还需要接收数据则发送
; 一个应答;"接收器"在第9个时钟周期将SDA拉低(应答).
I2C_MACK: CLR I2C_SDA
NOP
NOP
SETB I2C_SCL
LCALL I2C_DELAY ;保持数据时间大于4.7uS
CLR I2C_SCL
NOP
NOP
RET
;..................................................................................
;发送非应答信号子程序
;..................................................................................
;描述: 应答信号由“接收器”产生;每成功接收到1个字节后,如不再接收新发送
; 一个非应答;"接收器"在第9个时钟周期将SDA拉高(非应答).
I2C_MNACK: SETB I2C_SDA
NOP
NOP
SETB I2C_SCL
LCALL I2C_DELAY ;保持数据时间大于4.7uS
CLR I2C_SCL
NOP
NOP
RET
;..................................................................................
;检查应答信号子程序
;..................................................................................
;描述:获得"接收器"发出的应答或非应答信号;如应答ACK=1,否则(非应答)ACK=0.
I2C_CACK: SETB I2C_SDA
NOP
NOP
SETB I2C_SCL
CLR I2C_ACK
NOP
NOP
MOV C,SDA
JC CACK_END
SETB I2C_ACK ;应答
CACK_END: CLR I2C_SCL
NOP
NOP
RET
;..................................................................................
;发送一字节数据
;..................................................................................
;描述:将ACC中的数据发送出去.
I2C_SEND_BYTE: MOV R0,#8
SB3: RLC A
JC SB1
SJMP SB0
SB4: DJNZ R0,
NOP
NOP
RET
SB1: SETB I2C_SDA
NOP
NOP
SETB I2C_SCL
LCALL I2C_DELAY
CLR I2C_SCL
SJMP SB4
SB0: CLR I2C_SDA
NOP
NOP
SETB I2C_SCL
LCALL I2C_DELAY
CLR I2C_SCL
SJMP SB4
;................................................................................
;接收一字节数据
;................................................................................
;描述:将接收到的数据存入ACC中.
I2C_RCV_BYTE: MOV R0,#8
MOV A,#0
RB1: SETB I2C_SDA
NOP
NOP
SETB I2C_SCL
NOP
NOP
MOV C,I2C_SDA
RLC A
NOP
NOP
CLR I2C_SCL
NOP
NOP
DJNZ R0,RB1
RET
;..................................................................................
;********************************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -