📌 专栏:Arduino进阶实战
💡 适合人群:Arduino入门进阶学习者、想要掌握多位数码管驱动、理解动态扫描原理的开发者
🔖 核心知识点:四位数码管结构、动态扫描原理、先选位后选段、视觉暂留、数组批量控制
一、前言:为什么要用四位数码管动态扫描?
在单片机开发中,如果我们直接驱动四个独立的一位数码管,需要占用32个IO口,不仅极度浪费硬件资源,接线繁琐,代码冗余,开发效率极低。
而四位一体数码管完美解决了这个问题,通过硬件并联设计+动态扫描算法,仅需 12个IO口(8个段码引脚+4个位选引脚) 即可实现四位数字同时显示,是计时器、计数器、温湿度显示、车速显示等项目的核心外设。
很多新手疑惑:四个数码管明明是逐个点亮,为什么肉眼看起来是同时亮的?

答案就是:人眼视觉暂留效应。高速轮流点亮四个数码管,间隔仅5ms左右,人眼无法捕捉闪烁,最终形成“同时点亮”的视觉效果。
二、四位数码管硬件工作原理
2.1 硬件结构设计
四位共阴数码管结构非常规整,核心分为两部分:
- 段码端(a、b、c、d、e、f、g、dp):四个数码管的同名段脚全部并联,共用8个IO口,统一控制数字的字形。
- 位选端(A1、A2、A3、A4):四个独立引脚,分别对应第一位、第二位、第三位、第四位数码管,负责控制单个数码管的启停。

2.2 核心控制逻辑:先选位,再选段
这是四位数码管驱动的核心口诀,所有动态扫描代码都基于这个逻辑编写:

2.3 标准扫描流程(以显示3、5为例)
三、硬件接线方案
本次教程采用通用接线方式,适配绝大多数四位共阴数码管,可直接照搬:
引脚分配

段码引脚(公共端)
a、b、c、d、e、f、g、dp 依次接 Arduino 2、3、4、5、6、7、8、9
位选引脚(独立端)
A1(第一位)、A2(第二位)、A3(第三位)、A4(第四位) 依次接 10、11、12、13
四、课堂实验:四位数码管显示 2019(完整源码)
4.1 实验需求
通过动态扫描算法,让四位数码管稳定显示数字 2019,无闪烁、无重影、无残影。
4.2 完整可运行代码
// 四位数码管段码引脚 a b c d e f g dp
byte seg_pin[8] = {2, 3, 4, 5, 6, 7, 8, 9};
// 四位数码管位选引脚 A1 A2 A3 A4
byte bit_pin[4] = {10, 11, 12, 13};
// 0~9 数码管标准段码(适配共阴数码管)
bool num_code[10][8] = {
{0,0,0,0,0,0,0,0}, // 0
{0,1,1,0,0,0,0,0}, // 1
{1,1,0,1,1,0,1,0}, // 2
{1,1,1,1,0,0,1,0}, // 3
{0,1,1,0,0,1,1,0}, // 4
{1,0,1,1,0,1,1,0}, // 5
{1,0,1,1,1,1,1,0}, // 6
{1,1,1,0,0,0,0,0}, // 7
{1,1,1,1,1,1,1,0}, // 8
{1,1,1,1,0,1,1,0} // 9
};
// 四位数码管动态扫描函数
void displayScan(int data[4])
{
// 循环扫描四个数码管
for(int i = 0; i < 4; i++)
{
// 1. 关闭所有位选,消除残影
for(int j = 0; j < 4; j++)
{
digitalWrite(bit_pin[j], HIGH);
}
// 2. 加载当前位置数字段码
for(int k = 0; k < 8; k++)
{
digitalWrite(seg_pin[k], num_code[data[i]][k]);
}
// 3. 选中当前数码管,点亮显示
digitalWrite(bit_pin[i], LOW);
// 4. 视觉暂留延时
delay(5);
}
}
void setup()
{
// 初始化段码引脚为输出模式
for(int i = 0; i < 8; i++)
{
pinMode(seg_pin[i], OUTPUT);
}
// 初始化位选引脚为输出模式
for(int i = 0; i < 4; i++)
{
pinMode(bit_pin[i], OUTPUT);
}
}
void loop()
{
// 固定显示 2 0 1 9
int show_data[4] = {2, 0, 1, 9};
displayScan(show_data);
}
五、课后练习:四位数码管显示数字 12
5.1 练习需求
在四位数码管上稳定显示数字 12,默认左对齐显示,后两位空白熄灭。
5.2 实现思路
复用上面完整代码,仅需修改主循环中的显示数组,前两位赋值1、2,后两位填充无效值,配合逻辑实现空白效果。
5.3 核心修改代码
void loop()
{
// 前两位显示1、2,后两位默认熄灭
int show_data[4] = {1, 2, 0, 0};
displayScan(show_data);
}
如需纯空白不显示,可自定义一组全0段码,替换后两位数值即可实现完美留白效果。
六、开发常见问题与解决方案
1. 数码管闪烁严重
原因:扫描延时过短或循环频率过低 | 解决方案:固定延时5ms,不要低于3ms
2. 数字出现重影、残影
原因:未先关闭所有位选就刷新段码 | 解决方案:严格遵循「先关所有位→刷新段码→打开当前位」的顺序
3. 数字显示错乱
原因:位选引脚顺序与显示数组顺序不匹配 | 解决方案:核对A1-A4引脚接线与数组顺序一致
七、知识点总结
- 四位数码管核心优势:IO口极致节省,用12个引脚实现四位数字显示
- 驱动核心原理:动态扫描 + 视觉暂留,逐位高速轮流点亮
- 固定执行顺序:先选位、后选段、短延时、循环扫描
- 代码核心思想:二维数组封装段码,函数封装扫描逻辑,代码简洁可复用
掌握本篇内容后,可自主拓展倒计时、秒表、温度数值显示、计数累加等经典Arduino项目!
原创Arduino进阶教程持续更新,点赞收藏,解锁更多单片机实战项目!
![[开源]基于STM32单片机WiFi智能停车场系统 Onene车位管理设计 云平台停车场车位检测 APP智慧停车场HK-010-171主机测评](https://www.171host.com/wp-content/uploads/2026/09/20260921150408-6ab1476821e49-220x150.jpg)



