📄 compass-i2c.asm
字号:
;------------------ 周立功单片机研究所 -----------------------
;-------------------------------------------------------------
;文件名: COMPASS-I2C.ASM
;功能: 指南针模块的I2C总线操作
;创建人: 唐尧福
;创建日期: 2004.04.01
;注意: 使用模拟I2C。
;-------------------------------------------------------------
$INCLUDE (REG932.INC)
;变量定义
ACK BIT 10
SLA DATA 76H
NUMBYTE EQU 30H
MTD EQU 51H
SUBA EQU 32H
MRD EQU 40H
ORG 0000H
AJMP MAIN
;主程序开始
ORG 0100H
MAIN:
MOV SP,#60H
MOV P0M1,#00H
MOV P0M2,#00H
MOV P1M1,#00H
MOV P1M2,#00H ;P1口设置为准双向
MAIN_L1:
MOV SLA,#76H ;指定器件地址
MOV SUBA,#00H ;指定子地址
MOV NUMBYTE,#03H
LCALL IRDNBYTE ;从指南针模块读取3个字节
AJMP MAIN_L1
;***********************
;名称: START
;启动I2C总线子程序
;***********************
START:
SETB SDA
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB SCL ;起始条件建立时间大于4.7us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SDA
NOP ;起始条件锁定时大于4us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL ;钳住总线,准备发数据
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
;****************************
;名称: STOP
;功能: 结束总线子程序
;****************************
STOP:
CLR SDA
NOP
NOP
NOP
NOP
SETB SCL ;发送结束条件的时钟信号
NOP ;结束总线时间大于4us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB SDA ;结束总线
NOP ;保证一个终止信号和起始信号的空闲时间大于4.7us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
;*******************************
;名称: MACK
;功能: 发送应答信号子程序
;*******************************
MACK:
CLR SDA ;将SDA置0
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB SCL
NOP ;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
;****************************
;名称: MNACK
;功能: 发送非应答信号
;****************************
MNACK:
SETB SDA ;将SDA置1
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB SCL
NOP
NOP ;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
;**************************************
;名称: CACK
;功能: 检查应答位子程序
; 返回值,ACK=1时表示有应答
;**************************************
CACK:
SETB SDA
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB SCL
CLR ACK
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV C,SDA
JC CEND
SETB ACK ;判断应答位
CEND:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
;*******************************************************
;名称: WRBYTE
;功能: 发送字节子程序
;入口参数: 字节数据放入ACC
;注意: 每发送一字节要调用一次CACK子程序,取应答位
;*******************************************************
WRBYTE:
MOV R0,#08H
WLP:
RLC A ;取数据位
JC WR1
SJMP WR3 ;判断数据位
WLP1:
DJNZ R0,WLP
NOP
RET
WR1:
SETB SDA ;发送1
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SJMP WLP1
WR3:
CLR SDA ;发送0
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SJMP WLP1
;*************************************************
;名称: RDBYTE
;功能: 读取字节子程序
;出口参数: 读出的值在ACC
;注意: 每取一字节要发送一个应答/非应答信号
;*************************************************
RDBYTE:
MOV R0,#08H
RLP:
SETB SDA
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
SETB SCL ;时钟线为高,接收数据位
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV C,SDA ;读取数据位
MOV A,R2
RLC A ;进行数据位的处理
MOV R2,A
CLR SCL ;将SCL拉低,时间大于4.7us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R0,RLP ;未够8位,再来一次
RET
;****************************************************************
;名称: IRDNBYTE
;功能: 向器件指定子地址读取N字节数据
;入口参数: 器件从地址SLA、器件子地址SUBA、接收字节数NUMBYTE
;出口参数: 接收数据缓冲区MTD
;占用: A、 R0、 R1、 R2、 R3、 CY
;****************************************************************
IRDNBYTE:
MOV R3,NUMBYTE
LCALL START
MOV A,SLA
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETRDN
MOV A,SUBA ;指定子地址
LCALL WRBYTE
LCALL CACK
LCALL START ;重新起动总线
MOV A,SLA
INC A ;准备进行读操作
LCALL WRBYTE
LCALL CACK
JNB ACK,IRDNBYTE
MOV R1,#MRD
RDN1:
LCALL RDBYTE ;读操作开始
MOV @R1,A
DJNZ R3,SACK
LCALL MNACK ;最后一字节发非应答位
RETRDN:
LCALL STOP ;并结束总线
RET
SACK:
LCALL MACK
INC R1
SJMP RDN1
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -