- 机器人等级考试
ESP32 驱动四位数码管(Arduino 环境)学习笔记
- 2025-7-19 9:58:21 @
ESP32 驱动四位数码管(Arduino 环境)学习笔记
一、前言
在嵌入式开发中,数码管是常用的显示设备。本次我们基于 ESP32,利用 Arduino 环境驱动四位数码管,通过 74HC595 移位寄存器实现,掌握硬件连接与程序控制逻辑,让数字 “亮” 起来 !
二、硬件原理与连接(以 74HC595 驱动四位数码管为例 )
1. 四位数码管与 74HC595 简介
- 四位数码管:共阴极(本次代码适配,
1=亮,0=灭
),通过动态扫描(利用人眼视觉暂留)实现多位显示,每位点亮时间短,快速切换就像同时亮 。 - 74HC595:串行输入、并行输出的移位寄存器,能减少 ESP32 引脚占用,通过
DS(数据)
、SH_CP(时钟)
、ST_CP(锁存)
三个引脚控制,实现串行数据转并行输出,驱动数码管段选和位选 。
2. 引脚对应关系(参考示例电路,需根据实际连线调整 )
ESP32 引脚 | 功能 | 对应 74HC595 引脚 | 作用 |
---|---|---|---|
9 | dataPin | DS | 传输串行数据 |
10 | clockPin | SH_CP | 时钟信号,同步数据移位 |
11 | latchPin | ST_CP | 锁存数据,让并行口输出 |
三、代码实现与详解
1. 完整代码
以下是提取的代码及详细解释:
提取的 Arduino 代码
const int dataPin = 9; // 数据引脚 (DS)
const int clockPin = 10; // 时钟引脚 (SH_CP)
const int latchPin = 11; // 锁存引脚 (ST_CP)
void setup() {
// put your setup code here, to run once:
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
byte duan = 0b10110110;//5 //0表示选中
byte wei = 0b00000010;//位 1表示选中
digitalWrite(clockPin, LOW);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, wei);
shiftOut(dataPin, clockPin, LSBFIRST, ~duan);
digitalWrite(latchPin, LOW); // 开始传输
digitalWrite(latchPin, HIGH); // 锁存数据
}
void loop() {
// put your main code here, to run repeatedly:
}
代码逐行解释
1. 引脚定义
const int dataPin = 9; // 数据引脚 (DS)
const int clockPin = 10; // 时钟引脚 (SH_CP)
const int latchPin = 11; // 锁存引脚 (ST_CP)
- 作用:定义与 74HC595 移位寄存器连接的 Arduino 引脚:
dataPin
:用于传输串行数据(DS 引脚)。clockPin
:用于同步数据移位(SH_CP 引脚)。latchPin
:用于锁存数据(ST_CP 引脚)。
- 74HC595 简介:
- 是一种串行输入、并行输出的移位寄存器。
- 可以用少量 Arduino 引脚控制多个输出(如数码管、LED 等)。
2. setup()
函数
void setup() {
// put your setup code here, to run once:
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
- 作用:初始化引脚为输出模式,确保 Arduino 可以控制这些引脚的电平。
3. 定义段选和位选数据
byte duan = 0b10110110;//5 //0表示选中
byte wei = 0b00000010;//位 1表示选中
duan
(段选数据):- 二进制
0b10110110
表示数码管的段选信号。 - 用于控制数码管的哪些段(如 a、b、c 等)点亮。
- 注释
//5
表示该数据对应显示数字5
(需结合数码管类型和硬件连接)。
- 二进制
wei
(位选数据):- 二进制
0b00000010
表示数码管的位选信号。 - 用于控制哪一位数码管点亮(如四位数码管的第二位)。
- 二进制
4. 初始化时钟和锁存引脚
digitalWrite(clockPin, LOW);
digitalWrite(latchPin, LOW);
- 作用:
- 将
clockPin
和latchPin
置为低电平,为后续数据传输做准备。
- 将
5. 传输位选和段选数据
shiftOut(dataPin, clockPin, MSBFIRST, wei);
shiftOut(dataPin, clockPin, LSBFIRST, ~duan);
shiftOut()
函数:- 用于将数据串行输出到 74HC595 移位寄存器。
- 参数说明:
dataPin
:数据输出引脚。clockPin
:时钟引脚,用于同步数据移位。MSBFIRST
/LSBFIRST
:数据传输顺序(高位先传或低位先传)。wei
/~duan
:要传输的数据。
~duan
:~
是按位取反操作。- 用于适配共阴极数码管的电平需求(低电平点亮段)。
6. 锁存数据
digitalWrite(latchPin, LOW); // 开始传输
digitalWrite(latchPin, HIGH); // 锁存数据
- 作用:
- 先将
latchPin
置为低电平,准备更新数据。 - 再将
latchPin
置为高电平,锁存数据并输出到 74HC595 的并行端口。 - 这一步确保 74HC595 将串行输入的数据并行输出,控制数码管显示。
- 先将
7. loop()
函数
void loop() {
// put your main code here, to run repeatedly:
}
- 作用:
- 主循环函数,但当前代码中为空,没有重复执行的逻辑。
- 如果需要动态更新数码管显示,可以在此处添加代码。
硬件连接与功能
- 74HC595 移位寄存器:
- 用于扩展 Arduino 的输出引脚,控制多位数码管。
- 通过
dataPin
、clockPin
和latchPin
与 Arduino 通信。
- 四位数码管:
- 通过 74HC595 的并行输出来控制每一位的显示。
- 段选数据(
duan
)控制数码管的段点亮,位选数据(wei
)控制哪一位数码管点亮。
运行逻辑
- 初始化引脚:将
dataPin
、clockPin
和latchPin
设为输出模式。 - 准备数据:定义段选(
duan
)和位选(wei
)数据。 - 传输数据:通过
shiftOut()
函数将数据串行输出到 74HC595。 - 锁存数据:通过
latchPin
控制 74HC595 锁存数据并输出,最终控制数码管显示。
总结
- 这段代码通过 Arduino 控制 74HC595 移位寄存器,实现了四位数码管的静态显示(当前显示数字
5
)。 - 关键步骤包括:引脚初始化、数据传输、锁存数据。
- 如果需要动态显示(如计数、显示传感器数据等),可以在
loop()
函数中添加逻辑,更新duan
和wei
的值并重新传输数据。
2. 完整代码
// 定义与 74HC595 连接的 ESP32 引脚
const int dataPin = 9; // 数据引脚 (DS),传输串行数据
const int clockPin = 10; // 时钟引脚 (SH_CP),同步数据移位
const int latchPin = 11; // 锁存引脚 (ST_CP),锁存并行数据输出
// 数码管段选定义(共阴极:1=亮,0=灭),数组索引对应 0-9 和小数点
const byte disNum[11] = {
// 对应数码管段 a b c d e f g dp(小数点),1 表示亮,0 表示灭
0b11111100, // 0:a~f 亮,g、dp 灭
0b01100000, // 1:b、c 亮,其他灭
0b11011010, // 2:a、b、g、e、d 亮
0b11110010, // 3:a、b、g、c、d 亮
0b01100110, // 4:f、g、b、c 亮
0b10110110, // 5:a、f、g、c、d 亮
0b10111110, // 6:a、f、g、c、d、e 亮
0b11100000, // 7:a、b、c 亮
0b11111110, // 8:所有段亮
0b11110110, // 9:a、b、c、d、f、g 亮
0b00000001 // .:只有小数点亮
};
void setup() {
// 初始化引脚为输出模式,让 ESP32 能控制这些引脚电平
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
// 以下代码可根据需求调整,示例里仅做引脚初始电平设置(非必须,displayNumber 里会动态控制)
byte duan = 0b10110110;// 示例数值,可理解为预设段选(对应数字 5)
byte wei = 0b00000010;// 示例数值,可理解为预设位选(第二位亮)
digitalWrite(clockPin, LOW); // 时钟引脚置低
digitalWrite(latchPin, LOW); // 锁存引脚置低
}
// 显示函数:n 为要显示的数字(如 1234),逐位驱动数码管显示
void disPlayNumber(int n) {
byte wei = 0b00000001; // 初始位选,从最右边(第一位)数码管开始
// 当数字 n 不为 0 时,循环处理每一位
while (n != 0) {
// 1. 输出位选信号:决定点亮哪一位数码管(MSBFIRST 表示高位先传)
shiftOut(dataPin, clockPin, MSBFIRST, wei);
// 2. 输出段选信号:根据数字的当前位(n%10 取余),取反是因为共阴极数码管低电平驱动段亮(代码里定义 1 是亮,通过 ~ 取反适配硬件逻辑)
shiftOut(dataPin, clockPin, LSBFIRST, ~disNum[n%10]);
digitalWrite(latchPin, LOW); // 拉低锁存引脚,准备更新数据
digitalWrite(latchPin, HIGH); // 拉高锁存引脚,锁存数据,让数码管显示当前位
wei = (wei << 1); // 位选左移,切换到下一位数码管(从右往左)
n /= 10; // 数字去掉已处理的最后一位(如 1234→123→12→1→0 )
delay(2); // 延时短暂时间,利用视觉暂留让显示稳定(可调整,1 - 2ms 即可)
}
}
void loop() {
// 循环调用显示函数,持续显示数字 1234
disPlayNumber(1234);
}
2. 关键代码解析
- 引脚定义:
dataPin
、clockPin
、latchPin
对应 ESP32 控制 74HC595 的三个关键引脚,通过它们实现串行数据传输与锁存 。 disNum
数组:预先定义 0 - 9 和小数点对应的数码管段亮灭状态,用二进制直观表示各段(a - g、dp )的亮灭,方便快速查找 。shiftOut
函数:shiftOut(dataPin, clockPin, MSBFIRST, wei)
:从dataPin
逐位输出wei
的数据(MSBFIRST
表示高位先传 ),配合clockPin
时钟信号,将位选数据传入 74HC595 。shiftOut(dataPin, clockPin, LSBFIRST, ~disNum[n%10])
:同理,传输段选数据,LSBFIRST
是低位先传,~
取反适配共阴极数码管低电平驱动段亮的逻辑 。
latchPin
作用:先拉低(LOW
)准备接收新数据,再拉高(HIGH
)锁存数据,让 74HC595 并行输出当前数据,驱动数码管显示 。disPlayNumber
逻辑:通过while
循环逐位处理数字(n%10
取当前位、n/=10
去掉已处理位 ),配合位选左移(wei << 1
),实现多位数码管动态扫描显示 。
四、调试与扩展
1. 调试注意事项
- 硬件连接:确保 ESP32 引脚与 74HC595、数码管连接正确,尤其是
DS
、SH_CP
、ST_CP
对应关系,否则数据传输异常,数码管不亮或乱码 。 - 共阴/共阳适配:若数码管是共阳极,需修改
disNum
数组(1=灭,0=亮
),且shiftOut
时可能无需~
取反,根据实际硬件调整 。 - 延时调整:
delay(2)
可微调,太小可能显示闪烁,太大可能切换不流畅,根据实际视觉效果优化 。
2. 功能扩展
- 显示更多数字/字符:扩展
disNum
数组,添加字母(如 A、b 等)、特殊符号段选定义,实现更丰富显示 。 - 动态数据显示:结合传感器(如温度传感器),让
disPlayNumber
的参数从传感器读取,实时显示温度、湿度等数据 。 - 多组数码管级联:若有多个四位数码管,可增加 74HC595 级联,调整
shiftOut
传输数据长度和位选逻辑,实现更多位显示 。
通过本次学习,你掌握了 ESP32 + 74HC595 驱动四位数码管的核心逻辑,从硬件连接到代码控制都有了清晰认知。多动手调试、扩展功能,就能让数码管成为你项目中炫酷的显示窗口,继续探索嵌入式世界吧,你会发现更多有趣的玩法 !
0 条评论
目前还没有评论...