您好,欢迎访问三七文档
数码管和矩阵键盘----笔记2其实这次笔记我想和大家分享的是矩阵,但是单独的把矩阵拿出来,显得少了什么,因为展现矩阵的功能,必须有一个比较的明显展示区域。看单片机上,最显眼就是那一排数码管。选数码管,其实是有原因,因为本次笔记中矩阵刚好是4X4的,分别对16个按键进行操作,操作显示不同数字,正好就用数码管显示。废话不多说,在讲矩阵之前,要说一下数码管,但在说数码管之前,必须了解单个数码管。现在开始大家说单个数码管:1:数码管的结构:led数码管常用段数一般为7段有的另加一个小数点,还有一种是类似于3位“+1”型。位数有半位,1,2,3,4,5,6,8,10位等等....,led数码管根据LED的接法不同分为共阴和共阳两类,了解LED的这些特性,对编程是很重要的,因为不同类型的数码管,除了它们的硬件电路有差异外,编程方法也是不同的。图2是共阴和共阳极数码管的内部电路,它们的发光原理是一样的,只是它们的电源极性不同而已。颜色有红,绿,蓝,黄等几种。led数码管广泛用于仪表,时钟,车站,家电等场合。选用时要注意产品尺寸颜色,功耗,亮度,波长等。下面将介绍常用LED数码管内部引脚图片。一个数码管的引脚是10个,显示一个8字需要7个小段,还有一个小数点,所以内部只有8个二极管,生产厂商为了封装统一,单位数码管都封装10个引脚,剩下的两个为公共端。(如图a)对于共阴极的数码管,其8个发光二极管的阴极在数码管里全部连接在一起,所以称为共阴极,而他们的阳极一般都是独立的,通常在设计电路的时候,阴极接地。所以当我们给数码管中任一阳极高电平的时候,就会点亮该二极管,同理,如果你想显示“8”和右下角的小数点,那么必须把所有的阳极全部送高电平。对应共阴极的0-F的编码:0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e对于共阳极的数码管,其内部8个发光二极管的所有阳极连接在一起,电路连接时,公共电断接高电平,因此我们要点数码管中二极管,则必须送低电平过去,此时显示的数字的编号于共阴极编码相反,数码管内部发光二极管点亮时,也需要5mA以上的电流,理论上电流越大越好,但是最好在5mA-20mA范围内,不然很容易烧坏。对应共阴极的0-F的编码:0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x712:驱动方式LED数码管要正常显示,就要用驱动电路来驱动数码管的各个段码,从而显示出我们要的数字,因此根据LED数码管的驱动方式的不同,可以分为静态式和动态式两类。静态显示静态驱动也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个单片机的I/O端口进行驱动,或者使用如BCD码二-十进制译码器译码进行驱动。静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O端口多,如驱动5个数码管静态显示则需要5×8=40根I/O端口来驱动,要知道一个89S51单片机可用的I/O端口才32个,实际应用时必须增加译码驱动器进行驱动,增加了硬件电路的复杂性。动态显示LED数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划a,b,c,d,e,f,g,dp的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当单片机输出字形码时,单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。在这里提一个知识点:(1)利用万用表检测数码管的引脚排列对数字万用表来说,红表笔线连接表内部电池正极,黑标笔连接表内部电池的负极,当把数字万用表置于二极管挡时,其两表笔之间开路电压约1。5V,把两表笔正确接在二极管两端时,可以点亮发光二极管。如下图,将数字万用表置于二极管挡,红表笔接在a脚,然后用黑标笔接触其他各引脚,假设只有但会接触h脚的时候,数码管a段发光,而接触其余引脚时不发光。由此可知,被测数码管为共阴极结构类型,h脚为公共端,a脚则是数码管的a段,接下来再检测各段引脚,依旧使用外用表二极管挡,将黑标笔固定h脚,用红表笔一次接触b、c、d、e、f、g、p引脚时,相对应的二极管先后发光,便可以绘出内部结构和引脚排列。而上述方法不行,将万用表红黑表笔调换解法。数码管基本上说完,接下来就要进入主题了,,,,矩阵键盘!2、矩阵键盘2.1键盘接口键盘是由若干按键组成的开关矩阵,它是微型计算机最常用的输入设备,用户可以通过键盘向单片机输入指令、地址和数据。一般单片机系统中采用非编码键盘,非编码键盘是由软件来识别键盘上的闭合键,它具有结构简单,使用灵活特点,因此被广泛用于单片机系统。2.2按键开关的抖动问题组成键盘的按键有触点和非触点式两种,单片机中应用的一般是由机械触点构成。在下图1、2中,当按键被按下时,P1.0输入为高电平,单按键被按下后,P1.0输入为低电平,由于按键是解析触点,当机械触点无论是被按下还是断开的时都会有抖动,P1.0输入端的波形如图2。这种抖动对人来说是感觉不到,但对单片机而言,则是完全可以感应到,因为单片机处理速度都是在微妙级别以下,而抖动是毫秒级别,对单片机而言,是一个漫长的过程。图2为了使CPU能正常读出P1口的状态,对每一次按键智能做一次响应,就必须考虑如何去除抖,常用的去抖动的方法有两种:硬件方法和软件方法,常用是软件法。下面就说说软件法;软件法其实很简单,就是在单片机获取P1.0口为低的消息后,不是立即认定已被按下,而是延时10ms的抖动时间或更长一段时间后再次检测P1.0口,如果还为低,说明按键已被按下,这是避开了按键按下的抖动时间。而在检测到按键释放后(P1.0为高)再延迟5-10个毫秒,消除后沿的抖动,然后再对键值处理。不过一般情况下,我们通常不对按键释放的后延处理,实时证明,也能满足一定要求。当然,在实际情况中,根据实际情况来编写处理程序。图1接下来,我们一起看一下,矩阵的应用:1:通过按键来实现加一、减一、复位;2:通过数码管显示当前的按键;程序见附件;#includereg52.hsbitKEY18=P1^4;sbitKEY19=P1^5;sbitKEY20=P1^6;sbitKEY21=P1^7;ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0-9;voiddelay_ms(uintt){uchari;for(;t0;t--)for(i=110;i0;i--);}ucharnum1;//定义一个全局变量,用来实现按键产生的值和数码管显示函数之间的值的传递;voidDisplay(){staticuchari=0;//定义i为局部静态变量P2=0xFF;//位消隐switch(i){case0:P0=~table[num1%10];break;case1:P0=~table[num1/10];break;case2:P0=~table[2];break;case3:P0=~table[3];break;case4:P0=~table[4];break;case5:P0=~table[5];break;case6:P0=~table[6];break;case7:P0=~table[7];break;}P2=~(0x80i);//动态扫描i++;if(i==2)i=0;//打开右边两个数码管}ucharkey_scan(){staticucharsta=1;//设置一个状态,表示按键是否按下,1为抬起if(sta==1&&(KEY18==0||KEY19==0||KEY20==0||KEY21==0))//如果有一个按键按下,则进入下面程序,注意此时使用的逻辑或的关系{//delay_ms(10);//消抖10mssta=0;//设置一个状态,表示按键是否按下,0为按下if(KEY18==0)return1;elseif(KEY19==0)return2;elseif(KEY20==0)return3;elseif(KEY21==0)return4;}elseif(KEY18==1&&KEY19==1&&KEY20==1&&KEY21==1)sta=1;//表示没有按键按下,注意此时使用的是逻辑与的关系;return0;//没有按键按下}voidmain(){ucharkey;num1=1;while(1){Display();delay_ms(10);key=key_scan();if(key==1){num1++;if(num199)num1=1;}if(key==2){num1--;if(num11)num1=99;}if(key==3){num1=01;}}}其实我最想说的,关于独立按键的相关方法:下面是两个老师讲的,各有特色,自己慢慢体会;案例1:#includereg52.hsbitKEY1=P1^4;sbitKEY2=P1^5;sbitKEY3=P1^6;sbitKEY4=P1^7;ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F值voiddelay(uintt){while(t--);}ucharKey_Scan()//独立按键{uchari;staticucharkey_sta[]={1,1,1,1};//表示按键当前状态为抬起for(i=0;i4;i++){P1=~(0x01i);if(key_sta&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))//当前状态必须为抬起。{key_sta[i]=0;//把按键状态标记为0delay(1000);if(KEY1==0)return1+i*4;//功能elseif(KEY2==0)return2+i*4;//功能elseif(KEY3==0)return3+i*4;//功能elseif(KEY4==0)return4+i*4;//功能}elseif(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)key_sta[i]=1;}return0;//没有按键按下}voidmain(){ucharkey;while(1){P2=0x00;key=Key_Scan();switch(key){case1:P0=~table[key-1];break;case2:P0=~table[key-1];break;case3:P0=~table[key-1];break;case4:P0=~table[key-1];break;case5:P0=~table[key-1];break;case6:P0=~table[key-1];break;case7:P0=~table[key-1];break;case8:P0=~table[key-1];break;case9:P0=~table[key-1];break;case10:P0=~table[key-1];break;case11:P0=~table[key-1];break;case12:P0=~table[key-1];break;case13:P0=~table[key-1];break;ca
本文标题:数码管和矩阵
链接地址:https://www.777doc.com/doc-2336033 .html