LED数码管
简介:LED数码管是一种常用的数字显示设备。它由多个发光二极(LED)封装在一起,形成“8”字型的器件。数码管通常由7段LED组成,有的还会额外加一个小数点。LED数码管的引线已在内部连接好,只需要将其各个段引出来,并共用一个公共电极。
LED数码管具有高亮度、低功耗、显示灵活、易于操作等特点,广泛应用于各种计时器、仪表、电子钟、电子秤等场合,提供数字和字符的直观显示。
我们单片机上的是4位一体的数码管,在这里,我们先介绍单独一位的晶体管。
一位晶体管
对于一个数码管来说,是由8个LED组成的,我们要表示什么数字,就亮什么LED,表示数字。在这里,晶体管不同位置的LED是有一定的命名方式,从最上端开始命名‘a’,然后顺时针方向yici命名’b’‘c’‘d’‘e’‘f’,然后在中间命名为‘g’,右下角的一点命名为’dp’;
我们看一下右边的图,对于单个数码管的电路连接方式一般有两种,一种是共阴极连接方式,另一种是共阳极连接方式;在我们单片机上是共阴极的连接方式,图中对应的8个平行端口正好是连接着各个LED的,然后它们有一个公共端,直接接地。假设我们要点亮数字‘6’,那么我们就要在对应的LED上输入高电平(1),下图是LED对应的高低电平。
而对于共阳极来说,就需要反过来,因为LED是一个二极管,必须让其正极端是高电平的,但8个平行端口连接着二极管的负极,所以要亮的部分输入低电平;
多位一体数码管
在我们单片机上,正好就是一个四位一体的数码管;
对于这样的数码管,他总共有12个引脚:
其中上面的表示共阴极连接,下面是共阳极连接,这里我只以共阴极为例来讲解,我们发现,对于每个数码管来说它们的平行端口都是连接在一起的,也就是共同引用了8个引脚,对于每个数码管的公共端,是独立分开控制的,假设我们要在第二个打印上1,像这种选择在哪个位置上显示数字的,我们称之为‘位选’,我们只需要使要亮的赋予低电平,不亮的赋予高电平,就达到我们位选的条件,接下来就是跟单个晶体管同个原理,只需要选择对应的LED二极管亮起即可,高电平为亮,低电平为灭,这种选择我们称之为‘段选’;
那么当我们要位选多个显示时,如果我们要显示的是不同的数字,那么它可能会报出错误,无法达到我们想要的结果,这是因为由于段选是是个数码管共同引用的,无法同时达到显示不同数字的效果。 那么对于我们要显示这种对各数字的,我们就利用人眼视觉暂留和数码管显示的余晖的原理,通过对显示的数字进行延迟就能达到显示多个数字的效果,这也就是我们下面要讲的动态数码管显示。
单片机上的数码管原理
我们要段选什么数字,这里使用P0寄存器来控制,在连接电路中里面还包括了一个双向数据缓冲器和一个电阻;
双向数据缓冲器是一种用于在不同设备之间传输数据的电子元件。它可以在发送者和接收者之间提供临时存储,以平衡数据流速度不一致带来的问题。
由VCC直接供电,然后接地,里面的DIR表示方向(direction),在这里我们只需要由寄存器向数码管提供高低电平即可,也就是单项数据传输;
OE表示输出使能(Output Enable):
输出使能是一个控制信号,用于控制某个设备或模块的输出是否有效。当输出使能信号有效时,相应的输出电路或功能将被允许工作或产生输出;当输出使能信号无效时,相应的输出将被禁止或失效。
然后连接晶体管,我们单片机上有8个数码管,从左向右依次称之为LED1,LED2···,对于如此之多的数码管,我们这里用到一个译码器的元件来得以控制。
74HC138译码器,简称为38译码器,由电源直接控制,并接地;左下角是使能,由电源直接供电,并接地;左上角有ABC,并连接着P2寄存器,右边的Y正好连接着不同的数码管,这里,我们用到二进制表示十进制的方式,控制着不同的数码管;如:打开LED1,A为低位,C为高位,那么二进制就是000,对应着的就是Y0,就能打开LED1;下面依次类推,
这样就能控制八个数码管了,所以38译码器,就是利用三个寄存器,来对二进制数字进行转换,达到控制8个位置数码管的意思;
静态数码管显示
先给出代码:
#include <REGX52.H> char Nixienumber[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; void Nixie(unsigned char x,number) { switch(x) { case 1:P2_2=0;P2_3=0;P2_4=0;break; case 2:P2_2=1;P2_3=0;P2_4=0;break; case 3:P2_2=0;P2_3=1;P2_4=0;break; case 4:P2_2=1;P2_3=1;P2_4=0;break; case 5:P2_2=0;P2_3=0;P2_4=1;break; case 6:P2_2=1;P2_3=0;P2_4=1;break; case 7:P2_2=0;P2_3=1;P2_4=1;break; case 8:P2_2=1;P2_3=1;P2_4=1;break; } P0=Nixienumber[number]; } void main() { Nixie(7,6); }
这里对于位选的数码管,我们写了一个函数,用switch条件语句来进行选择,在对应的位选数码管通过38译码器来选择;而段选位置的数字,通过一个数组,将0~9对应的 数字依次用十六进制表示,通过利用数组下标的方式选出对应的数字。
动态数码管显示
上面我们说,对于数码管无法同时显示多个,那么解决方法就是一个一个亮起,通过延迟的效果让数码管暂留一会,利用我们人眼的视觉暂留,一般来说24ms内就能让肉眼无法察觉闪烁的效果,认为是静态的效果。
在这里先写一个延迟函数,以1ms为单位。
在这里先写一个延迟函数,以1ms为单位。
Delay.c
void Delayms(unsigned int x) //@11.0592MHz { unsigned char i, j; while(x--) { i = 2; j = 199; do { while (--j); } while (--i); } }
头文件:Delay.h
#ifndef __DELAY_H__ #define __DELAY_H__ void Delayms(unsigned int x); #endif
然后再写一个数码管函数
Nixie.c
#include <REGX52.H> #include "Delay.h" char Nixienumber[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; void Nixie(unsigned char x,number) { switch(x) { case 1:P2_2=0;P2_3=0;P2_4=0;break; case 2:P2_2=1;P2_3=0;P2_4=0;break; case 3:P2_2=0;P2_3=1;P2_4=0;break; case 4:P2_2=1;P2_3=1;P2_4=0;break; case 5:P2_2=0;P2_3=0;P2_4=1;break; case 6:P2_2=1;P2_3=0;P2_4=1;break; case 7:P2_2=0;P2_3=1;P2_4=1;break; case 8:P2_2=1;P2_3=1;P2_4=1;break; } P0=Nixienumber[number]; Delayms(2);//延时,使位选在一定闪烁在一定频率内,8个3ms内 P0=0x00;//消隐,除去前一个段选 }
Nixie.h
#ifndef __NIXIE_H__ #define __NIXIE_H__ void Nixie(unsigned char x,number); #endif
这里我打出的是八个晶体管同使亮起,那么要达到同时显示的效果,对于每个晶体管闪烁的频率就要保持在2ms内,然后每个晶体管显示后对需要清零,让下一个晶体管显示不会显示混乱;
最后,在主函数中调用各自的头文件,就能实现动态数码显示:
#include "Nixie.h" void main() { while(1) { Nixie(8,8); Nixie(7,7); Nixie(6,6); Nixie(5,5); Nixie(4,4); Nixie(3,3); Nixie(2,2); Nixie(1,1); } }