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

📄 kb.asm

📁 ps/2键盘程序 采用第2套编码方式
💻 ASM
字号:
;晶振: 11.0592
RED_LED  	EQU P1.0
GREEN_LED 	EQU P1.1

KEY_CLOCK	EQU P3.3
KEY_DATA	EQU P3.4

DLY20 		EQU 20;14H;17
DLY30 		EQU 30;1EH;27
DLY40 		EQU 40;28H;36
DLY50 		EQU 50;32H;45

	org	0000H
	ljmp	start
	org	0050H
start:
	mov	sp,#0030H
	mov	p1,#0FFH
	mov	p2,#0FFH
	mov	r1,#0FFH
l1:	mov	r3,#0FFH
	djnz	r3,$
	djnz	r1,l1

	setb	KEY_CLOCK
	setb 	KEY_DATA
loop:
	setb	RED_LED
	clr 	GREEN_LED
key0:
	jnb	P2.0,key1
	jnb	P2.1,key2
	jnb	P2.2,key3
	jnb	P2.3,key4
	jnb	P2.4,key5
	jnb	P2.5,key6
	jmp	key0;
key1:
	mov	r4,#16H	;1
	jmp	key
key2:
	mov	r4,#1EH	;2
	jmp	key
key3:
	mov	r4,#26H	;3
	jmp	key
key4:
	mov	r4,#25H	;4
	jmp	key
key5:
	mov	r4,#2EH	;5
	jmp	key
key6:
	mov	r4,#36H	;6
key:
	setb	GREEN_LED
	clr	RED_LED
loopa1:
	jnb	KEY_CLOCK,$	;1. 等待时钟转为高电平
	mov	r1,#DLY50	;2. 延时 50us
	djnz	r1,$		;	 50us*11.0592/12-1
	jnb	KEY_CLOCK,loopa1;3. 不是高电平的话,回到第一步
	jnb	KEY_DATA,loop	;4. 不是高电平的话,放弃发送,转为接收
	mov	r1,#DLY20	;5. 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;6. 发送起始位 0
	clr	KEY_DATA	
	mov	r1,#DLY20	;6.1 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	;6.2 拉低时钟
	mov	r1,#DLY40	;6.3 延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK	;6.4 释放时钟
	mov	r1,#DLY20	;6.5 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送

	;7. 发送8位数据
	clr	a
	mov	r5,a		;r5为发送计数
	mov	r3,#0	;效验位计数复位
	mov	r6,#01
nexta1:
	mov	a,r6
	anl	a,r4	;要发送的字符放在r4中
	jnz	bita1
	clr	KEY_DATA
	sjmp	nexta2
bita1:	
	setb	KEY_DATA
	inc	r3	;为1的个数加1
nexta2:	
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	;拉低时钟
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK	;释放时钟
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送
	;JNB	KEY_CLOCK,SEND_BYTE
	mov	a,r6
	add     a,acc
	mov	r6,a
	inc	r5		;发送位数加1
	cjne	r5,#08,nexta1	;连续发送8位
	;发送效验位
	mov	a,r3	
	anl	a,#01
	jz	nexta3
	clr	KEY_DATA
	sjmp	nexta4
nexta3:
	setb	KEY_DATA
nexta4:
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送
	;JNB	KEY_CLOCK,SEND_BYTE
	;发送停止位
	setb	KEY_DATA
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK
	mov	r1,#DLY30	;延时30us
	djnz	r1,$		;	30us*11.0592/12-1

;==================================================================
loopb1:
	jnb	KEY_CLOCK,$	;1. 等待时钟转为高电平
	mov	r1,#DLY50	;2. 延时 50us
	djnz	r1,$		;	 50us*11.0592/12-1
	jnb	KEY_CLOCK,loopb1;3. 不是高电平的话,回到第一步
	jnb	KEY_DATA,loopb1	;4. 不是高电平的话,放弃发送,转为接收
	mov	r1,#DLY20	;5. 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;6. 发送起始位 0
	clr	KEY_DATA	
	mov	r1,#DLY20	;6.1 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	;6.2 拉低时钟
	mov	r1,#DLY40	;6.3 延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK	;6.4 释放时钟
	mov	r1,#DLY20	;6.5 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送

	;7. 发送8位数据
	clr	a
	mov	r5,a		;r5为发送计数
	mov	r3,#0		;效验位计数复位
	mov	r6,#01
nextb1:
	mov	a,r6
	anl	a,#0F0H		;发送F0
	jnz	bitb1
	clr	KEY_DATA
	sjmp	nextb2
bitb1:	
	setb	KEY_DATA
	inc	r3		;为1的个数加1
nextb2:	
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	;拉低时钟
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK	;释放时钟
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送
	;JNB	KEY_CLOCK,SEND_BYTE
	mov	a,r6
	add     a,acc
	mov	r6,a
	inc	r5		;发送位数加1
	cjne	r5,#08,nextb1	;连续发送8位
	;发送效验位
	mov	a,r3	
	anl	a,#01
	jz	nextb3
	clr	KEY_DATA
	sjmp	nextb4
nextb3:
	setb	KEY_DATA
nextb4:
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送
	;JNB	KEY_CLOCK,SEND_BYTE
	;发送停止位
	setb	KEY_DATA
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK
	mov	r1,#DLY30	;延时30us
	djnz	r1,$		;	30us*11.0592/12-1
;=
loopc1:
	jnb	KEY_CLOCK,$	;1. 等待时钟转为高电平
	mov	r1,#DLY50	;2. 延时 50us
	djnz	r1,$		;	 50us*11.0592/12-1
	jnb	KEY_CLOCK,loopc1;3. 不是高电平的话,回到第一步
	jnb	KEY_DATA,loopc1	;4. 不是高电平的话,放弃发送,转为接收
	mov	r1,#DLY20	;5. 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;6. 发送起始位 0
	clr	KEY_DATA	
	mov	r1,#DLY20	;6.1 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	;6.2 拉低时钟
	mov	r1,#DLY40	;6.3 延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK	;6.4 释放时钟
	mov	r1,#DLY20	;6.5 延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送

	;7. 发送8位数据
	clr	a
	mov	r5,a		;r5为发送计数
	mov	r3,#0		;效验位计数复位
	mov	r6,#01
nextc1:
	mov	a,r6
	anl	a,r4		;要发送的字符放在KEY_BUFF中
	jnz	bitc1
	clr	KEY_DATA
	sjmp	nextc2
bitc1:	
	setb	KEY_DATA
	inc	r3		;为1的个数加1
nextc2:	
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	;拉低时钟
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK	;释放时钟
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送
	;JNB	KEY_CLOCK,SEND_BYTE
	mov	a,r6
	add     a,acc
	mov	r6,a
	inc	r5		;发送位数加1
	cjne	r5,#08,nextc1	;连续发送8位
	;发送效验位
	mov	a,r3	
	anl	a,#01
	jz	nextc3
	clr	KEY_DATA
	sjmp	nextc4
nextc3:
	setb	KEY_DATA
nextc4:
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK	
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	;测试主机是否放弃这次传送
	;JNB	KEY_CLOCK,SEND_BYTE
	;发送停止位
	setb	KEY_DATA
	mov	r1,#DLY20	;延时20us
	djnz	r1,$		;	20us*11.0592/12-1
	clr	KEY_CLOCK
	mov	r1,#DLY40	;延时40us
	djnz	r1,$		;	40us*11.0592/12-1
	setb	KEY_CLOCK
	mov	r1,#DLY30	;延时30us
	djnz	r1,$		;	30us*11.0592/12-1
	
	mov	r1,#0FFH
dly2:	mov	r3,#0FFH
	djnz	r3,$
	djnz	r1,dly2

	ljmp	loop

end

⌨️ 快捷键说明

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