注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
ginny的个人空间 https://home.eeworld.com.cn/space-uid-200931.html [收藏] [复制] [分享] [RSS]
日志

单片机按键设计方法探究

已有 5020 次阅读2010-3-17 20:44 |个人分类:我的论文

单片机按键设计方法探究

汪志军

(南昌航空大学  10406

 

摘要:介绍单片机按键设计方法,简要坦述它们设计思路和原理。

 

关键词:按键设计   51单片机

 

引言: 自单片机诞生以后,它就步入人们的生活,如洗衣机、电冰箱、电子玩具等家用电器配上单片机后,提高了智能化程度,增加了功能,倍受人们喜爱。本论文介绍了如何更好的设计单片机外部按键,充分利用单片机IO口。

作者概述:本论文主要讲述单片机按键设计方法,电路图和汇编程序都较为简单。写本论文的目的是为了使读者对按键有更深的了解,论文重在设计启发,激发大家自己设计更好的按键方法。论文全部的程序和电路图都是作者亲自制作,有些设计思路是从网上书上获得的,有些是自己想出来的。本人希望以自己的亲身感受来谈谈自己对按键设计方法的认识。本论文程序设计可能会有点乱,希望读者原谅,同时也欢迎读者提出本论文的错误或不足。

 

作者联系方式——邮箱:gin0101@126.com  

QQ382594424

 

本论文主要介绍:1、独立按键 2、矩阵按键 3、组合键式按键 4、累加式按键 5、编码器按键 6AD按键 7、二进制式按键 8、频率式按键 9、模块克隆式按键10、其他按键(长按与短按、单击与双击)

 

为了尽量简化本论文,该论文使用的汇编程序大部分只写出它的按键扫描程序。所有按键的键值都储存在寄存器R1中,键值通过P1口各个IO口的高低电平显示,P2口与按键连接。

 

部分按键设计需要利用到得测试程序。


ORG 0000H

        LJMP MAIN

        ORG 0100H

MAIN:    

        LCALL KEYSCAN

        MOV P1,R1                                             ;把键值赋给P1

        JMP MAIN

;----------按键扫描子程序-----------

TIME20MS:

             MOV R6,#40

GIN:        MOV R7,#250

        DJNZ R7,$

        DJNZ R6,GIN

        RET

END


下面将分别介绍这些按键的具体设计

1.      独立按键

1.1    电路图

 

 

 

 

 

 

 

 

1

1.2     汇编程序

;按键扫描子程序


KEYSCAN:

         MOV P2,#0FFH

         MOV A,P2

         CJNE A,#0FFH,AGAIN1

         JMP EXIT

AGAIN1:  LCALL TIME20MS             ;延时去抖动

         MOV A,P2

         CJNE A,#0FFH,KEYSCAN1

         JMP EXIT

KEYSCAN1:                         ;键值查找

         MOV R1,#0

AGAIN2:  INC R1

         RRC A

         JC AGAIN2

EXIT:         RET


1.3    设计思路

   独立按键设计是简单的按键设计方法。是大部分人第一次接触的按键方法。它适用于按键比较少的设计电路中使用。5132IO口,最多只能安放32个独立按键。

优点:设计简单、容易控制、支持多点操作

缺点:占用单片机的IO口多

 

2.      矩阵按键

2.1    电路图

2

2.2    汇编程序

2.2.1逐点扫描法

KEYSCAN:

         MOV P2,#0F0H

         MOV A,P2

         CJNE A,#0F0H,AGAIN

         JMP EXIT

AGAIN:    LCALL TIME20MS             ;延时去抖动

         MOV A,P2

         CJNE A,#0F0H,KEYSCAN1        ;查找是否有键按下

         JMP EXIT

KEYSCAN1:                         ;第一行扫描

         MOV P2,#0FEH

         MOV A,#0

KEYSCAN1_1:                     ;第一行第一例扫描

         JB P2.4,KEYSCAN1_2

         JMP ADD1

KEYSCAN1_2:                     ;第一行第二例扫描

         JB P2.5,KEYSCAN1_3

         JMP ADD2

KEYSCAN1_3:                     ;第一行第三例扫描

         JB P2.6,KEYSCAN1_4

         JMP ADD3

KEYSCAN1_4:                     ;第一行第四例扫描

         JB P2.7,KEYSCAN2

         JMP ADD4

KEYSCAN2:                         ;第二行扫描

         MOV P2,#0FDH

         MOV A,#4

KEYSCAN2_1:

         JB P2.4,KEYSCAN2_2

         JMP ADD1

KEYSCAN2_2:

         JB P2.5,KEYSCAN2_3

         JMP ADD2

KEYSCAN2_3:

         JB P2.6,KEYSCAN2_4

         JMP ADD3

KEYSCAN2_4:

         JB P2.7,KEYSCAN3

         JMP ADD4

KEYSCAN3:                         ;第三行扫描

         MOV P2,#0FBH

         MOV A,#8

KEYSCAN3_1:

         JB P2.4,KEYSCAN3_2

         JMP ADD1

KEYSCAN3_2:

         JB P2.5,KEYSCAN3_3

         JMP ADD2

KEYSCAN3_3:

         JB P2.6,KEYSCAN3_4

         JMP ADD3

KEYSCAN3_4:

         JB P2.7,KEYSCAN4

         JMP ADD4

KEYSCAN4:                         ;第四行扫描

         MOV P2,#0F7H

         MOV A,#12

KEYSCAN4_1:

         JB P2.4,KEYSCAN4_2

         JMP ADD1

KEYSCAN4_2:

         JB P2.5,KEYSCAN4_3

         JMP ADD2

KEYSCAN4_3:

         JB P2.6,KEYSCAN4_4

         JMP ADD3

KEYSCAN4_4:

         JMP ADD4

ADD1:       ADD A,#1

         JMP EXIT1

ADD2:       ADD A,#2

         JMP EXIT1

ADD3:       ADD A,#3

         JMP EXIT1

ADD4:       ADD A,#4

EXIT1:       MOV R1,A

EXIT:         RET

2.2.2逐行(列)扫描法

KEYSCAN:

         MOV P2,#0F0H

         MOV A,P2

         CJNE A,#0F0H,AGAIN

         JMP EXIT

AGAIN:    LCALL TIME20MS             ;延时去抖动

         MOV A,P2

         CJNE A,#0F0H,KEYSCAN1        ;查找是否有键按下

         JMP EXIT

KEYSCAN1:                         ;第一行扫描

         MOV P2,#0FEH

         MOV R1,#0

         MOV A,P2

         ANL A,#0F0H

         CJNE A,#0F0H,FUZHI

KEYSCAN2:                         ;第二行扫描

         MOV P2,#0FDH

         MOV R1,#4

         MOV A,P2

         ANL A,#0F0H

         CJNE A,#0F0H,FUZHI

KEYSCAN3:                         ;第三行扫描

         MOV P2,#0FBH

         MOV R1,#8

         MOV A,P2

         ANL A,#0F0H

         CJNE A,#0F0H,FUZHI

KEYSCAN4:                        ;第四行扫描               

         MOV P2,#0F7H

         MOV R1,#12

         MOV A,P2

         ANL A,#0F0H

         CJNE A,#0F0H,FUZHI

FUZHI:      MOV R2,A                  ;给键值赋值

         MOV A,R1

         CJNE R2,#0E0H,ADD2

ADD1:       ADD A,#1

         JMP EXIT1

ADD2:       CJNE R2,#0D0H,ADD3

         ADD A,#2

         JMP EXIT1

ADD3:       CJNE R2,#0B0H,ADD4

         ADD A,#3

         JMP EXIT1

ADD4:       ADD A,#4

EXIT1:       MOV R1,A

EXIT:         RET

2.2.3 反转扫描法

KEYSCAN:

         MOV P2,#0F0H

         MOV A,P2

         CJNE A,#0F0H,AGAIN

         JMP EXIT

AGAIN:    LCALL TIME20MS             ;延时去抖动

         MOV A,P2

         CJNE A,#0F0H,KEYSCAN1        ;查找是否有键按下

         JMP EXIT

KEYSCAN1:

         MOV P2,#0FH

         MOV B,P2

         ORL A,B

         MOV B,A

         MOV DPTR,#TABLE

         MOV R1,#0

AGAIN2:  MOV A,R1

         MOVC A,@A+DPTR

         CJNE A,B,INCR1                 ;通过表中的值来确定键值

         JMP EXIT1

INCR1:      INC R1

         JMP AGAIN2

EXIT1:       INC R1

EXIT:         RET

TABLE:     DB 0EEH,0DEH,0BEH,7EH         ;键值表

         DB 0EDH,0DDH,0BDH,7DH

         DB 0EBH,0DBH,0BBH,7BH

         DB 0E7H,0D7H,0B7H,77H

 

2.3    设计思路

矩阵按键扫描法是比较好的按键设计方法,51单片机32IO口最多可以组成16*16=256个按键。上面介绍了三种扫描方式,下面来一一介绍他们的不同。

首先,逐点扫描法,它扫描的时间相对要多一点,它可以直接对每一个按键进行扫描,所以它可以扫描到同时多个键按下,支持多点。利用这种扫描方式,可以允许组合键的使用,而且不会混淆;再次,逐行(列)扫描法,扫描时间相对少,是逐行(列)扫描,支持多点,可以允许组合键的使用;最后,反转扫描法,扫描时间最少,最大的特点是利用了查表来确定键值,不支持多点。

在给出的程序中都没牵涉多点操作,只在单个按键按下有效。如果要考虑组合键的使用则使用逐点扫描法较好。

3.      组合键式按键

3.1    电路图

3

3.2    汇编程序

KEYSCAN:

         MOV P2,#3FH

         MOV A,P2

         CJNE A,#3FH,AGAIN

         JMP EXIT

AGAIN:    LCALL TIME20MS

         MOV A,P2

         CJNE A,#3FH,KEYSCAN1

         JMP EXIT

KEYSCAN1:MOV P2,#0FFH                ;第一轮扫描

         MOV R1,#0

         CLR P2.7

         NOP

         JNB P2.5,ADD1

         JNB P2.4,ADD2

         JMP KEYSCAN2

ADD1:       MOV A,R1

         ADD A,#1

         MOV R1,A

         JNB P2.4,ADD2

         JMP KEYSCAN2

ADD2:       MOV A,R1

         ADD A,#2

         MOV R1,A

KEYSCAN2:MOV P2,#0FFH                ;第二轮扫描

         CLR P2.6

         NOP

         JNB P2.5,ADD4

         JNB P2.4,ADD6

         JMP EXIT

ADD4:       MOV A,R1

         ADD A,#4

         MOV R1,A

         JNB P2.4,ADD6

         JMP EXIT1

ADD6:       MOV A,R1

         ADD A,#6

         MOV R1,A

EXIT1:       CJNE R1,#10,EXIT

         MOV R1,#7

EXIT:         RET

3.3    设计思路

在我们平时按键设计中,我们都是用两根电路线,但你们想没想过用三根或更多电路线组成一个按键呢。组合键式按键最大特点就是利用了组合键,把组合键也单立一个按键,所以它不支持多点。它的电路设计简单,但按键要求是可以同时开/关多条电路的复合按键。你可以把三条电路线复合成一个按键,也可以把四根电路线复合成一个按键,当然也可以同时复合。当你把三条电路线复合成一个按键,将可以组合:在总共四条电路线中选三条,有4种;当你把四条电路线复合成一个按键,将可以组合1个按键;在加上我们平时常用的两根电路线组成的按键,也就是四种选二有6种,这样四根电路线总共可以组成4+1+6=11个按键。

 

4.      累加式按键

4.1    电路图

4

4.2    汇编程序

KEYSCAN:

         MOV P2,#0FFH

KEYSCAN1:                                  ;键值小于等于8的扫描(18

         MOV A,P2

         CJNE A,#0FFH,KEYSCAN1_1

         JMP KEYSCAN2

KEYSCAN1_1:

         LCALL TIME20MS

         MOV A,P2

         CJNE A,#0FFH,KEYSCAN1_2

         JMP KEYSCAN2

KEYSCAN1_2:

         MOV R1,#0

AGAIN1:  INC R1

         RRC A

         JC AGAIN1

         JMP EXIT

KEYSCAN2:                                  ;键值大于8的扫描(936

KEYSCAN2_1:

         MOV P2,#0FEH

         MOV A,P2

         CJNE A,#0FEH,GIN2_1_1

         JMP KEYSCAN2_2

GIN2_1_1:LCALL TIME20MS

         MOV A,P2

         CJNE A,#0FEH,GIN2_1_2

         JMP KEYSCAN2_2

GIN2_1_2:MOV R1,#7

         ORL A,#1

AGAIN2_1:INC R1

         RRC A

         JC AGAIN2_1

         JMP EXIT

KEYSCAN2_2:

         MOV P2,#0FDH

         MOV A,P2

         CJNE A,#0FDH,GIN2_2_1

         JMP KEYSCAN2_3

GIN2_2_1:LCALL TIME20MS

         MOV A,P2

         CJNE A,#0FDH,GIN2_2_2

         JMP KEYSCAN2_3

GIN2_2_2:MOV R1,#13

         ORL A,#2

AGAIN2_2:INC R1

         RRC A

         JC AGAIN2_2

         JMP EXIT

KEYSCAN2_3:

         MOV P2,#0FBH

         MOV A,P2

         CJNE A,#0FBH,GIN2_3_1

         JMP KEYSCAN2_4

GIN2_3_1:LCALL TIME20MS

         MOV A,P2

         CJNE A,#0FBH,GIN2_3_2

         JMP KEYSCAN2_4

GIN2_3_2:MOV R1,#18

         ORL A,#4

AGAIN2_3:INC R1

         RRC A

         JC AGAIN2_3

         JMP EXIT

KEYSCAN2_4:

         MOV P2,#0F7H

         MOV A,P2

         CJNE A,#0F7H,GIN2_4_1

         JMP KEYSCAN2_5

GIN2_4_1:LCALL TIME20MS

         MOV A,P2

         CJNE A,#0F7H,GIN2_4_2

         JMP KEYSCAN2_5

GIN2_4_2:MOV R1,#22

         ORL A,#8

AGAIN2_4:INC R1

         RRC A

         JC AGAIN2_4

         JMP EXIT

KEYSCAN2_5:

         MOV P2,#0EFH

         MOV A,P2

         CJNE A,#0EFH,GIN2_5_1

         JMP KEYSCAN2_6

GIN2_5_1:LCALL TIME20MS

         MOV A,P2

         CJNE A,#0EFH,GIN2_5_2

         JMP KEYSCAN2_6

GIN2_5_2:MOV R1,#25

         ORL A,#10H

AGAIN2_5:INC R1

         RRC A

         JC AGAIN2_5

         JMP EXIT

KEYSCAN2_6:

         MOV P2,#0DFH

         MOV A,P2

         CJNE A,#0DFH,GIN2_6_1

         JMP KEYSCAN2_7

GIN2_6_1:LCALL TIME20MS

         MOV A,P2

         CJNE A,#0DFH,GIN2_6_2

         JMP KEYSCAN2_7

GIN2_6_2:MOV R1,#27

         ORL A,#20H

AGAIN2_6:INC R1

         RRC A

         JC AGAIN2_6

         JMP EXIT

KEYSCAN2_7:

         MOV P2,#0BFH

         MOV A,P2

         CJNE A,#0BFH,GIN2_7_1

         JMP EXIT

GIN2_7_1:LCALL TIME20MS

         MOV A,P2

         CJNE A,#0BFH,GIN2_7_2

         JMP EXIT

GIN2_7_2:MOV R1,#36

EXIT:         RET

4.3    设计思路

本方案按键可以分为两个方面,一个是独立按键,另一个是两线制组合按键。独立按键就不在这再叙述了,我们重点来讲讲两线制组合按键。

它分为七组,每一组都有一个公共端。扫描时把公共端置0,其它IO口都置1,然后读取被置1 IO口的值,为0则表明有键按下。它支持多点操作,但程序中没牵涉。一个端口有八个IO口(程序以P2为例),可以组成七组,有七个公共端,第一个公共端(图中为靠近51单片机的)可以设置七个按键,第二个公共端可以设置六个按键,其它公共端可以以此类推。这样可以组成7+6+5+4+3+2+1=28按键,再加上独立按键8个按键,这样一个端口就可以组成8+7+6+5+4+3+2+1=36(等式是一个累加式)个按键。

 

5.      编码器按键

5.1    电路图

5

 

5.2    汇编程序

KEYSCAN:

         SETB P2.0        ;SETB P2.0, SETB P2.1, SETB P2.2,而不直接MOV P2,#0FFH

         SETB P2.1         ; 是因为直接把0FFH赋给P2端口会影响其他没有参加按键扫描的IO

         SETB P2.2      ;但在本论文中有些程序是直接赋值的,这只是为了方便,简化程序

         MOV A,#0

         MOV C,P2.2

         RLC A

         MOV C,P2.1

         RLC A

         MOV C,P2.0

         RLC A

         CJNE A,#7,AGAIN

         JMP EXIT

AGAIN:    LCALL TIME20MS

         MOV A,#0

         MOV C,P2.2

         RLC A

         MOV C,P2.1

         RLC A

         MOV C,P2.0

         RLC A

         CJNE A,#7,FUZHI

         JMP EXIT

FUZHI:      XRL A,#7

         MOV R1,A

EXIT:         RET

 

 

5.3    设计思路

利用了8421编码器,当然如果有特别的要求也可以用优选编码器。38编码器,可以把51单片机的3IO口扩展到7个。在使用38编码器时一定要给编码器的8个输入端加上上拉电阻。有人会问38编码器怎么不是可以把51单片机的3IO口扩展到8个啊?为什么不是8个呢,因为单片机必须有一个默认状态也就是没有任何按键按下的时候,比如111,这要38编码器也就必须有一个默认状态,那就是第0输入端口保持为1。所以38编码器最多只能设置7个按键。它的程序较为简单,不支持多点操作。如果要进一步扩展IO口,可以将多个38编码器连接起来使用。

 

6.      AD按键

6.1    电路图

6

6.2       汇编程序

                  ORG 0000H

         LJMP MAIN

         ORG 0100H

MAIN:      

         MOV R1,#0

         MOV R2,#0

         MOV R3,#0

START:

         LCALL KEYSCAN

         MOV P1,R1

         NOP

         JMP START

KEYSCAN:

         CLR P2.0                    ;/CS0,使芯片开始工作

         NOP

         NOP

         SETB P2.1

         NOP

         NOP

         SETB P2.2

         NOP

         NOP

         CLR P2.1                     ;D1端口输入1

         NOP

         NOP

         SETB P2.1

         NOP

         NOP

         SETB P2.2

         NOP

         NOP

         CLR P2.1            ;D1端口输入1

         NOP

         NOP

         CLR P2.2

         NOP

         NOP

         SETB P2.1

         NOP

         NOP

         CLR P2.1                      ;D1端口输入0

         NOP

         NOP

         MOV R2,#8

         SETB P2.2

AGAIN1:  SETB P2.1          ;读取D0数据

         NOP

         NOP

         CLR P2.1

         MOV C,P2.2

         RLC A

         DJNZ R2,AGAIN1

         SETB P2.0

         MOV R2,A

GINNY:     MOV DPTR,#TABLE

         MOV R3,#0

WZQ:         MOV A,R3

         MOVC A,@A+DPTR

         CJNE A,#255,WZQWZJ                ;不加这条程序初始AD的误转换使R1超出范围,没有按下键R1也被赋值而且超出了键值范围

         JMP EXIT

WZQWZJ: SUBB A,R2

         JC INCR3

         CJNE R3,#0,FUR1

         JMP EXIT

FUR1:        MOV A,R3

         MOV R1,A

         JMP EXIT

INCR3:      INC R3

         JMP WZQ

EXIT:         RET

TABLE: DB 10,25,40,55,70,85,100,120,255             ;255是为了防止R1的值超出范围

TIME20MS:

    MOV R6,#40

GIN:         MOV R7,#250

        DJNZ R7,$

         DJNZ R6,GIN

         RET

END

;在这个程序中读取AD值时省略读取反字节过程,一般是不能省略,在这只是为了简化程序

6.3    设计思路

AD设计按键现在已经比较多人在用了,它的重点在于时序的掌握。在读取AD值时要先对ADC芯片(程序以ADC0832为例)电平设置,须先将/CS使能端置低电平并且保持低电平直到转换完全结束。此时芯片开始工作,同时由处理器向芯片时钟输入端CLK输入时钟脉冲,D0/D1端则使用D1端输入通道功能选择的数据信号。在第1个时钟脉冲的下沉之前D1端必须是高电平,表示启动信号。在地23个脉冲下沉之前D1端应输入2位数据用于选择通道功能,当此2位数据为10,时,只对CH0进行单通道转换。到第3个脉冲下沉后D1端的输入电平就失去输入作用,此后D0/D1端则开始利用数据输出D0进行转换数据的读取。从第4个脉冲下沉开始有D0端输出转换数据最高位,随后每一个脉冲下沉D0端输出下一个数据,直到第11个脉冲时发出最低位数据,一个字节的数据输出完成。从第12个脉冲下沉时,D0输出数据的反字节,到第19个脉冲时标志着一次A\D转换的结束,最后将/CS置高电平禁用芯片。

时钟信号可以形象的描述为,把数据挤进去或拉出来。在向D1输入数据时,就是把数据挤进去,每一次下沉就把一个数据挤进去;在读取D0数据时,就是把数据拉出来,每一次下沉就把一个数据拉出来。

TABLE: DB 10,25,40,55,70,85,100,120,255  是设置了一个范围。小于10则键值为0(没有按键按下),大于10小于25则键值为1,大于25小于40则键值为2,大于40小于55则键值为3,大于55小于70则键值为4,大于70小于85则键值为5,大于85小于100则键值为6,大于100小于120则键值为7。但如果大于120小于255键值则为0,因为大于120小于255,超出了硬件电路ADC0832分得的最大电压值所对应的表值,是出现异常时转换的数据,实验证明如果不加上这个表值,在单片机启动时,键值会出错(没有按键也被赋键值)。这些表值不是算出来的,是通过相应按键按下时单片机读取的,然后通过这些表值反过来推导出键值,这样键值会更加稳定、准确。

理论上一个ADC芯片一个通道可以设置255个按键。一个ADC芯片可以同时多个通道同时设置按键。AD按键设计方案不支持多点操作

 

7.      二进制式按键

7.1    电路图

7

7.2    汇编程序

;程序与编码器按键程序一样

7.3    设计思路

每一个IO口都有两种状态‘1’,‘0’,两个IO口就可以组成四种状态,nIO口就有2^n2n次方)种状态。理论上nIO口就可以组成2^n1个按键,还有一个状态是默认的状态(没有任何按键的情况下),实际上设计二进制式按键比较繁琐,IO口多了就非常难设计它的电路图。图7是设计了三个IO口的二进制式按键,用二极管单向导通功能来防止键与键之间的影响

不支持多点操作。

 

8.      频率式按键

8.1    电路图

8

8.2       汇编程序

         ORG 0000H

         LJMP MAIN

         ORG 001BH

         LJMP TIME1

         ORG 0100H

MAIN:

         MOV TH1,#33H

         MOV TL1,#28H

         MOV TMOD,#16H              ;T/C0计数方式2T/C1定时方式1

         MOV TL0,#0

         MOV IE,#88H

         MOV SP,#0EFH

         MOV R3,#0

         MOV R1,#0

START:      LCALL KEYSCAN

         MOV P1,R1

         NOP

         JMP START

KEYSCAN:

         CJNE R3,#0,EXIT

         SETB TR1

         SETB TR0

         MOV R3,#1

EXIT:         RET

TIME1:      ORL TL1,#28H

         MOV TH1,#33H

         MOV R3,#0

         CLR TR1

         CLR TR0

         CLR TF0

         MOV R2,TL0

         MOV TL0,#0

         MOV DPTR,#TABLE

         MOV R4,#0

GINNY:     MOV A,R4

         MOVC A,@A+DPTR

         SUBB A,R2

         JC INCR4

         CJNE R4,#0,FUR1

         JMP EXIT_TIME1

FUR1:        MOV A,R4

         MOV R1,A

         JMP EXIT_TIME1

INCR4:      INC R4

         JMP GINNY

EXIT_TIME1:RETI

TABLE:     DB 10,18,23,28,33,38,45   ;键值范围表

;这种方式,不太稳定,容易误判。因为你不知道频率什么时候定下来,

;tl0很可能只计到部分计数,常常会使键值偏小

8.3    设计思路

频率式按键程序设计有两种,一种是在一定时间内读取它的周期个数(上述汇编程序就是用这种方法),这种方法不准确,容易误判,因为你不知道频率什么时候定下来,很可能只都到部分计数,常常会使键值偏小;另一种方法是读取若干个周期的时间,这种方法准确,程序编辑相对复杂一点。

每个按键按下对应接入到555的电阻都不同,555产生的频率就会不同,当单片机读取到这些频率,然后查表,就可以根据频率的差异,相应赋键值。最好每个按键产生的频率差异尽量大一点,这样单片机就更容易识别这些按键。

不支持多点操作。

9.      模块克隆式按键

9.1    电路图

9

9.2    汇编程序

KEYSCAN:

         MOV A,P2

         ORL A,#1FH

         MOV P2,A

         CLR P2.0

         CLR P2.1

         MOV A,P2

         ANL A,#0CH

         CJNE A,#0CH,AGAIN1

         JMP EXIT

AGAIN1:  LCALL TIME20MS

         MOV A,P2

         ANL A,#0CH

         CJNE A,#0CH,AGAIN2

         JMP EXIT

AGAIN2:  JNB P2.4,KEYADD4  ;检测是否是第二模块有按键按下,有则跳转

         MOV R1,#0

         JMP KEYSCAN1

KEYADD4:MOV R1,#4

KEYSCAN1:MOV A,P2

         ORL A,#1FH

         MOV P2,A

         CLR P2.0

         JNB P2.2,ADD1

         JNB P2.3,ADD2

         JMP KEYSCAN2

ADD1:       MOV A,R1

         ADD A,#1

         MOV R1,A

         JMP EXIT

ADD2:       MOV A,R1

         ADD A,#2

         MOV R1,A

         JMP EXIT

KEYSCAN2:SETB P2.0

         CLR P2.1

         JNB P2.2,ADD3

         JNB P2.3,ADD4

         JMP EXIT

ADD3:       MOV A,R1

         ADD A,#3

         MOV R1,A

         JMP EXIT

ADD4:       MOV A,R1

         ADD A,#4

         MOV R1,A

EXIT:         RET

;该程序没错,但放入proteus中不会出结果,经检查proteus中或门出问题,目前这个问题还没被解决

;希望读者能者指出错误所在,谢谢!

9.3    设计思路

      模块克隆式按键顾名思义就是以一个模块为模板,然后以这个模板进行克隆复制。图9就是一个四个键的模块为模板来克隆复制,图中复制了一次。当然可以再次克隆,再次克隆就是以上次的全部按键为模板来复制。每个模板通过逻辑门和一个IO口来区别,如图9是通过或门区别。每复制一次就只要一个IO口,这要一个端口就可以组成4*2^(8-4)=2^6=64个按键,这是理论上可行,实际现实是很困难的。按照这个原理复制则一个51单片机的四个端口最多可以组成2^6+8+8+8=2^30=1024^3=1073741824个按键。克隆复制方法还可以还其他按键方法一起使用比如独立按键、二进制式按键等,如果和独立按键使用则最多可以组成2^7+8+8+8=2^31=2147483648个按键。

不支持多点操作。

 

10. 其他按键

电路图与独立按键一样,但这里只用了独立按键的P2.0一个IO口。

10.1其他按键—长按与短按

;延时法

KEYSCAN:

SETB P2.0

NOP

JB P2.0,EXIT

AGAIN1:    LCALL TIME20MS            

JB P2.0,EXIT                                 ;判断是否有按键按下

AGAIN2:    MOV R3,#10

GINNY:      MOV R2,#10               ;检测按键按下的时间是否达到长按的要求

WZQ: LCALL TIME20MS

DJNZ R2,WZQ

JB P2.0,EXIT2             ;按键在长按的要求时间内抬起则为短按键值为1

DJNZ R3,GINNY

MOV R1,#2                 ;达到长按的要求时间则为长按键值为2

JMP EXIT1

EXIT2:        MOV R1,#1

EXIT1:        JNB P2.0,$                   ;判断按键是否抬起

EXIT: RET

 

10.1.1 设计思路

 长按与短按可以用两种方法检测,一种是延时法检测(上述程序),另一种是定时法。

延时法是在延时的时间内不断地检测按键是否被抬起,如果在延时过后按键还是没被抬起则说明按键是长按操作,如果在延时范围内被抬起则说明按键是短按操作,一般延时为一秒以上。当检测是长按操作时,要等待按键被抬起,否则可能又会被检测到一个短按操作,因为长按时间很可能大于延时,当延时完成后就立即赋键值后退出,而这时按键又处于按下状态,这样程序很可能再次检测这个按下的按键,如果在第二个延时检测中按键被抬起,这时程序就会误把上次的长按操作变成本次检测的短按操作。但延时法会降低单片机处理效率,会影响单片机其他外设的操作,比如数码管的显示等。

定时法和延时法的原理一样,只是采用的方式不同。定时是每隔一段时间就检测一下按键的状态,在规定的读取次数,根据读取到的按键状态来判断按键是长按还是短按。当然这也的注意到长按操作后的处理,要在读取到长按操作后不能马上关闭定时中断,要检测到按键抬起再关闭,才可以进行下一次按键状态检测。定时法在一定程度上不会影响单片机其他外设的操作。

 

10.2其他按键—单击与双击

;延时法

KEYSCAN:

SETB P2.0

NOP

NOP

JB P2.0,EXIT

AGAIN1:    LCALL TIME20MS            

JB P2.0,EXIT               ;判断是否有按键按下

MOV R1,#1

AGAIN2:    MOV R2,#25

GINNY1:   

LCALL TIME20MS

JNB P2.0,NEXT1                 ;规定时间内等待按键抬起

JMP GINNY2

NEXT1:      DJNZ R2,GINNY1

JMP EXIT

GINNY2:    LCALL TIME20MS

JB P2.0,NEXT2           ;在规定时间内判断按键抬起后是否有再按下操作

JMP ADDR1               ;在规定时间内按键再次按下则跳转

NEXT2:      DJNZ R2,GINNY2

JMP EXIT          ;超过双击检测时间则退出

ADDR1:     INC R1

JNB P2.0,$                   ;等待按键抬起

EXIT: RET

 

10.2.1 设计思路

单击与双击也可以用两种方法检测,一种是延时法检测(上述程序),另一种是定时法。单击与双击的检测方法和长按与短按的检测方法很相似。

延时法就是在延时范围内检测有几个按下操作,如果有两个按下操作则退出延时,说明是双击,如果在延时后只有一个按下操作,则说明单击。在得到键值后要等待按键抬起,原因和长按与短按的一样。

定时法也是每隔一段时间检测一次按键状态,在规定的次数中读取按键按下的次数,当读到按键次数为两次则赋键值说明是双击,读到两次按下操作后如果检测到按抬起则关闭中断,如果在规定的次数中只检测到一个按下操作则说明是单击。

相关资料可以到: javascript:;javascript:;论坛原创中下载。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章