📄 time.asm
字号:
;读写时钟芯片PDF8563
;使用22.1184MHz晶振
;--------------------------------------------------------------------
;启动I2C 总线子程序
START:
SETB SDA
NOP
SETB SCLK ;起始条件建立时间大于4.7us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SDA
NOP ;起始条件锁定时大于4us
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCLK ;钳住总线准备发数据
NOP
NOP
RET
;--------------------------------------------------------------------
;结束总线子程序
STOP:
CLR SDA
NOP
NOP
SETB SCLK ;发送结束条件的时钟信号
NOP ;结束总线时间大于4us
NOP
NOP
NOP
NOP
NOP ;结束总线时间大于4us
NOP
NOP
NOP
NOP
SETB SDA ;结束总线
NOP ;保证一个终止信号和起始信号的空闲时间大于4.7us
NOP
NOP
NOP
NOP ;保证一个终止信号和起始信号的空闲时间大于4.7us
NOP
NOP
NOP
RET
;--------------------------------------------------------------------
;发送应答信号子程序
MACK:
CLR SDA ;将SDA 置0
NOP
NOP
NOP
NOP
SETB SCLK
NOP ;保持数据时间即SCL 为高时间大于4.7us
NOP
NOP
NOP
NOP
NOP ;保持数据时间即SCL 为高时间大于4.7us
NOP
NOP
NOP
NOP
CLR SCLK
NOP
NOP
NOP
NOP
RET
;--------------------------------------------------------------------
;发送非应答信号
MNACK:
SETB SDA ;将SDA 置1
NOP
NOP
NOP
NOP
SETB SCLK
NOP
NOP ;保持数据时间即SCL 为高时间大于4.7us
NOP
NOP
NOP
NOP
NOP ;保持数据时间即SCL 为高时间大于4.7us
NOP
NOP
NOP
CLR SCLK
NOP
NOP
NOP
NOP
RET
;--------------------------------------------------------------------
; 检查应答位子程序
; 返回值ACK=1 时表示有应答
CACK:
SETB SDA
NOP
NOP
NOP
NOP
SETB SCLK
CLR ACK
NOP
NOP
NOP
NOP
MOV C,SDA
JC CEND
SETB ACK ;判断应答位
CEND:
NOP
NOP
CLR SCLK
NOP
NOP
RET
;--------------------------------------------------------------------
;发送字节子程序
;字节数据放入ACC
;每发送一字节要调用一次CACK 子程序取应答位
WRBYTE:
MOV R0,#08H
WLP:
RLC A ;取数据位
JC WR1
SJMP WR0 ;判断数据位
WLP1: DJNZ R0,WLP
NOP
NOP
RET
WR1: SETB SDA ;发送1
NOP
NOP
SETB SCLK
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCLK
SJMP WLP1
WR0: CLR SDA ;发送0
NOP
NOP
SETB SCLK
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCLK
SJMP WLP1
;--------------------------------------------------------------------
;读取字节子程序
;读出的值在ACC
;每取一字节要发送一个应答/非应答信号
RDBYTE:
MOV R0,#08H
RLP: SETB SDA
NOP
NOP
SETB SCLK ;时钟线为高接收数据位
NOP
NOP
NOP
NOP
MOV C,SDA ;读取数据位
MOV A,R2
CLR SCLK ;将SCL 拉低时间大于4.7us
RLC A ;进行数据位的处理
MOV R2,A
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R0,RLP ;未够8 位再来一次
RET
;--------------------------------------------------------------------
;向器件指定子地址写N 个数据
;入口参数: 器件从地址SLA 器件子地址SUBA 发送数据缓冲区MTD 发送字节数NUMBYTE
; 占用A R0 R1 R3 CY
IWRNBYTE:
MOV A,#NUMBYTE+2
MOV R3,A
LCALL START ;起动总线
MOV A,#SLA
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETWRN ;无应答则退出
MOV A,#SUBA-2 ;指定子地址
LCALL WRBYTE
LCALL CACK
MOV R1,#MTD
WRDA:
MOV A,@R1
LCALL WRBYTE ;开始写入数据
LCALL CACK
JNB ACK,IWRNBYTE
INC R1
DJNZ R3,WRDA ;判断写完没有
RETWRN: LCALL STOP
RET
;--------------------------------------------------------------------
;向器件指定子地址读取N 个数据
;入口参数: 器件从地址SLA 器件子地址SUBA 接收字节数NUMBYTE
;出口参数: 接收数据缓冲区MRD
;占用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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -