LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件
一、数码管引脚定义
在右边的两张图上,分别为两种数码管的连接方式,上面那种为共阴极连接,下面这种为共阳极连接。左下方这两张图第一张标注了数码管段的定义,第二张则为数码管连接的引脚口。在右图中可以看到引脚口的排布很乱,但是根据左图可知数码管上的各led灯段都和最近的引脚相连,就近引出。
如果我们想要在数码管上点亮一个数字6,需要将对应段上的LED灯点亮,由于开发板为共阴极连接,所以阴极已经全置为0,我们需要在阳极上给各个I/O口置1才能将对应的LED灯点亮。所以要将A、C、D、E、F、G点亮,需要给7、4、2、1、9、10置1,也就是将对应的段码置为1。
开发板上的为4位一体的开发板,他们的每一位各自的共阴极都引出去了,他们的位选段都接在一起,例如所有的A都接在11上面,如果想在第三个地方显示1,其他地方不亮,则将其他数码管的共阴极置1,接在阳极上,三号位数码管则置0,接阴极上,再将B、C置为1,则三号位置显示数字1。
但是这种公用引脚的数码管的缺点在于,只可以同时点亮一个数码管,或者点亮多个显示一样的数码管,但是这种共用引脚可以节省单片机的I/O口,操作时用更少的引脚。
那我们怎么样让他不同的数码管显示内容不一样呢?这样则需要利用人眼视觉暂存和LED的余晖现象。例如很快的让第一个数码管显示1,第二个数码管显示2,第三个数码管显示3,在快速的扫描,这样就能看到3个数字同时显示了
二、原理图
数码管的LED1~8接在了138译码器的输出端,138译码器能够使右边Y0~Y7八个端口变成右边A、B、C三个端口控制的,左下角三个引脚是使能端,相当于开关,如果使能电平有效的话,138译码器才工作,没有效的话就不工作。这个开关需要把G1接上高电平1,G2A、G2B接上低电平0,才能工作,在原理图中,G1是接在正极上,G2A、G2B是接在负极上,所以138译码器上电就工作。
138译码器的工作原理:
C | B |
| Y |
0 | 0 | 0 | Y0 |
0 | 0 | 1 | Y1 |
0 | 1 | 0 | Y2 |
0 | 1 | 1 | Y3 |
1 | 0 | 0 | Y4 |
1 | 0 | 1 | Y5 |
1 | 1 | 0 | Y6 |
1 | 1 | 1 | Y7 |
在左边A、B、C三个端口中,C为最高位,A为最低位,将这三个端口的高低电平信号组成的二进制数翻译为10进制数得到的数字就表示对应的数码管I/O口置为0,而其他的则置为1。
在我使用的51单片机中,数码管为共阴极连接,而在上图中可以看到,数码管的阳极连接着一个74HC245芯片,这个芯片的称为双向数据缓冲器,他的作用是用来提高驱动能力的,由于单片机功率较小,所以一般情况低电平驱动能力强,高电平驱动能力弱,如果CPU的I/O口直接连在数码管的引脚上会导致效果不明显或者看不到效果,但是有双向数据缓冲器后,CPU过来的电流就变成了一种电信号,只要很微弱就能有效,再由双向数据缓冲器用自己芯片上接的正极电流给到数码管,这个过程也成为弱电控制强电。
芯片上的OE的作用也是使能,低电平的时候该芯片工作,高电平的时候,该芯片不工作,所以OE接在地上,DIR(Direction Port)是方向端口。它是一种数字输入输出口,通常用于控制电机、步进电机、LED灯等设备的方向。用DIR的值来判断是将左边的数据传输到右边还是把右边的数据读到左边。因为数码管的数据不需要读回来,只需要传输过去就好,所以DIR口接在LE上,LE上接了个跳线帽使他短路,接在了VCC上使得LE一直为高电平(在新版中,DIR则是直接接在VCC正极上)。
在电源正极vcc上接着一个电容C22,他的作用是滤波。
电容的大小和电阻的大小看法一致,104的含义代表着10x10^4,也就是100 000pF。一般读为一百千。
电容的单位,pf是最小的电容单位。
1000pf = nF
1000nf = uF
1000uf = mF
1000mf = F
RP4和RP5是4位一体的排阻,作用是限流电阻,防止数码管电流过大
三、静态数码管显示
现在我们想在LED6上显示一个数字6,由上面介绍可知,需要将译码器P24,P23、P22上的二进制数转化为10进制的5,再段选,将对应的数码段点亮,若要显示6,则b段和dp段不点亮,B0~B7为 1011 1110,I/O口的大段对应着地址的大段,所以转化为16进制时应该为0111 1101,也就是0x7D
#include <REGX52.H>
void main()
{
P2_4 = 1;
P2_3 = 0;
P2_2 = 1;
P0 = 0x7D;
while(1)
{
}
}
模块化编程:
模块化编程是一种将程序分解为多个模块或子程序的编程方法,每个模块或子程序都负责完成特定的任务或功能。模块化编程具有以下好处:
-
代码复用:模块化编程可以使代码更加模块化和可复用,可以在不同的项目中重复使用模块,提高代码的效率和可维护性。
-
分工合作:模块化编程可以使多个程序员分工合作,每个程序员负责开发和维护自己的模块,提高开发效率和代码质量。
-
可维护性:模块化编程可以使程序结构更加清晰和易于维护,可以更快地定位和修复错误,降低程序维护成本。
-
灵活性:模块化编程可以使程序更加灵活和可扩展,可以根据具体需求添加或删除模块,提高程序的适应性和可扩展性。
-
测试容易:模块化编程可以使程序的测试更加容易和有效,可以单独测试每个模块,以确保程序的正确性和稳定性。
#include <REGX52.H>
unsigned char nember[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x07,0x7f,0x6f};
void nixie(unsigned char Locating,Number)
{
switch(Locating)
{
case 1: P2_4 = 1; P2_3 = 1; P2_2 = 1;break;
case 2: P2_4 = 1; P2_3 = 1; P2_2 = 0;break;
case 3: P2_4 = 1; P2_3 = 0; P2_2 = 1;break;
case 4: P2_4 = 1; P2_3 = 0; P2_2 = 0;break;
case 5: P2_4 = 0; P2_3 = 1; P2_2 = 1;break;
case 6: P2_4 = 0; P2_3 = 1; P2_2 = 0;break;
case 7: P2_4 = 0; P2_3 = 0; P2_2 = 1;break;
case 8: P2_4 = 0; P2_3 = 0; P2_2 = 0;break;
}
P0 = nember[Number];
}
void main()
{
nixie(2,2);
while(1)
{
}
}
四、动态数码管显示
有了前面的模块化编程,我们可以很方便的让静态的数码管显示,变成动态的数码管显示,但是在动态显示的过程中,会有显示错乱的情况,这个时候就需要进行消影。
显示错乱的原理:
在我们进行动态数码管显示时,进行的是,位选 段选 位选 段选 位选 段选,在这个过程中,第二次的段选数据还没有过来时,已经进行了第二次的位选,而将第一次的段选数据给到了第二次的位选上,所以造成了显示错乱的现象。
消影:
在第二次位选之前,第一次段选之后,将第一次的段选择清零,这样就不会影响到下一个数码管段的显示。
#include <REGX52.H>
unsigned char nember[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x07,0x7f,0x6f};
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
void nixie(unsigned char Locating,Number)
{
switch(Locating)
{
case 1: P2_4 = 1; P2_3 = 1; P2_2 = 1;break;
case 2: P2_4 = 1; P2_3 = 1; P2_2 = 0;break;
case 3: P2_4 = 1; P2_3 = 0; P2_2 = 1;break;
case 4: P2_4 = 1; P2_3 = 0; P2_2 = 0;break;
case 5: P2_4 = 0; P2_3 = 1; P2_2 = 1;break;
case 6: P2_4 = 0; P2_3 = 1; P2_2 = 0;break;
case 7: P2_4 = 0; P2_3 = 0; P2_2 = 1;break;
case 8: P2_4 = 0; P2_3 = 0; P2_2 = 0;break;
}
P0 = nember[Number];
Delay1ms();
P0 = 0x00;
}
void main()
{
while(1)
{
nixie(1,1);
nixie(2,2);
nixie(3,3);
}
}
五、数码管的驱动方式