1、单片机的输入接口-键盘 一、键盘输入的特点键盘中的一个按键为一个机械弹性开关,用一个电压信号(0,1)代表开关触点的合、断。机械开关触点的弹性作用使得按键的闭合过程不会马上稳定地接通,断开时也不会瞬时断开,会出现所谓的“抖动”现象,其抖动时间一般为5-10ms。 抖动现象会引起CPU对一次键操作进行多次处理,从而可能产生错误。按键过程如下:,二、按键的识别按键的闭合与否,反映在电路上就是电位出现高低的变化,-对连接有按键电路电位的高低的判断也就是对按键闭合与否的判断。,键盘扫描控制方式 程序控制扫描方式(查询方式)键处理程序固定在主程序的某个程序段。特点:对CPU工作影响小,但应考虑键盘处理程
2、序的运行间隔周期不能太长,否则会影响对键输入响应的及时性。 定时控制扫描方式利用定时/计数器每隔一段时间产生定时中断,CPU响应中断后对键盘进行扫描。特点:与程序控制扫描方式的区别是,在扫描间隔时间内,前者用CPU工作程序填充,后者用定时/计数器定时控制。定时控制扫描方式也应考虑定时时间不能太长,否则会影响对键输入响应的及时性。 中断控制方式中断控制方式是利用外部中断源,响应键输入信号。特点:克服了前两种控制方式可能产生的空扫描和不能及时响应键输入的缺点,既能及时处理键输入,又能提高CPU运行效率,但要占用一个宝贵的中断资源。, 硬件去抖动,三、消除抖动不良后果的方法:,其中RC滤波电路去抖动
3、电路简单实用,效果较好。, 软件去抖动检测到按键按下后,执行延时10ms子程序后再确认该键是否确实按下,消除抖动影响。,四、键盘的设计,设计按键有两种方式,独立式设计,矩阵式设计,1.独立式按键 独立式按键是每个按键占用一根I/O端线。 特点: 各按键相互独立,电路配置灵活; 按键数量较多时,I/O端线耗费较多,电路结构繁杂; 软件结构简单。 适用于按键数量较少的场合。,独立式按键及软件设计按键的识别方式,查询,中断,定时扫描,与普通的I/O传送一致,利用单片机定时器产生定时 中断,在中断服务程序中对 键盘进行扫描获得键值,例1,用查询的方法对下图的独立式键盘进行识别编程。,四按键独立式设计,
4、程序如下:ORG 0000HAJMP MAINORG 0040H MAIN: MOV SP ,#60HORL P1,#0FH LOOP:JNB P1.0,KEY0JNB P1.1,KEY1JNB P1.2,KEY2JNB P1.3,KEY3LJMP LOOP,KEY0:CALL DELAY10msRET KEY1:CALL DELAY10msRET KEY2:CALL DELAY10msRET KEY3:CALL DELAY10msRET DELAY10ms: .RET END,例2,用定时扫描的方法对上题所示的独立式键盘进行编程识别。fosc=6MHz,定时中断程序定时50ms.程序如下:O
5、RG 0000H AJMP MAINORG 000BHAJMP INTOORG 0040H MAIN:MOV TMOD,#01HMOV TL0,#58HMOV TH0,#9EHSETB EASETB ET0,SETB TR0SJMP $ INT0:JNB P1.0,KEY0JNB P1.1 ,KEY1JNB P1.2, KEY2JNB P1.3,KEY3MOV TL0,#58HMOV TH0,#9EHRETI,KEY0: CALL DELAY10msMOV TL0,#58HMOV TH0,#9EHRET KEY1: CALL DELAY10msMOV TL0,#58HMOV TH0,#9EHR
6、ET,KEY2: CALL DELAY10msMOV TL0,#58HMOV TH0,#9EHRET KEY3: CALL DELAY10msMOV TL0,#58HMOV TH0,#9EHRET DELAY10ms:RETEND,例3,对上题进行中断式检测的改造。利用外中断0来检测按键。,按图 (a)、(b),试分别编制按键扫描子程序。,思考:,解:按图 (a)编程如下: KEYA:ORL P1,#07H ;置P1.0P1.2为输入态MOV A,P1 ;读键值,键闭合相应位为0CPL A ;取反,键闭合相应位为1ANL A,#00000111B;屏蔽高5位,保留有键值信息的低3位 JZ GR
7、ET ;全0,无键闭合,返回LCALL DY10ms ;非全0,有键闭合,延时10ms,软件去抖动MOV A,P1 ;重读键值,键闭合相应位为0CPL A ;取反,键闭合相应位为1ANL A,#00000111B;屏蔽高5位,保留有键值信息的低3位JZ GRET ;全0,无键闭合,返回;非全0,确认有键闭合JB Acc.0,KA0 ;转0#键功能程序JB Acc.1,KA1 ;转1#键功能程序JB Acc.2,KA2 ;转2#键功能程序 GRET:RET KA0: LCALL WORK0 ;执行0#键功能子程序RET KA1: LCALL WORK1 ;执行1#键功能子程序RET KA2: L
8、CALL WORK2 ;执行2#键功能子程序RET,按图 (b)编程如下: KEYB:ORL P1,#07H ;置P1.0P1.2为输入态MOV A,P1 ;读键值,键闭合相应位为1ANL A,#00000111B ;屏蔽高5位,保留有键值信息的低3位JZ GRET ;全0,无键闭合,返回LCALL DY10ms ;非全0,有键闭合,延时10ms,软件去抖动MOV A,P1 ;重读键值,键闭合相应位为1 ANL A,#00000111B ;屏蔽高5位,保留有键值信息的低3位JZ GRET ;全0,无键闭合,返回;非全0,确认有键闭合JB Acc.0,KB0 ;转0#键功能程序JB Acc.1,
9、KB1 ;转1#键功能程序JB Acc.2,KB2 ;转2#键功能程序 GRET:RET KB0: LCALL WORK0 ;执行0#键功能子程序 RET KB1: LCALL WORK1 ;执行1#键功能子程序RET KB2: LCALL WORK2 ;执行2#键功能子程序RET,2、矩阵式键盘接口技术及编程矩阵式键盘: I/O端线分为行线和列线,按键跨接在行线和列线上,按键按下时,行线与列线发生短路。 特点: 占用I/O端线较少; 软件结构教复杂。 适用于按键较多的场合。,矩阵按键的识别 (1)扫描法 逐列置为零电平,检查行线电平的变化,如果行电平由高电平变为零电平,则可确定此行与此列交叉
10、点处的按键被按下。 (2)线反转法 线反转法的操作步骤分两步:第一步,将行线编程为输入线,列线编程为输出线,并使列线为全零电平,则行线电平由高到低的行为按键所在行;第二步,将行线编程为输出线,列线编程为输入法,并使输出线输出为全零电平,则列线中电平由高到低的列为按键所在列。 即先确定行线位置,再确定列线位置, 键值=行号*列数+列号,【例1】按上图,试编制矩阵式键盘扫描程序。(先画出流程图) 解:KEY: MOV P1,#0F0H ;行线置低电平,列线置输入态 KEY0: MOV A,P1 ;读列线数据CPL A ;数据取反,“1”有效ANL A,#0F0H ;屏蔽行线,保留列线数据MOV R
11、1,A ;存列线数据(R1高4位)JZ GRET ;全0,无键按下,返回 KEY1: MOV P1,#0FH ;行线置输入态,列线置低电平MOV A, P1 ;读行线数据CPL A ;数据取反,“1”有效ANL A, #0FH ;屏蔽列线,保留行线数据MOV R2,A ;存行线数据(R2低4位)JZ GRET ;全0,无键按下,返回JBC F0,WAIT ;已有消抖标志,转SETB F0 ;无消抖标志,置消抖标志LCALL DY10ms ;调用10ms延时子程序,消抖SJMP KEY0 ;重读行线列线数据 GRET: RET ;,WAIT: MOV A,P1 ;等待按键释放CPL A ;ANL
12、 A,#0FH ;JNZ WAIT ;按键未释放,继续等待 KEY2: MOV A,R1 ;取列线数据(高4位)MOV R1,#03H ;取列线编号初值MOV R3,#03H ;置循环数CLR C ; KEY3: RLC A ;依次左移入C中JC KEY4 ;C=1,该列有键按下,(列线编号存R1)DEC R1 ;C=0,无键按下,修正列编号DJNZ R3,KEY3 ;判循环结束否?未结束继续寻找有键按下的列线 KEY4: MOV A,R2 ;取行线数据(低4位)MOV R2,#00H ;置行线编号初值MOV R3,#03H ;置循环数CLR C ; KEY5: RRC A ;依次右移入C中J
13、C KEY6 ;C=1,该行有键按下,(行线编号存R2)INC R2 ;C=0,无键按下,修正行线编号DJNZ R3,KEY5 ;判循环结束否?未结束继续寻找有键按下的行线,KEY6: MOV A,R2 ;取行线编号CLR C ;RLC A ;行编号2RLC A ;行编号4ADD A,R1 ;行编号4+列编号=按键编号 KEY7: CLR C ;RLC A ;按键编号2RLC A ;按键编号4(LCALL+ RET共4字节)MOV DPTR,#TABJ ;JMP A+DPTR ;散转,执行相应键功能子程序 TABJ: LCALL WORK0 ;调用执行0#键功能子程序RET ;LCALL WO
14、RK1 ;调用执行1#键功能子程序RET ; LCALL WORK15 ;调用执行15#键功能子程序RET,【例2】按下图,试编制中断方式键盘扫描程序,将键盘序号存入内RAM 30H。,ORG 0000H ;复位地址LJMP STAT ;转初始化ORG 0003H ;中断入口地址LJMP PINT0 ;转中断服务程序ORG 0100H ;初始化程序首地址 STAT: MOV SP,#60H ;置堆栈指针SETB IT0 ;置为边沿触发方式MOV IP,#00000001B ;置为高优先级中断MOV P1,#00001111B ;置P1.0P1.3置为输入态,置P1.4P1.7输出0SETB E
15、A ;CPU开中SETB EX0 ;开中LJMP MAIN ;转主程序,并等待有键按下时中断,OGR 2000H ;中断服务程序首地址 PINT0: PUSH Acc ;保护现场PUSH PSW ;MOV A,P1 ;读行线(P1.0P1.3)数据CPL A ;数据取反,“1”有效ANL A, #0FH ;屏蔽列线,保留行线数据MOV R2,A ;存行线(P1.0P1.3)数据(R2低4位)MOV P1,#0F0H ;行线置低电平,列线置输入态MOV A,P1 ;读列线(P1.4P1.7)数据CPL A ;数据取反,“1”有效ANL A,#0F0H ;屏蔽行线,保留列线数据(A中高4位)MOV
16、 R1,#03H ;取列线编号初值MOV R3,#03H ;置循环数CLR C ; PINT01:RLC A ;依次左移入C中JC PINT02 ;C=1,该列有键按下,(列线编号存R1)DEC R1 ;C=0,无键按下,修正列编号DJNZ R3,PINT01 ;判循环结束否?未结束继续寻找有键按下列线,PINT02:MOV A,R2 ;取行线数据(低4位)MOV R2,#00H ;置行线编号初值MOV R3,#03H ;置循环数 PINT03:RRC A ;依次右移入C中JC PINT04 ;C=1,该行有键按下,(行线编号存R2)INC R2 ;C=0,无键按下,修正行线编号DJNZ R3,PINT03 ;判循环结束否?未结束继续寻找有键按下行线 PINT04:MOV A,R2 ;取行线编号CLR C ;RLC A ;行编号2RLC A ;行编号4ADD A,R1 ;行编号4+列编号=按键编号MOV 30H,A ;存按键编号POP PSW ;POP Acc ;RETI ;,