使用数码管前,我要先介绍一个元器件——74HC138。
我在这里简单叙述一下74HC138的主要功能及如何使用。
我们知道3位二进制可以表示8种情况。而74HC138中有三个输入端,分别是A0,A1,A2。在我们的单片机中的原理图表示的是A、B、C。当然名字不重要,重要的是三个输入可以表示八种情况。
以下是左边3个输入不同情况时,分别对应右边8个输出端的不同情况(右边输出端从最下面的Y7开始,排到上面的Y0)
当A0=1,A1=1,A2=1时-------对应-------0111 1111
当A0=1,A1=1,A2=0时-------对应-------1011 1111
当A0=1,A1=0,A2=1时-------对应-------1101 1111
当A0=1,A1=0,A2=0时-------对应-------1110 1111
当A0=0,A1=1,A2=1时-------对应-------1111 0111
当A0=0,A1=1,A2=0时-------对应-------1111 1011
当A0=0,A1=0,A2=1时-------对应-------1111 1101
当A0=0,A1=0,A2=0时-------对应-------1111 1110
由此我们可以用三个输入表示八个输出,但是74HC138使用时需要使能,让4、5号管脚接地,6号管脚接电源即可使能,让其工作。
现在我们看一下A7和A2中关于74HC138部分的原理图,方便之后的接线和使用。
A7开发板的4、5、6号管脚已经接好了电源和地,我们不用接线;
而A、B、C(即上面的A0,A1,A2)没有接线,我们分别将其与P2_2,P2_3,P2_4连接;
右边的输出端Y在PCB内部已经连接了数码管段选,我们这里不管,后面会再提到。
A2开发板的74HC138在开发板内部已经全部连好线了。
接下来我们来看一下数码管的原理图
这是A7的数码管原理图,看起来很复杂,我们将数码管的J6用线和P0端口组连接,实际上和A2的原理图一致。
这是A2的数码管原理图,是不是看起来简单明了了一些
图中有个74HC245,我们不用对它进行操作,这是一个驱动器,简单得来说是帮单片机驱动数码管的。
解下面我们对照A2的原理图讲解一下数码管
实际上数码管就是八个LED灯组成的一个显示器(七个竖状LED和一个点状LED)
这个八个LED有编号,分别是a,b,c,d,e,f,g,dp。
我们可以看到这个数码管上面有个COM,这表示这个数码管是共阴数码管,即八个LED连接一个地。
我们想要点亮LED,就只需要让对应的LED的阳极输入1,即可点亮。例如我们想显示1,只有对b、c编号的LED输入1,即可点亮。
知道了一个数码管如何显示数字,那么我们看一下八个如何使用
我们可以看到这八个数码管的a,b,c,d,e,f,g,dp都连接着P0号端口组。
那么我们可以思考,如果我们给74HC138输入000,那么输出的是1111 1110,即A2开发板中的Y0对应的LED1输出的是0。
那么最右边的数码管将会接地,此时给b,c对应的P0_1,P0_2输出1,就可以让最右边的数码管显示1。
下面是测试代码,验证一下目前为止的理论。(使用的是A7开发板)
A7开发板的74HC138输出端接线与A2正好相反,给74HC138输入000时,是最左边的数码管点亮,所以为了让最右边的数码管点亮,应该给输入端输入111,此时输出端是0111 1111,第一个0对应最右边的数码管。
验证完以上理论后,目前可以显示数字1,点亮的是b、c,将需要点亮的LED输出1从而让数码管显示数字的过程就是数码管段选。
想要数码管显示0、1...9的数字,我们需要知道数码管的段选代码
目前已经知道了1的段选是让b、c输出1,其它为0。
即P0_7=0,P0_6=0,P0_5=0,P0_4=0,P0_3=0,P0_2=1,P0_1=1,P0_0=0。
直接对P0端口码操作,即P0=0x06。(对应的二进制是0000 0110)
0x06就是1的段码表,我们还需要知道0、2、3、4、5、6、7、8、9的段码表
我已经整理好了,使用时可以直接复制,以下是0-9的段码表
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F
我们将他写成一个数组,方便后续使用
//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
这个是数码管共阴的情况,如果是共阳,代码则需要改变。
能够显示0-9的数字后,我们还需要让数字能在想要出现的位置出现,则需要控制74HC138去控制输出端输出0的位置。
8个数码管的阴极是分别接在74HC138的输出端。138输出端输出0,则对应的数码管阴极接入0,即可显示数字。
那么我们控制8个数码管显示一个数字的位置,这个问题就转化为了控制138的输出端的0。
上文提到了74HC138输入端和输出端的对应关系。根据这个关系,可以编写一个函数
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
switch(Location) //位码输出
{
case 8:P2_4=1;P2_3=1;P2_2=1;break;
case 7:P2_4=1;P2_3=1;P2_2=0;break;
case 6:P2_4=1;P2_3=0;P2_2=1;break;
case 5:P2_4=1;P2_3=0;P2_2=0;break;
case 4:P2_4=0;P2_3=1;P2_2=1;break;
case 3:P2_4=0;P2_3=1;P2_2=0;break;
case 2:P2_4=0;P2_3=0;P2_2=1;break;
case 1:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number]; //段码输出
}
由于普中A7和普中A2关于74HC138输出端的接线是相反的,所以代码需要稍微修改
以下是A2关于这个函数的编写
//数码管显示子函数
void Nixie(unsigned char Location,Number)
{
switch(Location) //位码输出
{
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=NixieTable[Number]; //段码输出
}
这个函数第一个变量是位置。利用switch-case,当给函数不同的数字时,会在不同的位置显示数字。这叫数码管的位选。
第二个变量是显示的数字,利用上文中写到的数组NixieTable[],选择不同的数字。如NixieTable[0]代表的数字是0。
最后就可以在主函数main中使用这个void Nixie(unsigned char Location,Number)函数了。例如我们在第二个数码管显示3
以下是实物图
这就是静态数码管的编程,下一篇会写到动态数码管的代码编程,从而使八个数码管都显示不同的数字。