⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jzhave3out.asm

📁 PS2键盘通信程序 不知道能用不
💻 ASM
字号:
		  ORG 	0000H
		  LJMP	WAIT
		  ORG	0080H
WAIT:     
		  MOV P2,#0F0H   			 ;USE P2.0~P2.3
		  MOV P1,#0FFH
	          MOV A,P0				;USE P0.0~P0.3
		  ANL A,#0FH				;准备判断低四位
		  MOV R2,A			 	;R2存储P0低四位,以避免反复读取P0
		  ;CLR C
		  ;SUBB A,#07H				;判断第一行(L5)被拉低否
		  ;JZ HAVEONE0
		  JNB	ACC.3,GETIT
		  MOV A,R2
		  ;CLR C	
		  ;SUBB A,#0BH
		  ;JZ	HAVEONE1
		  JNB	ACC.2,GETIT
		  MOV A,R2				;USE P0.0~P0.3	;准备判断低四位
		  ;CLR C
		  ;SUBB A,#0DH
		  ;JZ	HAVEONE2
		  JNB	ACC.1,GETIT
		  MOV A,R2				;USE P0.0~P0.3	;准备判断低四位
		  ;CLR C
		  ;SUBB	A,#0EH
		  ;JZ	HAVEONE3
		  JNB	ACC.0,GETIT
		  LJMP	WAIT
;---------------------确定按键位置,并输出-----------------------------------
;HAVEONE0:
GETIT:		LCALL	DELAY10MS
		MOV	A,P0
		ANL	A,#0FH
		;CJNE 	A,#07H,WAIT			;确定是第一行有键按下? 没有则返回扫描主程序
		;LCALL	GETCOLUMN			;确定哪列,值放在R4中C2~C5对应为0~3
		;MOV	DPTR,#TABLE
		;MOV	A,R2 				;FAULT
		JNB	ACC.3,HAVEONE0
		JNB	ACC.2,HAVEONE1
		JNB	ACC.1,HAVEONE2
		JNB	ACC.0,HAVEONE3
		LJMP	WAIT
		;ADD	R4,#0
HAVEONE0:	LCALL	GETCOLUMN			;确定哪列,值放在R4中C2~C5对应为0~3
		MOV	DPTR,#TABLE
		MOV	A,R4
		ADD	A,#0
		MOVC	A,@A+DPTR			;读通码到A中
		MOV	R5,A
		MOV	R6,A				;暂存于R6中,备断码显示时候调用
		GOTO	TOSHOW	;---------调试时候考虑调用子程序
HAVEONE1:	LCALL	GETCOLUMN			;确定哪列,值放在R4中C2~C5对应为0~3
		MOV	DPTR,#TABLE
		MOV	A,R4
		ADD	A,#4
		MOVC	A,@A+DPTR			;读通码到A中
		MOV	R5,A
		MOV	R6,A
		GOTO	TOSHOW
HAVEONE2:	LCALL	GETCOLUMN			;确定哪列,值放在R4中C2~C5对应为0~3
		MOV	DPTR,#TABLE
		MOV	A,R4
		ADD	A,#8
		MOVC	A,@A+DPTR			;读通码到A中
		MOV	R5,A
		MOV	R6,A
		GOTO	TOSHOW
HAVEONE3:	LCALL	GETCOLUMN			;确定哪列,值放在R4中C2~C5对应为0~3
		MOV	DPTR,#TABLE
		MOV	A,R4
		ADD	A,#12
		MOVC	A,@A+DPTR			;读通码到A中
		MOV	R5,A
		MOV	R6,A
TOSHOW:		LCALL	DISPLAY				;发送通码+断码
WAITING:	MOV	A,P0				;查询按键弹起,并发出断码
		ANL 	A,#0FH
		CJNE	A,#0FH,WAITING
		MOV	R5,#0F0H
		MOV	A,R5
		LCALL	DISPLAY				;发送断码F0
		MOV	A,R6
		MOV	R5,A
		LCALL	DISPLAY				;发送断码的第2部分
		NOP
		LJMP	WAIT

;BACK:		LJMP	WAIT
;--------------------查询C2~C4,以确定哪列有键被按下------------------------------
GETCOLUMN:						;确定哪列为低
		;MOV A,R0
		;MOV	R2,A
		MOV	P2,#0F7H
		MOV 	A,P0
		ANL 	A,#0FH
		CLR 	C
		SUBB	A,#0FH
		JZ 	NEXT				;第一列?
		MOV	R4,#0         			;是
		SJMP	GETOUT
NEXT:		MOV	P2,#0FBH
		MOV	A,P0
		ANL	A,#0FH
		CLR	C
		SUBB	A,#0FH
		JZ 	NEXT1				;第二列?
		MOV	R4,#1				;是
		SJMP	GETOUT
NEXT1:		MOV	P2,#0FDH
		MOV 	A,P0
		ANL 	A,#0FH
		CLR 	C
		SUBB	A,#0FH
		JZ 	NEXT2				;第三列?
		MOV	R4,#2    			;是
NEXT2:		MOV	P2,#0FEH
		MOV 	A,P0
		ANL 	A,#0FH
		CLR 	C
		SUBB	A,#0FH
		JZ 	GETOUT				;第四列?都否,则退出子程序
		MOV	R4,#3    			;是
GETOUT:		;MOV	A,R2
		;MOV	R0,A
		RET
;-------------------延时10MS------------------------------------------
DELAY10MS:						;延时10MS程序,数字还需要再确定下?????????
    		MOV R6,#10
D1:         	MOV R7,#248
D2:		DJNZ R7,D2
    		DJNZ R6,D1
    		RET
;------------------输出显示程序---------------------------------------
DISPLAY:														;通码已经在R5和A中----------------------
		MOV C,P3.2      			;查询时钟线是否为高,若为低,PC主机禁止通
         	JNC GOOUT      				;信,跳出
	      	CLR P3.1      				;通信起始位0送出
          	MOV R0,8
          	;MOV R6,A				;因为后面直接使用R5中的数据,空出寄存器R6
          	CLR P3.0         			;清零位P3.0,准备停止位输出的条件
PS2SET:   	MOV TMOD,#10H 				;T1模式1,定时
	      	SETB TR1        			;启动T1
LOOP:   	MOV TH1,#0FFH  				;T1计数初值
 		MOV TL1, #0D6H  
LOOP1:  	JNB  TF1, LOOP1  			;等待T1溢出
	 	CLR TF1          			;产生溢出清标志位
	 	CPL P3.2          			;取反输出
	 	JNB P3.2,LOOP    			;判断是否为上升沿;否,则不输出新数据
	 	JB P3.0, OUTSTOP  			;输出奇校验后的下一时钟输出停止位
		RRC A            			;假定已经将要传送的数据放入A,带进位移位
	 	MOV P3.1,C       			;输出新1位数据
	 	MOV R1,A         			;保存移位后的数据
	 	;DEC R0           			;准备判断8位数据是否全部输出
		DJNZ R0, LOOP     			;8位数据未输出完;若完,准备输出奇校验位
		SETB P3.0   ;--------调试时候需要斟酌
		MOV A,R5				;通过PSW.0判断输出数据的奇偶,1为奇
	 	MOV C,PSW.0
		MOV P3.1, C				;输出奇校验位
		SJMP LOOP
OUTSTOP: 	SETB P3.1     				;输出停止位1
GOOUT:		RET
	
TABLE:		DB	45H,16H,1EH,26H,25H,2EH,36H,3DH     ;通码表
		DB	3EH,46H,1CH,32H,21H,23H,24H,2BH
		END

⌨️ 快捷键说明

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