用汇编语言编写独立式键盘的扫描程序

用汇编语言编写独立式键盘的扫描程序,第1张

这个简单,我来好了:

ORG 0000H

AJMP MAIN

ORG 0010H

MAIN:MOV P0,#0FFH 给按键接口赋高电平

MOV A,P0 假设P1.0是开,P1.1是关开关

SUBB A,#FE

ACALL DELAY去抖

JZ RUN

SUBB A,#FD

ACALL DELAY去抖10MS

JZ STOP

SJMP MAIN

RUN: MOV P2,#0FEH假设P2.0是控制口,低电平开

SJMP MAIN

STOP: MOV P2,#0FEH假设P2.0是控制口,高电平关

SJMP MAIN

DELAY: MOV R7,#08H

DELAY1:MOV R6,#0FFH

DELAY2:DJNZ R6,DELAY2

DJNZ R7,DELAY1

RET

END

P1口接键盘进行扫描,P2口接数码管的位码,P0口接数码管的段码

ORG 0000H

LJMP START

ORG 0030H

START:

MOV 30H,#10H 第8个数码管显示数据缓存寄存器

MOV 31H,#10H 第7个数码管显示数据缓存寄存器

MOV 32H,#10H 第6个数码管显示数据缓存寄存器

MOV 33H,#10H 第5个数码管显示数据缓存寄存器

MOV 34H,#10H 第4个数码管显示数据缓存寄存器

MOV 35H,#10H 第3个数码管显示数据缓存寄存器

MOV 36H,#10H 第2个数码管显示数据缓存寄存器

MOV 37H,#10H 第1个数码管显示数据缓存寄存器

MAIN:

LCALL SAOMIAO 调用键盘扫描寄存器

LCALL DISPLAY 调用显示寄存器

LJMP MAIN

SAOMIAO:

MOV P1,#11111110B 将P1.4-P1.7口做为输入检测口,屏蔽P1.0-P1.3三行按键,扫描P0.0行的按键

JNB P1.4,A0第一行第一个按键被按下,则跳至A0

JNB P1.5,A1第一行第二个按键被按下,则跳至A1

JNB P1.6,A2第一行第三个按键被按下,则跳至A2

JNB P1.7,A3第一行第四个按键被按下,则跳至A3

MOV P1,#11111101B 扫描P0.1接的第二行

JNB P1.4,A4第二行第一个按键被按下,则跳至A4

JNB P1.5,A5

JNB P1.6,A6

JNB P1.7,A7

MOV P1,#11111011B

JNB P1.4,A8

JNB P1.5,A9

JNB P1.6,A10

JNB P1.7,A11

MOV P1,#11110111B

JNB P1.4,A12

JNB P1.5,A13

JNB P1.6,A14

JNB P1.7,A15

RET

A0:

LJMP AN0 由于JNB指令的跳转范围仅为8位,所以用LJMP跳入按键处理子程序

A1:

LJMP AN1

A2:

LJMP AN2

A3:

LJMP AN3

A4:

LJMP AN4

A5:

LJMP AN5

A6:

LJMP AN6

A7:

LJMP AN7

A8:

LJMP AN8

A9:

LJMP AN9

A10:

LJMP AN10

A11:

LJMP AN11

A12:

LJMP AN12

A13:

LJMP AN13

A14:

LJMP AN14

A15:

LJMP AN15

AN0:

LCALL DISPLAY

MOV P1,#11111110B

JNB P1.4,AN0 按键消抖

MOV 3FH,#0 将按键值送入按键缓存寄存器

LJMP YIDONG调用移动子程序

AN1:

LCALL DISPLAY

MOV P1,#11111110B

JNB P1.5,AN1

MOV 3FH,#1

LJMP YIDONG

AN2:

LCALL DISPLAY

MOV P1,#11111110B

JNB P1.6,AN2

MOV 3FH,#2

LJMP YIDONG

AN3:

LCALL DISPLAY

MOV P1,#11111110B

JNB P1.7,AN3

MOV 3FH,#3

LJMP YIDONG

AN4:

LCALL DISPLAY

MOV P1,#11111101B

JNB P1.4,AN4

MOV 3FH,#4

LJMP YIDONG

AN5:

LCALL DISPLAY

MOV P1,#11111101B

JNB P1.5,AN5

MOV 3FH,#5

LJMP YIDONG

AN6:

LCALL DISPLAY

MOV P1,#11111101B

JNB P1.6,AN6

MOV 3FH,#6

LJMP YIDONG

AN7:

LCALL DISPLAY

MOV P1,#11111101B

JNB P1.7,AN7

MOV 3FH,#7

LJMP YIDONG

AN8:

LCALL DISPLAY

MOV P1,#11111011B

JNB P1.4,AN8

MOV 3FH,#8

LJMP YIDONG

AN9:

LCALL DISPLAY

MOV P1,#11111011B

JNB P1.5,AN9

MOV 3FH,#9

LJMP YIDONG

AN10:

LCALL DISPLAY

MOV P1,#11111011B

JNB P1.6,AN10

MOV 3FH,#10

LJMP YIDONG

AN11:

LCALL DISPLAY

MOV P1,#11111011B

JNB P1.7,AN11

MOV 3FH,#11

LJMP YIDONG

AN12:

LCALL DISPLAY

MOV P1,#11110111B

JNB P1.4,AN12

MOV 3FH,#12

LJMP YIDONG

AN13:

LCALL DISPLAY

MOV P1,#11110111B

JNB P1.5,AN13

MOV 3FH,#13

LJMP YIDONG

AN14:

LCALL DISPLAY

MOV P1,#11110111B

JNB P1.6,AN14

MOV 3FH,#14

LJMP YIDONG

AN15:

LCALL DISPLAY

MOV P1,#11110111B

JNB P1.7,AN15

MOV 3FH,#15

LJMP YIDONG

YIDONG: 移动子程序,将数码管数字向左移动一位

MOV 37H,36H

MOV 36H,35H

MOV 35H,34H

MOV 34H,33H

MOV 33H,32H

MOV 32H,31H

MOV 31H,30H

MOV 30H,3FH

RET

DISPLAY:

MOV DPTR,#TAB

MOV A,30H

MOVC A,@A+DPTR

MOV P0,A

MOV P2,#11101111B

LCALL DELAY

MOV DPTR,#TAB

MOV A,31H

MOVC A,@A+DPTR

MOV P0,A

MOV P2,#11011111B

LCALL DELAY

MOV DPTR,#TAB

MOV A,32H

MOVC A,@A+DPTR

MOV P0,A

MOV P2,#10111111B

LCALL DELAY

MOV DPTR,#TAB

MOV A,33H

MOVC A,@A+DPTR

MOV P0,A

MOV P2,#01111111B

LCALL DELAY

MOV DPTR,#TAB

MOV A,34H

MOVC A,@A+DPTR

MOV P0,A

MOV P2,#11111110B

LCALL DELAY

MOV DPTR,#TAB

MOV A,35H

MOVC A,@A+DPTR

MOV P0,A

MOV P2,#11111101B

LCALL DELAY

MOV DPTR,#TAB

MOV A,36H

MOVC A,@A+DPTR

MOV P0,A

MOV P2,#11111011B

LCALL DELAY

MOV DPTR,#TAB

MOV A,37H

MOVC A,@A+DPTR

MOV P0,A

MOV P2,#11110111B

LCALL DELAY

RET

TAB:

DB 03H 9FH 25H 0DH 99H 49H 41H 1FH 03H到071H是表示0到F

DB 01H 19H 11H 0C1H 0E5H 85H 21H 71H

DB 0FFH“0”——“F”再加上不显示,一共十七个代码

DELAY:

MOV R6,#5

D1:

MOV R7,#255

DJNZ R7,$

DJNZ R6,D1

RET

这是一个典型的T扫电路,具体代码我就不说了,我现在来说一下它的原理

扫描是一次把一个IO置0,其它的IO均为输入状态(51是准双向IO,没有输入输出概念,把输出高当输入即可)。比如说,现在是扫描P00,那么把P00写0,其它的IO写1,然后把所有的IO读取回来,把值赋给一个临时变量用来判断,eg key_buffer_temp =P0把扫描(写0的相应)位强制性写上1, 即

key_buffer_temp=key_buffer_temp|0x01这时看这个key_buffer_temp的值,有没有位是0的,即这个值是不是0xff,如果是0xff,则和P00接的按键都没有按键。如果不是0xff,则有几位是0就有几个按键。这样循环下去,一直扫到P06(不用扫P07)。

程序的注意点:

1扫描P00时,只看读回来key_buffer_temp的位1--位7,扫描P01时,只看读回来key_buffer_temp的位2--位7,……扫描P06时,只看读回来key_buffer_temp的位7,不用扫描P07

2每扫描一个就判断一次key_buffer_temp的值,一个个位来判断,同时把计数加1,如果有按键则把计数的值赋给key_value0,key_value1……

3扫描结束后看key_value0,key_value1……里面的值,有几个就几个按键

4比如说key_value0为1,key_value为10,那么就是S1,和S10有按键

至于消抖,这一般的做法就是多采样几次


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12123123.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存