您的位置首页  科技产品

共阴极数码管编码表_共阴极数码管编码表a~g

今天咱聊聊数码管,其实数码管这个器件,本身没有什么好讨论的。为什么这里作为单独一节拿出来讨论呢?个人认为,这个小东西虽然简单,实际使用过程中,其实包含了很多。单片机知识以外的内容,譬如一些简单的编程技巧、编程与实际现象的关联,非常值得入门者

共阴极数码管编码表_共阴极数码管编码表a~g

 

今天咱聊聊数码管,其实数码管这个器件,本身没有什么好讨论的为什么这里作为单独一节拿出来讨论呢?个人认为,这个小东西虽然简单,实际使用过程中,其实包含了很多单片机知识以外的内容,譬如一些简单的编程技巧、编程与实际现象的关联,非常值得入门者认真思考。

因为在今后的电子之路上,遇到的情况会比这个复杂得多所以建立一种分析问题解决问题的方法和思考,比掌握一种单片机或者一种外设要重要得多先来看看啥是数码管吧,其实数码管就是几个LED并联的产物,看下图的数码管:

这是一个常用的二位8段数码管,可以看到有7个段位和1个小数点,其实对于每一个段位,内部都有与之对应的一个LED。

上图中右上角给出了每个段位的称号,分别是abcdefg和dp,dp指的就是小数点上图中的03621A和03621B说明的就是:这8个LED在内部的连接方式值得注意的是,03621A中,所有LED的阳极都连接到了一起,称之为共阳极数码管。

不难判断,abcdefg和dp需要给个低电平,才能使得LED导通发光03621B中,所有LED的阴极都连接到了一起,称之为共阴极数码管不难判断,abcdefg和dp需要给个高电平,才能使得LED导通发光;因为这是个两位的数码管,所以还设置了DIG1和DIG2来控制那位数码管进行显示。

举个栗子:在共阳极数码管中,阳极连接到电源如果要显示数字“1”,那么就需要a和c这两个段位一个低电平,其它为高,使得这两段位的LED发光即可So,a-g的编码就是0101111,以此类推,0-9均可以通过abcdefg的赋值来通过显示。

小数则可以通过dp段的赋值来显示好玩一点的话,整个16进制0-f都可以显示,特别值得一提的是共阴极和共阳极的输入编码是不一样的在共阳极数码管中,如果要显示数字“1”,a-g分别输入0101111 而在共阳阴极数码管中,如果要显示数字“1”,a-g分别输入1010000。

到这里,数码管的内部结构应该有了个大致的了解,来一起玩玩吧。上个洞洞板图

背部飞线,焊接功底比较差,请随性鄙视

上个原理图吧

三极管在这里不是用于信号放大,而是作为一个开关器件,完成对位的选通其余每个段位都使用1k左右的电阻作为限流,这个限流电阻值的选取,需要考虑端口的灌电流能力特别注意a-dp,完全使用P2的8个端口,加上P1.7,总共消耗9个IO口。

上代码#include sbit smgbit1 = P1^7;sbit smgbit2 = P1^6;disp_cache[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90};

void delay_ms(unsigned int xms){unsigned int i,j;for(i=xms;i>0;i--){for(j=124;j>0;j--);}}void main(){ unsigned char i;

smgbit1 = 1;smgbit2 = 0;while(1){for(i = 0;i <= 9;i++){P2 = disp_cache[i];delay_ms(250);}}}这段代码里面有个数组disp_cache,第一个元素disp_cache[0]=0xC0,换做二进制便是1100 0000。

对照数码管的段位,dp至a的电平便是1100 0000,abcdef都亮,g和dp不亮,也就形成的数字“0”以此类推,disp_cache[1]- disp_cache[9]则分别代表了数字“1”-“9”,所以,咱进行数码管显示的时候。

只需要关注disp_cache[i]里面i这个变量就行了方便不少,这种简单有效的编程技巧,会有助于代码更加简洁,主函数里面将smgbit,也就是p1.7位置1这个时候,DIG1端口的三极管导通DIG1口相当于直接连接至Vcc,而DIG2则与Vcc断开。

然后在for循环里面,每500ms对i从0-9自加操作同时在P2口输出disp_cache[i],也就是数码管从0-9进行显示,看实际运行情况

这样就完成了一个基础的数码管显示,但是回头想想.咱这可是2位的数码管哟!如果按照这种显示方式,同时显示2位的话,需要占用8+1+8+1=18个IO口.单片机硬件资源消耗情况实在太夸张了.如何解决?一是采用ASIC来驱动数码管,这种方式一来会增加硬件成本,二来要研究ASIC复杂的协议.另外一种就是扫描的显示方式了,所谓扫描显示,就是利用人眼的视觉暂留原理.这个原理在现实生活中用的非常广泛,譬如电源、摇摇棒等等!每次只显示一位数码管,在ms的时间内进行切换.譬如要显示”13”,那就先显示1,再切换显示3.切换时间不超过十多ms的话,人眼会认为是同时显示的.这种方式可以较少IO口的使用,同时降低功耗

上个代码#include sbit smgbit1 = P1^7;sbit smgbit2 = P1^6;smgdisp_cache[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsigned int count,timer_count;void init(){smgbit1 = 0;smgbit2 = 1;TMOD=0x01;//设置定时器0为工作方式1TH0=0xfc;TL0=0X66;

EA=1;//开总中断ET0=1;//开定时器0中断TR0=1;//启动定时器0}void SMG_Dis(){if(smgbit1){P2 = smgdisp_cache[count%10];//求余,取个位数显示

}if(smgbit2){P2 = smgdisp_cache[count/10];//求商,取十位数显示}}void time0() interrupt 1{timer_count++;if(timer_count == 100)

{count++;timer_count = 0;}smgbit1 = ~smgbit1;smgbit2 = ~smgbit2;if(count>99){count = 0;}SMG_Dis();TF0 = 0;

TH0 = 0xfc;TL0 = 0x66;}void main(){ init();while(1){}}在这段代码中,Init()用于初始化定时器,1ms中断,同时两位数码管只有其中一位可以显示.SMG_Dis()用于进行扫描显示,如果smgbit1和smgbit2.哪个选通,哪个就进行显示,中断服务函数中,处理定时器事宜,每100ms进行一次自加.并且每次中断都将smgbit1和smgbit2取反,保证每次只显示其中一位.看看运行效果

上面的动图中,基本计数显示的功能是达到了,但是,似乎个位的走动会影响到十位的显示.其实就是数码管在刷新下一个数据时,上次的数据会留有余晖导致的.也就是传说中的数码管鬼影.鬼影的消除,无非就是两种,加延时和数据清零.这里使用数据清零的办法,把中断函数做个简单处理

void time0() interrupt 1{ P2 = 0xff; //消除鬼影timer_count++;if(timer_count == 100){count++;timer_count = 0;

}smgbit1 = ~smgbit1;smgbit2 = ~smgbit2;if(count>99){count = 0;}SMG_Dis();TF0 = 0;TH0 = 0xfc;TL0 = 0x66;

}增加一句P2 = 0xff;及时对数码管的显示数据进行清零.用来对暂态数据进行清除看效果

可以看出来,基本上残影都被消除掉了.其实鬼影的出现,并非是代码思路有问题.而是一些外部器件的特性使然.今后碰到的器件,很可能会有类似的情况.养成遇山开路、遇水搭桥的思维习惯,才是学习单片机的捷径.Ok,今天就讨论到这里.

了解更多51系列教程,请关注“云汉电子社区”官方微信公众号,关注后回复活动可免费参与社区最新活动,有机会获得电子类图书以及京东购物卡!

免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186