数码管 | 我的日常分享

数码管

数码管

一、数码管介绍

  • LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件。
image-20210321124827004

1.1 数码管引脚定义

image-20210321125020771
  • 共阴

    image-20210321125127972

    阴极连接在3和8号两个引脚上。

  • 共阳

    image-20210321125127972

    阳极连接在3和8号两个引脚上。

1.2 四位一体的数码管

image-20210321125631271
  • 共阴
image-20210321125800103
  • 共阳

    image-20210321125836770

四位一体数码管的特点:同一时刻可以至少一个数码管被选中(点亮),即使选中多个,每个显示的内容也一定是一样的。但是可以利用人眼视觉暂留实现同时显示多个内容。

二、开发板数码管电路分析

image-20210321132311721

74HC245(八线双向收发器):

  • 作用:图中的A0、B0到A7、B7可以理解为是相连的,74HC245这里作为驱动器,如果A0传过来的信号弱了,它也能识别到,并且在B0输出时把信号增强。
  • OE:输出使能,控制其是否工作
  • DIR:方向控制,信号是A到B传递,还是B到A传递。
  • GND:逻辑地
  • VCC:逻辑电源
  • A0–A7:数据输入/输出
  • B0–B7:数据输入/输出

74hc245是一种在单片机系统中常用的驱动器,三态输出八路收发器,它在电路中的作用是:增加io口的驱动能力,比如说51单片机的io口本身的驱动电流较小但所带的负载很大,这种时候就可以使用74hc245来增强io口的驱动能力。

PR3、PR4:

两个四并一的电阻,防止过载。

image-20210321133549493

74HC138译码器:

image-20210321134236675

输出口分别与八个数码管的共阴极相连。

名称 功能说明
Y0–Y7 数据输出
A0–A2 数据输入
E1、E2、E3 使能控制
VDD 逻辑电源
GND 逻辑地

在我们设计单片机电路的时候,单片机的IO口数量是有限的,有时并满足不了我们的设计需求,比如我们的STC89C52RC一共是32个IO口,但是我们为了控制更多的器件,就要使用一些外围的数字芯片,这种数字芯片由简单的输入逻辑来控制输出逻辑,比如74HC138这个三八译码器。

三、静态数码管

image-20210321140923674

3.1 案例1:让第三个数码管显示数字6

3.1.1 分析:

选中LED3,并且使得LED3中的a、f、e、d、c、d段亮。选中LED3即74HC138译码器输出0010 0000,输入010,即P22、P23、P24分别置0、1、1;使a、f、e、d、c、g段亮,即74HC245中输出1011 1110,即P0置0111 1101(0x7d)dp为右下角的点。

3.1.2 代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
#include<regx52.h>

void main(){
P2_2 = 0;
P2_3 = 1;
P2_4 = 0;

P0 = 0x7d;
while(1){

}
}

3.1.2 现象:

img

四、动态数码管

由开发板电路图知,八个数码管,不能同一时刻显示不同的字符。

但是我们可以利用快速的切换数码管的显示,给人肉眼一种假象,能够同时显示不同的字符。

image-20210321131808277

4.1 案例1:增加延时200ms

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<regx52.h>
#include<intrins.h>

void niXieTube(unsigned char location,unsigned char num);
void Delaynms(int nms);
void main(){
while(1){
niXieTube(8,5);
Delaynms(200);
niXieTube(7,2);
Delaynms(200);
niXieTube(6,0);
Delaynms(200);
}
}
unsigned char niXieTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
void niXieTube(unsigned char location,unsigned char num){
switch(location){
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;
}
//分别表示0 1 2 3 4 5 6 7 8 9 空
//unsigned char niXieTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
P0 = niXieTable[num];
}
void Delaynms(int nms) //@11.0592MHz
{
unsigned char i, j;
while(nms--){
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}

现象:

9ED872FFAA1EB3E89DFBF8DFE3BE4348 00_00_00-00_00_30

4.2 案例2:缩短延时为1ms

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<regx52.h>
#include<intrins.h>

void niXieTube(unsigned char location,unsigned char num);
void Delaynms(int nms);
void main(){
while(1){
niXieTube(8,5);
Delaynms(1);
niXieTube(7,2);
Delaynms(1);
niXieTube(6,0);
Delaynms(1);
}
}
unsigned char niXieTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
void niXieTube(unsigned char location,unsigned char num){
switch(location){
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;
}
//分别表示0 1 2 3 4 5 6 7 8 9 空
//unsigned char niXieTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
P0 = niXieTable[num];
}
void Delaynms(int nms) //@11.0592MHz
{
unsigned char i, j;
while(nms--){
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}

现象:

img

调整相机快门时间和曝光度可以看到闪烁

C9CC3005BA80C4440663309940A035F5 00_00_00-00_00_30

4.3 案例3:去掉延时

在while中不断在8、7、6三个数码管中不停显示5、2、0。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<regx52.h>
#include<intrins.h>

void niXieTube(unsigned char location,unsigned char num);
void Delaynms(int nms);
void main(){
while(1){
niXieTube(8,5);
niXieTube(7,2);
niXieTube(6,0);
}
}
unsigned char niXieTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
void niXieTube(unsigned char location,unsigned char num){
switch(location){
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;
}
//分别表示0 1 2 3 4 5 6 7 8 9 空
//unsigned char niXieTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
P0 = niXieTable[num];
}

现象:

img

分析:

其实用摄像头将曝光跟快门时间调到最小可以获得以下图片,还是可以看得出来520.

img img

这个时候我们就需要消影,因为数码管在显示过程中,是不断地“位选 段选 位选 段选 位选 段选 位选 段选”,在段选与位选之间就会出现问题,这个时候下一个段选的数据还没有到,所以显示的是上一个的数据,所以我们需要加一个清零,“位选 段选 清零 位选 段选 清零 位选 段选 清零 位选 段选 清零”。

4.4 案例4:消影 清零

image-20210321160213883

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<regx52.h>
#include<intrins.h>

void niXieTube(unsigned char location,unsigned char num);
void Delaynms(int nms);
void main(){
while(1){
niXieTube(8,5);
niXieTube(7,2);
niXieTube(6,0);
}
}
unsigned char niXieTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
void niXieTube(unsigned char location,unsigned char num){
switch(location){
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;
}
//分别表示0 1 2 3 4 5 6 7 8 9 空
//unsigned char niXieTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
P0 = niXieTable[num];

Delaynms(1);
P0 = 0x00;
}
void Delaynms(int nms) //@11.0592MHz
{
unsigned char i, j;
while(nms--){
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}

现象:

img

其实这个也是以1ms,频繁的闪烁,只不过延迟加在了niXieTube()函数里面,但是如果不加延迟,就清零,数码管会很暗。

4.5 余影

如果不清零,不加任何延时,使用下面代码可以清晰的看到余影

1
2
3
4
5
6
7
8
void main(){
while(1){
niXieTube(8,1);
niXieTube(7,2);
niXieTube(6,3);
niXieTube(3,8);
}
}
img

五、数码管驱动方式

  • 单片机直接扫描:硬件设备简单,但会耗费大量的单片机CPU时间。
  • 专用驱动芯片:内部自带显存、扫描电路,单片机只需告诉它显示什么即可。
image-20210321134914376 image-20210321134944440