程序.asm

来自「AT89C52单片机为核心」· 汇编 代码 · 共 869 行 · 第 1/2 页

ASM
869
字号
QCH:	MOV    @R0,A
        INC    R0
	DJNZ   R3,QCH
	ret
;***********************************************************************************************        	
;键盘扫描子程序
;***********************************************************************************************
KEYIN:	MOV	P1,#0FH
	MOV	A,P1
	ANL	A,#0FH
	MOV	B,A
	MOV	P1,#0F0H
	MOV	A,P1
	ANL	A,#0F0H
	ORL	A,B
	RET
;***********************************************************************************************
;查顺序码子程序
;***********************************************************************************************	
CHA:    MOV     R0,#0FFH			;查键码所对应的
        MOV     DPTR,#TABLE1
GO:     INC     R0
        MOV     A,R0
        MOVC    A,@A+DPTR
        CJNE    A,KEYC,GO
        MOV     KEYC1,R0 
        RET
WAIT1:	MOV	R6,#0ffH			;延时子程序
DL4:	MOV	R7,#0ffH
DL3:	NOP
	NOP
	DJNZ	R7,DL3
	DJNZ	R6,DL4
	RET     
;************************************************************************************************        
;延时子程序(延时1MS)
;***********************************************************************************************        
WAIT:	MOV	R6,#0AH			;延时子程序
DL2:	MOV	R7,#18H
DL1:	NOP
	NOP
	DJNZ	R7,DL1
	DJNZ	R6,DL2
	RET
;***********************************************************************************************
;清除键盘缓冲区内容
;***********************************************************************************************	
CLEAR:	MOV	R0,#30H
	MOV	R1,#03H
CLEAR1:	MOV	A,#00H
	MOV	@R0,A
	INC	R0
	DJNZ	R1,CLEAR1
	RET
;***********************************************************************************************
;数码管三位显示
;***********************************************************************************************	
SS:	MOV	R3,#03H
        MOV     R5,A	
SS1:	LCALL	WRITE7219
	INC    R5
	MOV    A,R5
	DJNZ	R3,SS1
	RET
;************************************************************************************************
;输入数字显示程序
;***********************************************************************************************	
sdp:    mov     r3,#03h
        mov     r0,#33h
        mov     r5,a
pp1:    dec     r0
        mov     a,@r0
        mov     r4,a
        mov     a,r5      
        lcall   write7219        
        dec     r5
        djnz    r3,pp1
        ret
;*******************************************************************************************
;max7219显示子程序
;*******************************************************************************************	
DISPLAY:MOV     R0,#34H 	;显示数据首地址
        MOV     R1,#01H
        MOV     R3,#8H		;显示位数
L2:     MOV     A,@R0
        MOV     R4,A
        MOV A,R1
        ACALL WRITE7219 	;将数据→7219
        INC R0
        INC R1
        DJNZ R3,L2
        RET 
;----------------------------------------------------------------------------------------
;向MAX7219送数据或地址的子程序:
;----------------------------------------------------------------------------------------
SEND7219:MOV R6,#8 	;向MAX7219 送8 位数据或地址
	CLR     C
L1:     NOP
        NOP
        CLR P0.0 	;CLK下跳
        RLC A 		;数据→C
        MOV P0.1,C 	;传数
        NOP
        NOP
        SETB P0.0 	;CLK上跳
        DJNZ R6,L1
        RET
;----------------------------------------------------------------------------------------               
;写MAX7219的子程序:
;-----------------------------------------------------------------------------------------
WRITE7219:ACALL SEND7219  	;先向MAX7219送地址
          MOV A,R4        	;待送内容
          ACALL SEND7219  	;向MAX7219 送数据
          SETB    P0.2        	;数据装载
          NOP
          CLR      P0.2
          NOP
          RET
;-----------------------------------------------------------------------------------------
;非压缩性BCD码转换成压缩BCD码
;入口条件:待转换的非压缩性BCD码存放在[R0]中,字节数放在R7中。
;出口条件:转换后的压缩性BCD码放在[R1]中
;----------------------------------------------------------------------------------------- 
ZHUAN:  MOV     UU,R0
        MOV     A,UU
        SUBB    A,R7    ;修改指针
        MOV     UU,A
ZHUAN1: MOV     A,@R0
        ORL     A,#0F0H
        MOV     R6,A
        DEC     R0
        MOV     A,R0
        CJNE    A,UU,KK ;判断是否转换完,为了防止待转换字节是奇数
        MOV     A,R6
        ANL     A,#0FH
        MOV     @R1,A
        LJMP    TT
KK:     MOV     A,@R0
        SWAP    A
        ORL     A,#0FH
        ANL     A,R6
        MOV     @R1,A
        DEC     R1
        DEC     R0
        dec     r7
        DJNZ    R7,ZHUAN1
TT:     NOP
        RET
;----------------------------------------------------------------------------------------
;入口条件:待转换的压缩BCD码放在[R0]中,转换的字节数放在R7中。
;出口条件:转换后的非压缩BCD码放在[R1]中。
;影响资源:A,R0,R1,R2,R7。
;----------------------------------------------------------------------------------------
ZHUAN2: MOV     A,R7
        ADD     A,R0
        MOV     R0,A
        MOV     A,R7
        ADD     A,R1
        MOV     R1,A
        DEC     R0
ZHUAN3: MOV     A,@R0
        MOV     R2,A
        ANL     A,#0FH
        MOV     @R1,A
        CJNE    R7,#01H,CC
        MOV     A,R2
        SWAP    A
        ANL     A,#0FH
        JZ      NN
        DEC     R1
        MOV     @R1,A
        LJMP    NN
CC:     DEC     R1
        MOV     A,R2
        SWAP    A
        ANL     A,#0FH
        MOV     @R1,A
        DEC     R0
        DEC     R1
        DJNZ    R7,ZHUAN3
NN:     NOP
        RET
;***********************************************************************************************        
;多字节BCD码加法。
;入口条件:字节数放在R7中,被加数放在[R0]中,加数放在[R1]中。
;出口信息:和在[R0]中,最高位进位在CY中。
;影响资源:PSW,A,R2.
;***********************************************************************************************             
BCDA:   MOV A,R7
	MOV R2,A       ;取字节数放在R2中
	ADD A,R0       ;初始化指针
	MOV R0,A
	MOV A,R2
	ADD A,R1
	MOV R1,A
	CLR C
BCDA1:	DEC R0
	DEC R1
	MOV A,@R0
	ADDC A,@R1
	DA A	
	MOV @R0,A
	DJNZ R2,BCDA1
	RET
;************************************************************************************************	
;多字节压缩BCD码减法子程序
;出口信息:差在[R0]中,最高位进位在CY中。
;入口信息:字节数在R7中,被减数在[R1]中。
;影响资源:PSW,A,R2.
;************************************************************************************************
BCDB:   LCALL   NEG1    ;减数[R1]十进制取补
        LCALL   BCDA    ;按多字节BCD码加法处理
        CPL     C       ;将补码加法的进位标志转换成借位标志
        MOV     F0,C    ;保护借位标志
        LCALL   NEG1    ;恢复减数[R1]的原始值
        MOV     C,F0    ;恢复借位标志
        RET
NEG1:   MOV     A,R0
        XCH     A,R1
        XCH     A,R0
        LCALL   NEG
        MOV     A,R0
        XCH     A,R1
        XCH     A,R0
        RET
;多字节BCD码取反
NEG:    MOV     A,R7
        DEC     A
        MOV     R2,A
        MOV     A,R0
        MOV     R3,A
NEG0:   CLR     C
        MOV     A,#99H;十进制取补
        SUBB    A,@R0
        MOV     @R0,A
        INC     R0
        DJNZ    R2,NEG0
        MOV     A,#9AH
        SUBB    A,@R0
        MOV     @R0,A
        MOV     A,R3
        MOV     R0,A
        RET 
;**************************************************************************************************
; 24C64发送数据程序
;名称:SENDDATA
;描述:发送BYTECNT 个字节给被控器PCF8583
;被控器地址在SLVADR 中单元地址在SUBADR 中
;所发送数据的字节数ByteCnt 在中发送的数据在XmtDat 缓冲区中
;发送数据正常返回标志F0=0 F0=1 表示被控器无应答或损坏
;*************************************************************************************************
SENDDATA:CLR    EA
        LCALL 	START      		;发送I2C 总线起始条件
	MOV 	A,SLVADR        	;取被控器总线地址
	LCALL 	SENTBYTE          	;发送被控器总线地址
	JB 	F0,SENDRETURN         	;出错返回
	MOV 	A,SUBADR1             	;取单元地址
	LCALL 	SENTBYTE           	;发送单元地址
	JB 	F0,SENDRETURN         	;出错返回
SENDTWO:MOV 	A,SUBADR2 	        ;取单元地址2
	LCALL 	SENTBYTE 	        ;发送单元地址
	JB 	F0,RCVRETURN           	;出错返回
SENDONE:MOV 	R0,#XMTDAT           	;取发送数据缓冲区首址
SENTNEXT:MOV 	A,@R0
	LCALL 	SENTBYTE           	;发送一次数据
	JB 	F0,SENDRETURN         	;出错返回
	INC 	R0                   	;取下一个数据
	DJNZ 	BYTECNT,SENTNEXT    	;重复操作直到发送完最后一个数据
	LCALL 	STOP               	;发送I2C 总线停止条件
DELAY10:MOV 	R7,#30H       		;延时10MS,等待数据写完   	
D1:	MOV 	R6,#34H
D2:	DJNZ 	R6,D2
	DJNZ 	R7,D1
SENDRETURN: SETB     EA
            RET
;***************************************************************************************************
;24C64接收数据程序;
;名称:RcvData
;描述:从被控器PCF8583 接收ByteCnt 个字节数据
;被控器地址在SlvAdr 中单元地址在SubAdr 中
;所接收数据的字节数ByteCnt 在中接收的数据在XmtDat 缓冲区中
;接收数据正常返回标志F0=0 F0=1 表示被控器无应答或损坏
;**************************************************************************************************
RCVDATA:CLR     EA
        LCALL 	START 	       		;发送I2C 总线起始条件
	MOV 	A,SLVADR 	        ;取被控器总线地址
	LCALL 	SENTBYTE 	        ;发送被控器总线地址
	JB 	F0,RCVRETURN          	;出错返回
	MOV 	A,SUBADR1 	        ;取单元地址
	LCALL 	SENTBYTE 	        ;发送单元地址
	JB 	F0,RCVRETURN           	;出错返回
RCVTWO:	MOV 	A,SUBADR2 	        ;取单元地址2
	LCALL 	SENTBYTE 	        ;发送单元地址
	JB 	F0,RCVRETURN           	;出错返回
RCVONE:	LCALL 	START 	          	;发送I2C 总线重复起始条件
	MOV 	A,SLVADR 	        ;取被控器总线地址
	SETB 	ACC.0 	           	;取总线读操作位
	LCALL 	SENTBYTE 	        ;发送被控器总线地址
	JB 	F0,RCVRETURN            ;出错返回
	CLR 	ACK 	           	;清接收非应答标志准备接收数据
	MOV 	R0,#RCVDAT 	        ;取接收数据缓冲区首址
	DJNZ 	BYTECNT,RCVNEXT       	;如果还未接收数据则转去接收前BYTECNT)-1 个数据
	SJMP 	RCVLAST 	        ;只剩最后一个数据未接收转去接收最后一个数据
RCVNEXT:LCALL 	RCVBYTE 	     	;接收数据
	MOV 	@R0,A 	           	;将数据放入接收缓冲区中
	INC 	R0 		        ;指向下一个缓冲区地址
	DJNZ 	BYTECNT,RCVNEXT       	;重复操作直到剩下最后一个数据
RCVLAST:SETB 	ACK 	           	;置接收非应答标志准备在接收完最后一个数据后发出非应答信;号以停止接收数据
	LCALL 	RCVBYTE 	        ;接收最后一个数据
	MOV 	@R0,A 	            	;将最后一个数据放入接收缓冲区中
	LCALL 	STOP 	            	;发送I2C 总线停止条件
RCVRETURN: SETB EA
          RET
;------------------------------------------------------------------------------------------------                    
;名称:START
;描述:启动I2C 总线子程序--发送I2C 起始条件
;--------------------------------------------------------------------------------------------------
START:	SETB 	SDA 	           	;发送起始条件的数据信号
	NOP
	SETB 	SCL 	           	;发送起始条件的时钟信号
	NOP 		           	;起始条件建立时间大于4.7 S
	NOP
	NOP
	NOP
	NOP
	CLR 	SDA 	            	;发送起始信号
	NOP 		             	;起始条件锁定时间大于4 S
	NOP
	NOP
	NOP
	NOP
	CLR 	SCL 	            	;钳住I2C 总线准备发送或接收数据
	RET
;---------------------------------------------------------------------------------------------------
;名称:STOP
;描述:停止I2C 总线子程序--发送I2C 总线停止条件
;---------------------------------------------------------------------------------------------------
STOP:	CLR 	SDA 	             	;发送停止条件的数据信号
	NOP
	SETB 	SCL 	             	;发送停止条件的时钟信号
	NOP 		             	;起始条件建立时间大于4 s
	NOP
	NOP
	NOP
	NOP
	SETB 	SDA 	             	;发送I2C 总线停止信号
	NOP
	NOP
	NOP
	NOP
	RET
;------------------------------------------------------------------------------------
;名称:SentByte
;描述:字节数据传送子程序发送一个字节数据或地址给被控器PCF8583
;要发送的数据在ACC 中
;发送数据正常返回标志F0=0 F0=1 表示被控器无应答或损坏
;-------------------------------------------------------------------------------------
SENTBYTE:MOV 	B,#08H      	;要传送的数据长度为8 位
SENTB:	RLC 	A 		        ;要发送的数据左移,发送位入C
	JC 	SENT1 	        	;发送位为“1”转发送数据位“1”
	CLR 	SDA 	         	;发送数据位“0”
	SJMP 	SENT 	         	;转发送数据位
SENT1:	SETB 	SDA 	         	;发送数据位“1”
	NOP
SENT:	NOP
	SETB 	SCL 	        	;置时钟线为高通知被控器开始接收数据位
	NOP 		         	;保证时钟高周期大于4 S
	NOP
	NOP
	NOP
	NOP
	CLR 	SCL 	         	;钳住总线准备接收下一个数据位
	DJNZ 	B,SENTB         	;8 位没发送完继续发送
	NOP
	NOP
	SETB 	SDA 	          	;8 位发送完后释放数据线准备收应答位
	NOP
	NOP
	SETB 	SCL 	          	;开始接收应答信号
	NOP
	NOP
	CLR 	F0 		        ;预先清发送数据出错标志
	JNB 	SDA, ACKEND            	;判断是否接收到应答信号正常转ACKEND
	SETB 	F0 	           	;未收到应答置位错误标志
ACKEND:	NOP
	CLR 	SCL 	           	;发送结束钳住总线准备下一步发送或接收数据或进行其它处理
	RET
;----------------------------------------------------------------------------------------------------
;名称:RCVBYTE
;描述:字节数据接收子程序从被控器PCF8583 接收一个字节数据然后根据主程序要求发送应答位
;接收的字节数据在ACC 中
;---------------------------------------------------------------------------------------------------
RCVBYTE:SETB 	SDA 	           	;置数据线为输入方式
	MOV 	B,#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 	B,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
TABLE1: DB      7EH,0BEH,0DEH,0EEH      
        DB      7DH,0BDH,0DDH,0EDH
        DB      7BH,0BBH,0DBH,0EBH
        DB      77H,0B7H,0D7H,0E7H
             END 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?