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 + -
显示快捷键?