第9章MCS-51单片机接口技术9.1键盘接口9.2显示器接口9.3A/D转换器接口9.4D/A转换器接口9.5步进电机控制9.1键盘接口9.1.1键盘概述1、按键开关去抖动问题图9-1键盘抖动过程键盘的抖动时间一般为5~10ms,抖动现象会引起CPU对一次键操作进行多次处理,从而可能产生错误。消除抖动不良后果的方法:⑴硬件去抖动图9-2硬件去抖动电路其中RC滤波电路去抖动电路简单实用,效果较好。⑵软件去抖动检测到按键按下后,执行延时10ms子程序后再确认该键是否确实按下,消除抖动影响。2.按键编码(1)用键盘连接的I/O线的二进制组合表示键码。(2)顺序排列编码。首先确定按键的行号m,再确定按键的列号n,则键码=行号m×4+列号n(a)二进制组合编码;(b)顺序排列编码9.1.2独立式按键独立式按键特点:(1)各按键相互独立,电路配置灵活(2)软件结构简单(3)按键数量较多时,I/O线耗费较多,只适用于按键数量较少的场合。独立式按键电路如图9-4所示。图9-4独立式按键图9-4(a)所示的独立按键扫描程序如下:KEYA:ORLP1,#07H;置P1.0~P1.2为输入态MOVA,P1;读键值,键闭合相应位为0CPLA;取反,键闭合相应位为1ANLA,#00000111B;屏蔽高5位,保留有键值信息的低3位JZGRET;全0,无键闭合,返回LCALLDY10ms;非全0,有键闭合,延时10ms,软件去抖动MOVA,P1;重读键值,键闭合相应位为0CPLA;取反,键闭合相应位为1ANLA,#00000111B;屏蔽高5位,保留有键值信息的低3位JZGRET;全0,无键闭合,返回;非全0,确认有键闭合JBAcc.0,KA0;转0#键功能程序JBAcc.1,KA1;转1#键功能程序JBAcc.2,KA2;转2#键功能程序GRET:RETKA0:LCALLWORK0;执行0#键功能子程序RETKA1:LCALLWORK1;执行1#键功能子程序RETKA2:LCALLWORK2;执行2#键功能子程序RET图9-4(b)所示的独立按键扫描程序如下:KEYB:ORLP1,#07H;置P1.0~P1.2为输入态MOVA,P1;读键值,键闭合相应位为1ANLA,#00000111B;屏蔽高5位,保留有键值信息的低3位JZGRET;全0,无键闭合,返回LCALLDY10ms;非全0,有键闭合,延时10ms,软件去抖动MOVA,P1;重读键值,键闭合相应位为1ANLA,#00000111B;屏蔽高5位,保留有键值信息的低3位JZGRET;全0,无键闭合,返回;非全0,确认有键闭合JBAcc.0,KB0;转0#键功能程序JBAcc.1,KB1;转1#键功能程序JBAcc.2,KB2;转2#键功能程序GRET:RETKB0:LCALLWORK0;执行0#键功能子程序RETKB1:LCALLWORK1;执行1#键功能子程序RETKB2:LCALLWORK2;执行2#键功能子程序RET9.1.3矩阵式键盘若需要的按键数目较多,通常采用矩阵式(也称行列式)键盘。I/O端口线分为行线和列线,按键跨接在行线和列线的交叉处,按键按下时,行线与列线连同,形成回路。其特点是占用I/O线较少,但软件较复杂。图9-5矩阵式键盘结构1.查询方式查询式确认键盘中有无键按下的基本方法是(以图9-5为例):P1.4-P1.7输出0,即所有列线置成低电平,然后将行线电平状态读入累加器A中。如果有键按下,总会有一根行线电平被拉至低电平,从而使行输入状态不全为1。确认键盘中哪一个键按下的方法是:从P1.4开始,依次输出0,置对应的列线为低电平,然后读入行线状态,如果全为1,则所按下之键不在此列;如果不全为1,则所按下的键必在此列,而且是与0电平行线相交的交点上的那个键。确认键码的过程是:先确认行号,再确认列号键码=行号×4+列号。参考程序如下:KEY:MOVP1,#0F0H;行线置低电平,列线置输入态KEY0:MOVA,P1;读列线数据CPLA;数据取反,“1”有效ANLA,#0F0H;屏蔽行线,保留列线数据MOVR1,A;存列线数据(R1高4位)JZGRET;全0,无键按下,返回KEY1:MOVP1,#0FH;行线置输入态,列线置低电平MOVA,P1;读行线数据CPLA;数据取反,“1”有效ANLA,#0FH;屏蔽列线,保留行线数据MOVR2,A;存行线数据(R2低4位)JZGRET;全0,无键按下,返回JBCF0,WAIT;已有消抖标志,转SETBF0;无消抖标志,置消抖标志LCALLDY10ms;调用10ms延时子程序消抖SJMPKEY0;重读行线列线数据GRET:RETWAIT:MOVA,P1;等待按键释放CPLAANLA,#0FHJNZWAIT;按键未释放,继续等待KEY2:MOVA,R1;取列线数据(高4位)MOVR1,#03H;取列线编号初值MOVR3,#03H;置循环数CLRCKEY3:RLCA;依次左移入C中JCKEY4;C=1,该列有键按下,(列线编号存R1)DECR1;C=0,无键按下,修正列编号DJNZR3,KEY3;判循环结束否?未结束继续寻找有键按下的列线KEY4:MOVA,R2;取行线数据(低4位)MOVR2,#00H;置行线编号初值MOVR3,#03H;置循环数CLRCKEY5:RRCA;依次右移入C中JCKEY6;C=1,该行有键按下,(行线编号存R2)INCR2;C=0,无键按下,修正行线编号DJNZR3,KEY5;判循环结束否?未结束继续寻找有键按下的行线KEY6:MOVA,R2;取行线编号CLRCRLCA;行编号×2RLCA;行编号×4ADDA,R1;行编号×4+列编号=按键编号KEY7:CLRCRLCA;按键编号×2RLCA;按键编号×4(LCALL+RET共4字节)MOVDPTR,#TABJJMP@A+DPTR;散转,执行相应键功能子程序TABJ:LCALLWORK0;调用执行0#键功能子程序RETLCALLWORK1;调用执行1#键功能子程序RET……LCALLWORK15;调用执行15#键功能子程序RET2.定时扫描方式图9-6定时扫描流程定时扫描方式就是每隔一段时间对键盘扫描一次,它利用单片机内部的定时器产生一定时间(例如10ms)的定时,当定时时间到就产生定时器溢出中断。CPU响应中断后对键盘进行扫描。3.中断方式图9-7中断键盘接口电路具体工作如下:当键盘无键按下时,与门各输入端均为高电平,输出端也为高电平,无中断请求;当有键按下时,相应行线为低电平,与门输出端也为低电平,向CPU申请中断。若CPU开放外部中断,则会响应中断请求,转去执行键盘扫描子程序。参考程序如下:ORG0000H;复位地址LJMPSTAT;转初始化ORG0003H;中断入口地址LJMPPINT0;转中断服务程序ORG0100H;初始化程序首地址STAT:MOVSP,#60H;置堆栈指针SETBIT0;置为边沿触发方式MOVIP,#00000001B;置为高优先级中断MOVP1,#00001111B;置P1.0~P1.3置为输入态,置P1.4~P1.7输出0SETBEA;CPU开中SETBEX0;开中LJMPSTAT;转主程序,并等待有键按下时中断ORG0200H;中断服务程序首地址PINT0:PUSHAcc;保护现场PUSHPSWMOVA,P1;读行线(P1.0~P1.3)数据CPLA;数据取反,“1”有效ANLA,#0FH;屏蔽列线,保留行线数据MOVR2,A;存行线(P1.0~P1.3)数据(R2低4位)MOVP1,#0F0H;行线置低电平,列线置输入态MOVA,P1;读列线(P1.4~P1.7)数据CPLA;数据取反,“1”有效ANLA,#0F0H;屏蔽行线,保留列线数据(A中高4位)MOVR1,#03H;取列线编号初值MOVR3,#03H;置循环数CLRCPINT01:RLCA;依次左移入C中JCPINT02;C=1,该列有键按下,(列线编号存R1)DECR1;C=0,无键按下,修正列编号DJNZR3,PINT01;判循环结束否?未结束继续寻找有键按下列线PINT02:MOVA,R2;取行线数据(低4位)MOVR2,#00H;置行线编号初值MOVR3,#03H;置循环数PINT03:RRCA;依次右移入C中JCPINT04;C=1,该行有键按下,(行线编号存R2)INCR2;C=0,无键按下,修正行线编号DJNZR3,PINT03;判循环结束否?未结束继续寻找有键按下行线PINT04:MOVA,R2;取行线编号CLRCRLCA;行编号×2RLCA;行编号×4ADDA,R1;行编号×4+列编号=按键编号MOV30H,A;存按键编号POPPSWPOPAccRETI9.1.4键盘控制器MM74C922引脚图9-8MM74C922引脚DATAOUTA—DATAOUTB键盘输出,接单片机输入口。COLUMNX1—X3键盘列线ROWY1—Y4键盘行线。Oscillator振荡引脚,接电容。KeyboardMask按键淹没引脚,功能为硬件消抖动。DataAvailable数据有效。OutEnable输出使能。表9-1MM74C922芯片输出与按键关系按键DCBA按键DCBA00000810001000191001200101010103001111101140100121100501011311016011014111070111151111图9-9MM74C922与单片机连接返回9.2显示器接口9.2.1LED数码管显示器结构图9-107段LED数码管显示器段选码:通常把控制发光二极管的8位二进制数称为段选码(显示代码)。各段码与数据位的对应关系如下:段码位D7D6D5D4D3D2D1D0显示位Dpgfedcba表9-2七段LED的段选码03FHC0HC39HC6H106HF9HD5EHA1H25BHA4HE79H86H34FHB0HF71H8EH466H99HP73H8CH56DH92HU3EHC1H67DH82HΓ31HCEH707HF8Hy6EH91H87FH80H8FFH00H96FH90H“灭”00HFFHA77H88HB7CH83H共阴极段选码共阴极段选码共阳极段选码共阳极段选码显示字符显示字符9.2.2LED数码管显示器工作原理1、LED静态显示静态显示是指数码管显示某一字符时,相应的发光二极管恒定导通或恒定截止。各位数码管相互独立,公共端恒定接地(共阴极)或接正电源(共阳极)。图9-11一位静态LED显示图9-123位静态LED显示DIR1:MOVDPTR,#TABMOVA,30H;读显示数MOVB,#100;置除数DIVAB;产生百位显示数字MOVCA,@A+DPTR;读百位显示符MOVDPTR,#0DFFFH;置74377(百位)地址MOVX@DPTR,A;输出百位显示符MOVA,B;读余数MOVB,#10;置除数DIVAB;产生十位显示数字MOVDPTR,#TAB;置共阳字段码表首址MOVCA,@A+DPTR;读十位显示符MOVDPTR,#0BFFFH;置74377(十位)地址MOVX@DPTR,A;输出十位显示符静态显示参考程序如下,设要显示的数据(≤255)存在30H开始的内RAM中。MOVA,B;读个位显示数字MOVDPTR,#TAB;置共阳字段码表首址MOVCA,@A+DPTR;读个位显示符MOVDPTR,#7FFFH;置74377(个位)地址MOVX@DPTR,A;输出个位显示符RETTAB:DB0C0H,0F9H,0A4H,0B0H,99H;共阳字段码表DB92H,82H,0F8H,80H,90H;静态显示也可以用串行方式实现,如图9-13所示。图9-13串行静态显示显示程序如下,设显示字段码已分别存在32H~30H内RAM中。DIR2:MOVSCON,#00H;置串口方式0CLRES;串口禁中SETBP1.0;“与”门开,允许TXD发移位脉冲MOVSBUF,30H;串行输出个位显示字段码JNBTI,$;等待