本文是江协科技up的课堂笔记!大家可以去bilibili配合这位up的51单片机入门教程食用,效果更佳~
我这里进行详细介绍,希望你忘记数码管的时候来这里看看!(你猜我为什么写这个TAT)
一.基本介绍
LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件
下面介绍引脚连接和段的概念

这个图显示的是数码管从A-DP这八个段,对应一个字节的八个比特位
这是引脚定义,类似单片机,一号引脚也是在左下角,呈逆时针排列
这个叫做共阴极连接,右边的叫做共阳极连接,我们观察引脚分布和各个段的引脚链接,我们发现在电路上是就近原则的
3.8引脚是公共的阴极
二.显示一个数字
比如说我们要显示数字六:ACDEFG点亮,其他熄灭就可以(以共阴极为例!!!)
步骤:
1.公共端接地(位选端选中)——决定哪个数字“8”亮起
2.把下面棕色的数字输入进去(段码)——决定哪根LED亮起
接下来看看更复杂的四位一体数码管!
上图是共阴极,下图是共阳极
相信聪明的你发现规律了:单个数码管是八个段引脚加上两个阴极的引脚,而四位一体就是把相同的引脚连在一起控制,然后再支出另外四个引脚作为每个数码管的阴极(还是以共阴极为例)
自然想到通过控制阴极端口的电平高低来控制哪一个数码管亮啦(负极接正极,那他就必然不会亮啊),然后控制其余引脚来控制他亮起来的数字是几
但是就出现了一个问题,我的数码管无论同时亮起几个都只能显示一个数字(比如我让第一个和第三个亮起,但是如果让1号亮起数字‘6’,第3号也只能亮起6)毕竟段的选择是公用的引脚
公用引脚可以减少io口的使用,但是如何让多位数字同时显示呢?
U4的用途是双向数据缓冲器,最下面的四个东西:
VCC:正极,GND:负极;OE:把它理解为下面的那个使能端得了,低电平有效,不用管;
DIR:方向选择,看是把左边的数据缓冲到右边还是把右边的数据输送到左边
(其实是接高电平就把数据输送到右边,这个是我买的电路,他是没有跳线改变输送方向的,直接连接正极,有些带有跳线的是可以改变它的方向的)
不用这个芯片的话,左侧的信号就是驱动,加入芯片他就是信号源;只需要低强度信号,让芯片接受,再加上芯片有自己的电源,就可以加强信号啦
那些电阻是排阻,四位一体的电阻元件
原理已知,首先我要在LED1-8这些个引脚里来进行位选,如何进行?
138译码器解决这个问题,它使用三个端口就可以解决问题
具体怎么做?
ABC表示输入端,右侧就是输出端,左下角就是使能端(其实不用管,知道这么接他就会工作就行)CBA是一次高位到低位
因为2^3=8,所以在abc处用二进制表示后,转换到0-7这八个数,分别对应LED1-8(这里有个很无语的错位哈。)
下图标的Y0一杠的横线表示0有效,就是说比如CBA顺序是000,就是Y0有效,即Y0是0,其他都是1
(问题又来了,这样搞得话,不就只有一个数码管可以亮了吗)
代码实现:
#include <REGX52.H>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
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];
}
void main()
{
// //CBA的顺序读
// //6号led对应的是Y5
// P2_4=1;
// P2_3=0;
// P2_2=1;
// //数据的高位对应端口的高位
// P0=0x7D;
Nixie(1,10);
while(1)
{
;
}
}
各位要注意,数字是从下往上读的!!!高位对高位
三.动态数码管显示
多个位显示不同的数字,如何做到
原理就是让数码管不断循环,这一个是1,下一个是2,在下一个是3,这样的话借着快速移动的数字加上他熄灭的时间以及人眼的视觉暂留就可以达到效果
初次尝试:
#include <REGX52.H>
#include <intrins.h>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
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];
}
void main()
{
Nixie(1,10);
while(1)
{
Nixie(1,1);
// Delay(20);
Nixie(2,2);
// Delay(20);
Nixie(3,3);
// Delay(20);
}
}
这个会出现数字串位的情况,因为数码管的消影过程中
//位选 段选 位选 段选
//在这个过程中,位变了,但是还没来得及变化段,所以上一个数字会串到下一位
//所以我们可以对段选清零
从而我们对函数进行了优化
#include <REGX52.H>
#include <intrins.h>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
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];
Delay(1);//先让他稳定的亮一会,否则就会亮度过低
P0=0x00;//让他熄灭
}
void main()
{
Nixie(1,10);
while(1)
{
Nixie(1,1);
// Delay(20);
Nixie(2,2);
// Delay(20);
Nixie(3,3);
// Delay(20);
//数码管的消影
//位选 段选 位选 段选
// 【 】
//在这个过程中,位变了,但是还没来得及变化段,所以上一个数字会串到下一位
//所以我们可以对段选清零
}
}