数码管

数码管是一种常用于嵌入式开发中的显示设备,能够显示数字或特定字符。它以多个 LED 段组成的形式显示信息,广泛应用于电子设备的数字显示,如电子钟、温度计、计数器等。

数码管通常由 7 段(七段显示器)8 段(包括小数点) 的 LED 组成,每个段对应一个 LED。当相应段被点亮时,会形成数字0-9的形状。

共阴与共阳

数码管的驱动方式主要有两种:共阳极和共阴极。

  • 共阳极:所有LED段的阳极(正极)连接在一起,通过控制各个LED段的阴极(负极)来控制其亮灭。
  • 共阴极:所有LED段的阴极(负极)连接在一起,通过控制各个LED段的阳极(正极)来控制其亮灭。

gongyingongyangtu

举例:

对于一个共阴数码管,要点亮某一段,比如“a段”,需要将“a段”的阳极引脚置高(电压为正),而阴极已经连接到地,所以电流会通过LED流向阴极,从而点亮LED。

对于一个共阳数码管,要点亮某一段,比如“a段”,需要将“a段”的阴极引脚置低(接地),而阳极已经连接到正电压(+5V),这样电流就会从阳极流向阴极,通过LED,从而点亮LED。

四位数码管原理图

siweishumaguanyuanlitu

74HC595位移寄存器

为了解决数码管端口复用的问题引入了 74HC595 位移寄存器

74HC595 是一个 8 位移位寄存器,具备 串行数据输入(逐位输入)和 并行数据输出(一次输出 8 位)的功能。它可以通过控制输入的时钟脉冲将串行输入的数据位依次移入寄存器中,然后一次性输出 8 位数据。

也是一个将二进制数据转换为高低电平的一个工具。

引脚图

74HC595yinjiaotu

74HC595 引脚:

  1. LATCH_CLOCK: 锁存时钟
  2. SHIFT_CLOCK: 移位时钟
  3. A: 数据输入信号管脚
  4. QA~QH: 将二进制数据信号转化为高低电平输出给数码管
  5. SQH: 串行数据输出管脚

管脚功能定义

74HC595guanjiaodingyi

真值表(“↑”表示上升沿;“↓”表示下降沿)

74HC595zhenzhibiao

真值表解释:

  1. X:表示该引脚的状态无关,处于任意状态(高电平或低电平都无影响)。
  2. :表示上升沿,即时钟从低电平变为高电平的瞬间。
  3. SER:串行数据输入
  4. SRCLK:移位寄存器时钟
  5. SRCLR:移位寄存器清零
  6. RCLK:存储寄存器时钟信号
  7. OE:输出使能信号

根据表中的不同情况,移位寄存器的行为如下:

  • X X X X H:当 OE 为高电平时,QA 到 QH 输出被禁用(输出处于高阻态)。
  • X X X X L:当 OE 为低电平时,QA 到 QH 输出被启用,输出寄存器的数据可以通过并行输出引脚输出。
  • X X L X X:当 SRCLR 为低电平时,移位寄存器的数据被清零,所有数据位变为 0。
  • L ↑ H X X:当 SER 为低电平且 SRCLK 时钟上升沿到来时,移位寄存器的第一级存储数据变为 0,其它级别的数据顺序右移。
  • H ↑ H X X:当 SER 为高电平且 SRCLK 时钟上升沿到来时,移位寄存器的第一级存储数据变为 1,其它级别的数据顺序右移。
  • X X X ↑ X:当 RCLK 时钟上升沿到来时,移位寄存器中的数据存储到输出寄存器,并更新输出。

工作原理

74HC595 原理图

74HC595yuanlitu

数据输入与移位过程

  • A(数据输入):通过该引脚,74HC595 可以接收一个串行数据流。
  • SHIFT_CLOCK(移位时钟):每个时钟上升沿时,串行数据通过 A 进入移位寄存器,寄存器中已有的数据则向高位位移。
  • LATCH_CLOCK(存储时钟/锁存时钟):该信号用于控制何时将移位寄存器中的内容输出到并行引脚 QAQH。通常移位完成后,上升沿时触发锁存操作,将寄存器中的数据输出到 Qx 引脚(Qx 泛指 QA~QH 中任意一个)。

清除与输出控制

  • RESET(复位引脚):当该引脚为低电平时,移位寄存器中的所有数据将被清零。
  • OE(输出使能):该引脚为低电平时,输出引脚 QAQH 才有效;为高电平时,输出引脚为高阻态(等效于禁用输出)。

其他

  • SQH(串行数据输出端):用于级联多个 74HC595 芯片,使得可以串联多个寄存器扩展更多的 IO 端口。第一个寄存器中的数据将通过这个引脚输出串行输入到下一个 74HC595 的串行数据输入端。

串联多个 74HC595

如果要控制超过 8 个输出,可以将多个 74HC595 级联。级联时,第一个 74HC595 的 SQH(串行输出引脚)连接到下一个 74HC595 的 A(数据输入引脚),以此类推。这样可以通过同一个数据和时钟输入同时控制多个 74HC595,实现扩展更多的并行输出。

74HC595cuanlian

当 U1 八个被填满后,在传入数据就会通过 SQH 引脚被挤到 U2 中的 QA 然后依次向高位位移。

STC8H

以 74HC595 为例

原理图

74HC595STC8Hyuanlitu

实现

八个数码管分别亮7、7、、7、7、7、7、7

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//main.c
#include "NIXIE.h"

void main() {
// 注意,此处要反着来,因为共阳时低电平导通,最低为代表 a 段数码管
u8 dat = 0xF8; // 要显示的数字 7 1111 1000
u8 num = 0xFB; // 要显示哪几个数码管 1111 1011

NIXIE_Init();

NIXIE_shwo(dat, num);

while(1) {
}
}

====================================================================================
// NIXIE.h
#ifndef __NIXIE_H__
#define __NIXIE_H__

#include "Config.h"

#define NIXIE_DI P44 // 数据输入
#define NIXIE_SCK P42 // 移位寄存器
#define NIXIE_RCK P43 // 锁存寄存器
// 获取 byte 的第 pso 位
#define GET_BIT_VAL(byte, pos) (byte & (1 << pos))
// 空操作
#define NOP_TIME() NOP2()
// 锁存操作 上升沿有效
#define RCK_ACTION() \
NIXIE_RCK = 0; \
NOP_TIME(); \
NIXIE_RCK = 1; \
NOP_TIME();

// 初始化
void NIXIE_Init();

// 显示操作
// dat 显示的数据,num 要显示那几个数码管
void NIXIE_show(u8 dat, u8 num);

#endif
======================================================================================
// NIXIE.c
#include "STC8G_H_GPIO.h"
#include "NIXIE.h"

void NIXIE_Config(void) {
GPIO_InitTypeDef GPIO_Init; // 结构定义
// 指定要初始化的IO,
GPIO_Init.Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
// 指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Init.Mode = GPIO_PullUp;

GPIO_Inilize(GPIO_P4, &GPIO_Init);//初始化
}

void NIXIE_Init(void) {
NIXIE_Config();
}

static void NIXIE_Write1Bit(u8 dat) {
char i;
for (i = 7; i >= 0; i--) {
NIXIE_DI = GET_BIT_VAL(dat, i);
// 寄存器的移位操作
NIXIE_SCK = 0;
NOP_TIME(); // 休眠一会儿
NIXIE_SCK = 1;
NOP_TIME(); // 休眠一会儿
}
}

void NIXIE_show(u8 dat, u8 num) {

// 显示 7.
// 0111 1000
// 先发字母位 (控制显示的内容) // 0点亮
// 8bit,先发出去的会作为高位
NIXIE_out(dat);

// 0,1,2,3....7
// 再发数字位 (控制显示哪几个) // 只要不是0,就是高电平
// 1111 1011
// 7.7.空7. 7.7.7.7. -------------------与二级制是反向
// 8bit,先发出去的会作为高位
NIXIE_out(num);

// 锁存操作
RCK_ACTION();
}