📄 pcf8574.asm
字号:
BitCnt DATA 30H ; I2C 数据位计数器
ByteCnt DATA 31H ; I2C 数据字节计数器
SlvAdr DATA 32H ;被控器地址
RcvDat DATA 70H ;接收数据缓冲区
XmtDat DATA 50H ;发送数据缓冲区
CS EQU P1.4 ;端口位定义
SDA BIT P1.0 ;模拟I2C 数据传送位
SCL BIT P1.1 ;模拟I2C 时钟控制状态标志
ACK BIT 20H ;接收数据非应答标志
main: MOV P1,#00H
MOV XmtDat,#01h ;传送的字节内容为#0F5h
LOOP: MOV SlvAdr,#042h ; 取PCF8574 的器件地址
MOV ByteCnt,#1 ;传送字节个数为1
; 并口P0-P7 的输出值为11110101
ACALL SendData ;调用数据发送模块
JMP main
;**************************************************************************************************
; 发送数据程序
;名称:SendData
;描述:发送ByteCnt 个字节给被控器PCF8574
;被控器地址在SlvAdr 中
;所发送数据的字节数ByteCnt 在中发送的数据在XmtDat 缓冲区中
;发送数据正常返回标志F0=0 F0=1 表示被控器无应答或损坏
;*************************************************************************************************
SendData: SETB CS
ACALL START ;发送I2C 总线起始条件
MOV A ,SlvAdr ;取被控器总线地址
ACALL SentByte ;发送被控器总线地址
;JB F0,SendReturn ;出错返回
MOV R0,#XmtDat ;取发送数据缓冲区首址
SentNext: MOV A,@R0
ACALL SentByte ;发送一次数据
;JB F0,SendReturn ;出错返回
;INC @R0 ;取下一个数据
LCALL DELAY
LCALL DELAY
LCALL DELAY
LCALL DELAY
LCALL DELAY
LCALL DELAY
;DJNZ ByteCnt,SentNext ;重复操作直到发送完最后一个数据
MOV A,XmtDat
RL A
MOV XmtDat, A
JMP SentNext
ACALL STOP ;发送I2C 总线停止条件
SendReturn:RET
;****************************************************************************************************
; 子程序
;***************************************************************************************************
;名称:START
;描述:启动I2C 总线子程序--发送I2C 起始条件
;--------------------------------------------------------------------------------------------------
START: CLR SCL
NOP
SETB SDA
NOP
SETB SCL
NOP
CLR SDA
NOP
CLR SCL
RET
;---------------------------------------------------------------------------------------------------
;描述:停止I2C 总线子程序--发送I2C 总线停止条件
;---------------------------------------------------------------------------------------------------
STOP:CLR SCL
NOP
SETB SDA
NOP
SETB SCL
NOP
CLR SDA
NOP
CLR SCL
RET
;------------------------------------------------------------------------------------
;名称:SentByte
;描述:字节数据传送子程序发送一个字节数据或地址给被控器PCF8574
;要发送的数据在ACC 中
;发送数据正常返回标志F0=0 F0=1 表示被控器无应答或损坏
;-------------------------------------------------------------------------------------
SentByte:NOP
MOV R3,#08H
WBY0: CLR SCL
RLC A
MOV SDA,C
SETB SCL
DJNZ R3,WBY0
CLR SCL
NOP
SETB SCL
NOP
JB SDA,$
CLR SCL
NOP
RET
;----------------------------------------------------------------------------------------------------
;名称:RcvByte
;描述:字节数据接收子程序从被控器PCF8574 接收一个字节数据然后根据主程序要求发送应答位
;接收的字节数据在ACC 中
;---------------------------------------------------------------------------------------------------
RcvByte: SETB SDA ;置数据线为输入方式
MOV BitCnt,#08H ;要传送的数据长度为8 位
Rcv: NOP
CLR SCL ;置时钟线为低准备接收数据位
NOP ;时钟低周期大于4.7 s
NOP
NOP
NOP
NOP
SETB SCL ;置时钟线为高使数据线上数据有效
NOP
NOP
CLR C ;准备将接收的数据位放入ACC 中
JNB SDA,Rcv0 ;读数据位若为“0”则置C=0 并转Rcv0 接收数据位
SETB C ;读数据位若为“1”则置C=1
Rcv0: RLC A ;接收的数据位放入ACC 中
NOP
NOP
DJNZ BitCnt,Rcv ;8 位没收完继续接收
CLR SCL ;8 位接收完置时钟线和数据线为低准备发送应答或非应答信号
NOP
NOP
NOP
CLR SDA
JNB ACK,SentAckB ;判断是否需要继续接收字节数据若需要则转SentAckB 发送应答位
SETB SDA ;发送非应答信号
SentAckB: NOP ;以下程序发送应答位
NOP
SETB SCL ;置时钟线为高使应答位有效
NOP ;时钟高周期大于4 s
NOP
NOP
NOP
NOP
CLR SCL ;清时钟线钳住I2C 总线以便继续接收字接数据或发送停止条件
CLR ACK ;清接收非应答标志
RET
;===================================================================================================
Delay: MOV R7,#0FFH ;延时10ms,等待数据写完
D1: MOV R6,#0FFH
D2: DJNZ R6,D2
DJNZ R7,D1
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -