time.asm
来自「上课老师给的8086仿真器」· 汇编 代码 · 共 353 行
ASM
353 行
ACK BIT 20H
SLA EQU 30H
SUBA DATA 31H
NUMBYTE DATA 32H
MTD EQU 40H
MRD EQU 50H
SCL EQU 0B0H
SDA EQU 0B1H
PCF8563 EQU 0A2H
;*******************************
ZLG7290 EQU 70H
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN: MOV SP,#60H
MOV R4,#0F0H ;延时,等待其它芯片复位
DJNZ R4,$
MOV MTD,#00H
MOV MTD+1,#12H
MOV MTD+2,#00H
MOV MTD+3,#00H
MOV MTD+4,#00H
WR8563: MOV SLA,#PCF8563
MOV SUBA,#00H
MOV NUMBYTE,#5H
LCALL IWRNBYTE
NOP
RD8563: MOV SLA,#PCF8563
MOV SUBA,#02H
MOV NUMBYTE,#3H
LCALL IRDNBYTE
NOP
LCALL CHA
;LCALL CHANG
LCALL DDISP
LCALL DISP
SJMP RD8563
;*******************************
CHANG: MOV R0,#MRD
MOV R1,#79H
MOV R2,#06H
CHANG1: MOV A,@R0
ANL A,#0FH
MOV @R1,A
MOV A,@R0
SWAP A
ANL A,#0FH
INC R1
MOV @R1,A
INC R0
INC R1
DJNZ R2, CHANG1
RET
;*******************************
DISP: MOV R6,#60H
MOV R0,#79H
MOV R2,#06H
LOOP1: MOV A, @R0
MOV R7,A
MOV MTD,R6
MOV MTD+1,R7
INC R6
INC R0
LCALL SENDCMD
NOP
NOP
; LCALL DELAY
DJNZ R2,LOOP1
RET
;*************************************
;发送命令子程序
SENDCMD: MOV SLA,#ZLG7290 ;指定器件地址
MOV SUBA,#07H ;指定子地址
MOV NUMBYTE,#02H ;发送2字节数据
LCALL IWRNBYTE
NOP ;调用写n字节数据程序
RET
;--------------------------------------------------------------------------------------------------------
;VI2C_ASM.ASM
;I2C 软件包的底层子程序,使用前要定义好SCL和SDA。在标准80C51模式
;(12 Clock)下,对主频要求是不高于12MHz(1个机器周期1us);若Fosc>12MHz
;则要增加相应的NOP指令数。在使用本软件包时,请在你的程序的未尾加入
;INCLUDE (VI2C_ASM.ASM)即可。
;--------------------------------------------------------------------------------------------------------
;启动I2C总线子程序
DY: MOV R7,#1H
DJNZ R7,$
RET
DELAY: MOV R5,#10H
DELAY0: MOV R4,#0F0H
DJNZ R4,$
DJNZ R5,DELAY0
RET
;启动I2C总线子程序
START: SETB SDA
NOP
SETB SCL ;起始条件建立时间大于4.7us
LCALL DY
CLR SDA
LCALL DY
CLR SCL ;钳住总线,准备发数据
NOP
RET
;结束总线子程序
STOP: CLR SDA
NOP
SETB SCL ;发送结束条件的时钟信号
LCALL DY
SETB SDA ;结束总线
LCALL DY
RET
;发送应答信号子程序
MACK: CLR SDA ;将SDA置0
NOP
NOP
SETB SCL
LCALL DY
CLR SCL
NOP
NOP
RET
;发送非应答信号
MNACK: SETB SDA ;将SDA置1
NOP
NOP
SETB SCL
LCALL DY
CLR SCL
NOP
NOP
RET
; 检查应答位子程序
; 返回值,ACK=1时表示有应答
CACK: SETB SDA
NOP
NOP
SETB SCL
CLR ACK
NOP
NOP
MOV C,SDA
JC CEND
SETB ACK ;判断应答位
CEND: NOP
CLR SCL
NOP
RET
;发送字节子程序
;字节数据放入ACC
;每发送一字节要调用一次CACK子程序,取应答位
WRBYTE:MOV R0,#08H
WLP: RLC A ;取数据位
JC WR1
SJMP WR0 ;判断数据位
WLP1: DJNZ R0,WLP
NOP
RET
WR1: SETB SDA ;发送1
NOP
SETB SCL
LCALL DY
CLR SCL
SJMP WLP1
WR0: CLR SDA ;发送0
NOP
SETB SCL
LCALL DY
CLR SCL
SJMP WLP1
;读取字节子程序
;读出的值在ACC
;每取一字节要发送一个应答/非应答信号
RDBYTE: MOV R0,#08H
RLP: SETB SDA
NOP
SETB SCL ;时钟线为高,接收数据位
NOP
NOP
MOV C,SDA ;读取数据位
MOV A,R2
CLR SCL ;将SCL拉低,时间大于4.7us
RLC A ;进行数据位的处理
MOV R2,A
NOP
NOP
NOP
DJNZ R0,RLP ;未够8位,再来一次
RET
; 无子地址器件写字节数据
; 入口参数: 数据为ACC、器件从地址SLA
; 占用: A、R0、CY
IWRBYTE: PUSH ACC
IWBLOOP: LCALL START ;起动总线
MOV A,SLA
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETWRB ;无应答则跳转
POP ACC ;写数据
LCALL WRBYTE
LCALL CACK
LCALL STOP
RET
RETWRB: POP ACC
LCALL STOP
RET
;无子地址器件读字节数据
;入口参数: 器件从地址SLA
;出口参数: 数据为ACC
;占用 A 、R0、R2 、CY
IRDBYTE: LCALL START
MOV A,SLA ;发送器件从地址
INC A
LCALL WRBYTE
LCALL CACK
JNB ACK,RETRDB
LCALL RDBYTE ;进行读字节操作
LCALL MNACK ;发送非应信号
RETRDB: LCALL STOP ;结束总线
RET
;向器件指定子地址写N个数据
;入口参数: 器件从地址SLA、器件子地址SUBA 、发送数据缓冲区MTD、发送字节数NUMBYTE
; 占用: A 、R0 、R1 、R3 、CY
IWRNBYTE: PUSH 00H
PUSH 01H
PUSH 03H
MOV A,NUMBYTE
MOV R3,A
LCALL START ;起动总线
MOV A,SLA
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETWRN ;无应答则退出
MOV A,SUBA ;指定子地址
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
POP 03H
POP 01H
POP 00H
RET
;向器件指定子地址读取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
RET
;*********************************************************************************************
; 请注意
;
;占用内部资源: R0,R1,R2,R3,ACC,Cy。
; 在你的程序里要做以下定义:
;使用前须定义变量: SLA 器件从地址 SUBA器件子地址 NUMBYTE读/写的字节数 ,位变量ACK
;使用前须定义常量: SDA SCL 总线位 MTD 发送数据缓冲区首址 MRD 接收数据缓冲区首址
;(ACK为调试/测试位,ACK为0时表示无器件应答)
;
;**********************************************************************************************
DDISP: SETB 0D4H
MOV R1,#7EH
MOV R2,#20H
MOV R3,#00H
DISP1: MOV DPTR,#0FF21H
MOV A,R2
MOVX @DPTR,A
MOV DPTR,#DATA1
MOV A,@R1
MOVC A,@A+DPTR
MOV DPTR,#0FF22H
MOVX @DPTR,A
DISP2: DJNZ R3,DISP2
DEC R1
CLR C
MOV A,R2
RRC A
MOV R2,A
JNZ DISP1
MOV A,#0FFH
MOV DPTR,#0FF22H
MOVX @DPTR,A
CLR 0D4H
RET
DATA1: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
DB 88H,83H,0C6H,0A1H,86H,8EH,0FFH,0CH,89H,0DEH,0BFH
CHA: MOV A,50H
ANL A,#0FH
MOV 79H,A
MOV A,50H
SWAP A
ANL A,#0FH
MOV 7AH,A
;************
MOV A,51H
ANL A,#0FH
MOV 7BH,A
MOV A,51H
SWAP A
ANL A,#0FH
MOV 7CH,A
;***********
MOV A,52H
ANL A,#0FH
MOV 7DH,A
MOV A,52H
SWAP A
ANL A,#03H
MOV 7EH,A
RET
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?