第9章人机对话接口的设计9.1单片机应用系统中的键盘全编码键盘:硬件完成键盘识别功能,通过硬件识别是否有按键被按下,以及到底被按下的是哪一个按键。每按下一个键,键盘会自动提供被按下按键唯一对应的编码,同时产生一个选通脉冲通知微处理器。非编码键盘:由软件完成键盘识别功能,利用简单的硬件和专门编写的键盘编码识别程序来判断键盘中是否有按键被按下,以及到底被按下的是哪一个按键。我们有时会将其中按键状态改变所引起的特殊电信号称为该按键的编码,但这个编码不会由键盘本身产生,与编码键盘中的编码有很大区别。单片机应用系统中为了实现简化硬件构成,缩小设备体积的目的,一般都是使用非编码键盘。9.1.1键盘接口设计要考虑的问题(1)判断是否有按键被按下。(2)如果有按键按下,判断是哪一个按键被按下。(3)不同按键与其功能程序段的衔接。(4)消除按键抖动造成的不利影响。9.1.2非编码键盘的类型及工作原理每一个按键独占一根I/O口线,按键的断开或闭合状态直接反映给这根I/O口线,单片机只需查询各I/O接口的状态,就可以了解与各I/O口线直接相连的按键开关状态。9.1.2.1独立式非编码键盘9.1.2.2矩阵式非编码键盘A电路设计方法将单片机的I/O口线分为行线和列线,将键盘中的各个按键分列于行线和列线的交叉点上,采用矩阵的形态排列,每个按键都分别与一根行线和一根列线相连。B矩阵式非编码键盘的按键识别过程及原理确定有没有按键被按下。当所有按键都没有被按下时,行线和列线是不相连的。如果通过行线发出某种信号(例如0信号),列线的状态不会受到影响。但有按键按下则会影响这根列线的状态。单片机检测所有列线的状态,一旦检测到与行线上所加信号相同的信号,即可判断有按键被按下。确定有按键被按下后,接着就应该确定到底被按下的是哪一个按键。线反转法行扫描法(1)线反转法。①先确定被按下的按键所处的列。以行线为输出口,列线为输入口。通过行线发出“0000”信号,然后读取列线的状态,在没有按键按下时,读入的四位信息应该是“1111”,有按键按下时,读入的四位信息中至少会出现一个“0”。找到这个“0”所对应的列线,可以确定被按下的按键所在列线。②再确定被按下的按键所处的行。以列线为输出口,行线为输入口(输出、输入口线反转)。通过四根列线发出“0000”信号,然后读取行线状态,读入的四位信息中至少会出现一个“0”。找到这个“0”所对应的行线,可以确定被按下的按键所在行线。(2)行扫描法。以行线为输出口,列线为输入口。通过各输出口轮流输出扫描信号(例如轮流输出“0”),然后读取输入口的反馈信息。矩阵式键盘的按键编码EEHDEHBEH7EHEDHDDHBDH7DHEBHDBHBBH7BHE7HD7HB7H77H9.1.3键盘的控制方式可采用的键盘控制方式主要有程序控制扫描、定时扫描和中断方式三种。9.1.3.1程序控制扫描方式一般是在单片机做完一段工作,暂时处于空闲状态时,或者允许进行键盘控制操作时,由程序主动调用键盘扫描子程序,查询键盘的状态。9.1.3.2定时扫描方式以一定的时间间隔,周期性地调用键盘扫描子程序,查询键盘的状态。这种方式一般会使用定时/计数器帮助确定扫描键盘的时刻。9.1.3.3中断方式以键盘按键状态变化作为单片机外部中断的触发信号。一旦有按键被按下,单片机即转入中断处理程序。例1如图,开关①闭合程序转向PRO1,开关②闭合程序转向PRO2,开关③闭合程序转向PRO3,试编程实现。KEY:MOVP1,#0FFHMOVA,P1;读按键的状态ANLA,#07H;高五位清零,低三位不变CJNEA,#07H,KEY2;判断有无按键按下AJMPKEYKEY2:MOVR0,A;将读取的按键状态暂存ACALLDELAY;消抖MOVP1,#0FFHMOVA,P1;再次读按键状态ANLA,#07H;高五位清零,低三位不变CJNEA,R0,KEY;确定是否有按键按下CJNEA,#06H,NOK1;若不是按一号键,则转NOK1LJMPPRO1;一号按键被按下,转PRO8xx51P1.0P1.1P1.2+5V①②③NOK1:CJNEA,#05H,NOK2;不是二号键按下则转NOK2LJMPPRO2;二号按键按下,转PRO2NOK2:LJMPPRO3;三号按键按下,转PRO3RETDELAY:MOVR0,#0AH;实现10ms延时的子程序DELAY2:MOVR1,#0FAHDELAY1:NOPNOPDJNZR1,DELAY1DJNZR0,DELAY2RET8xx51P1.0P1.1P1.2+5V①②③例2用行扫描法查询键盘状态,找出按下的键,将其编码存入R3,试编程(假定10ms的延时子程序DELAY可直接调用)。RDKEY:MOVP1,#0F0HMOVA,P1;读P1口ANLA,#0F0H;低四位清零,保留列值CJNEA,#0F0H,KEY;判断是否有按键被按下AJMPRDKEY;没有按键按下则转RDKEYKEY:LCALLDELAY;消抖MOVR7,A;将之前读取的列值暂存到R7中MOVA,P1;再读P1口ANLA,#0F0H;低四位清零,保留列值CJNEA,R7,RDKEY;若两次读取的列值不同,则认为没;有按键按下,转RDKEYHAVE:MOVA,#0FEH;有按键按下,则设置扫描初值LOOP:MOVR6,A;将扫描值暂存到R6中MOVP1,A;一根行线输出“0”,其余输出“1”例2用行扫描法查询键盘状态,找出按下的键,将其编码存入R3,试编程(假定10ms的延时子程序DELAY可直接调用)。MOVA,P1ANLA,#0F0H;低四位清零CJNEA,#0F0H,GET;判断该行线上是否有按键按下,;若有按键按下,则转GETRLA;此行上没有按键按下,扫描下一行CJNEA,#0EFH,LOOP;判断是否扫描完所有的行AJMPRDKEYGET:MOVR5,A;读取的列值暂时存入R5中MOVA,R6ANLA,#0FHORLA,R5;合并行扫描值和读取的列值MOVR3,ARET例3有矩阵键盘如图9-4所示,已知按键编码分别为EEH,DEH,BEH,7EH,EDH,DDH,BDH,7DH,EBH,DBH,BBH,7BH,E7H,D7H,B7H,77H,其对应的处理程序分别为PR1~PR16。要求使用线反转法查询图中键盘的状态,找出被按下的按键,并按照该按键的编码转向指定的程序,试编写子程序实现(假定延时10ms的子程序DELAY可以直接调用)。RDKEY:MOVP1,#0F0H;P1低四位对行线发“0”信号MOVA,P1ANLA,#0F0H;低四位清零,保留列值CJNEA,#0F0H,KEY;判断是否有按键按下AJMPRDKEY;没有按键按下则转RDKEYKEY:LCALLDELAY;消抖MOVR7,A;列值暂存MOVA,P1ANLA,#0F0H;低四位清零,仅保留列值CJNEA,R7,RDKEY;确定是否有按键按下HAVE:MOVP1,#0FH;P1高四位对列线发“0”信号MOVA,P1ANLA,#0FH;高四位清零,保留行值ORLA,R7;合并之前读取的列值和行值MOV20H,A;将按下按键的编码暂存THEN:MOVDPTR,#TAB1MOVA,#00H;初始偏移量为0NEXT:PUSHACC;将A中内容暂存MOVCA,@A+DPTR;查按键编码表CJNEA,20H,LOOP;比对按键编码和编码表中的值POPACCRLA;偏移量乘2MOVDPTR,#TAB2;令DPTR指向转移指令表的首地址JMP@A+DPTR;执行对应的转移指令LOOP:POPACCINCACJNEA,#10H,NEXT;16个按键编码是否比对完AJMPRDKEY;重新查询键盘状态RETTAB1:DBEEH,DEH,BEH,7EH,EDH,DDH,BDH,7DHDBEBH,DBH,BBH,7BH,E7H,D7H,B7H,77H;按键编码表TAB2:AJMPPR1AJMPPR2┇AJMPPR16;列转移指令表9.2单片机应用系统中的显示器9.2.1LED数码管的结构一个LED显示器一般由一位或多位LED数码管组成。常见的LED数码管由七个发光二极管排列成数字“8”的形态(七段式数码管),有时还要在右下角加上一个发光二极管作为小数点使用(八段式数码管)。001111113fhxgfedcbaabcdefgdpcdedp12345678910abfgcomcomabcefcomgLED数码管的g~a七个发光二极管因加正电压而发亮,因加零电压而不能发亮,不同亮暗的组合就能形成不同的字形,这种组合称之为字形码(段码),如显示”0”,字形码为3fh.abcdefgdp12345678910abfgcomcomabcefgxgfedcba0000011006h显示”1”,字形码为06h.显示”2”,字形码为5bh.(b)dpcomabcdefgdpcde12345678910comcomabcefgxgfedcba010110115bh显示字符段符号十六进制代码dpgfedcba共阴共阳0123456789ABCDEFHP0000000000000000010011111011110111111000111011111011111010001010111111111011011011011110001101111111110100101111100111100100111011011111101011013FH06H5BH4FH66H6DH7DH07H7FH6FH77H7CH39H5EH79H71H76HF3HC0F9A4B0999282F880908883C6A18684FFBF9.2.2LED数码管的显示方式9.2.2.1静态显示方式静态显示方式其实就是一种稳定显示方式。使用单片机的一组并行I/O接口与数码管的字形输入引脚相连,当这组I/O口向LED数码管输入一个字形码后,在相当长一段时间内,令该数码管内部的各个发光二极管稳定的维持在导通或者截止状态,一直显示该字符,直到需要显示另一个字符为止。LED数码管在采用静态显示方式时,为了确保显示状态不变常常会加接锁存器。将数码管的8个字形输入引脚分别与8位锁存器的8个输出端相连,单片机将字形码输出给锁存器后再令锁存器锁存,锁存器锁存的字形码输出维持不变,LED接收到的字形码也就稳定不变,这样一来,LED数码管就可以一直显示该字符。9.2.2.2动态显示方式适用于由多个数码管组成的LED显示器。将多个数码管的字形输入端与单片机的同一个8位I/O口相连,该I/O口我们称为字形选择口。将数码管的公共端分别与单片机的其他不同I/O口相连,这些I/O口我们称为位选择口。字形选择口将希望某一个数码管显示的字形码同时输出给所有的数码管,位选择口在同时向需要显示该字符的数码管发出选通信号,仅令该数码管点亮,持续状态1~2ms的时间。随后字形选择口将希望另一个数码管显示的字形码输出给所有数码管,并在同时由位选择口改变选通信号的输出,仅使需要显示该字符的数码管点亮,同样持续1~2ms的时间。接着,字形选择口再输出第三个数码管需要显示的字形码,位选择口输出令该数码管点亮的选通信号。依此类推,字形选择口轮流输出各数码管需要显示字符的字形码,位选择口相应地发出不同数码管的选通信号,令各数码管轮流显示各自需要显示的字符。由于人眼有视觉暂留的现象,看起来就好像所有的数码管在同时显示各自的字符。P0口06H5BH4FH06H5BH┅P2口FEHFDHFBHFEHFDH┅说明左边的数码管显示中间的数码管显示右边的数码管显示左边的数码管显示中间的数码管显示循环进行例4试设计51系列单片机与一个共阳极LED数码管的接口电路,并针对该电路编写程序,令数码管以2s的时间间隔,轮流显示数字“1”、“2”、“3”、“4”,给定晶振为6MHz。P0.0P0.1P0.2P0.3P0.4P0.5P0.6P0.78xx51abcdefgDPDIRA0B0A1B1A2B2A3B3A4B4A5B5A6B6A7B7G74