从零构建 48×8 滚动 LED 矩阵显示屏:Arduino 入门指南
组件与物料
| Arduino UNO | ×1 |
| 74HC595 8 位串并转换寄存器 | ×7 |
| 475Ω 电阻 | ×56 |
| 单排针 40P (2.54mm) | ×2 |
| 单排母座 8P (2.54mm) | ×21 |
| 通用孔板 6″×4″ | ×4 |
| 8×8 LED 点阵模块 (共阴) | ×6 |
| BC548 三极管 | ×1 |
所需工具
- 烙铁 (通用)
- 热熔胶枪 (通用)
- 数字万用表
应用与在线服务
- Arduino IDE
项目简介
大家好!
本项目讲解如何用 Arduino UNO 和 74HC595 移位寄存器制作 48×8 可编程滚动 LED 矩阵。这是我的第一个 Arduino 项目,源于老师的挑战。接受挑战时我连用 Arduino 点亮 LED 都不会,所以我认为哪怕是新手,只要有耐心和理解力也能完成。我只在网上找到了原理图作为唯一参考,随后自学移位寄存器和 Arduino 多路复用原理。
电路原理

单个 74HC595 控制 8 行,列控制每 8 列用一个 74HC595。因此只要会做 8×8 矩阵,就能通过复制列控制电路无限扩展列数——每增加一块 8×8 模块 (8 列) 就加一颗 74HC595,无列数上限。
元件采购
元件多渠道采购。5mm 8×8 共阴点阵从网上购得。

原型验证

先在面包板搭建 8×8 原型验证行列扫描逻辑。
焊接制作
行控制和列控制分别用独立孔板,引出排针/排母互连。

成功做出 8×8 后,只需级联更多共用时钟的 74HC595 驱动列。行控制始终只需一颗 74HC595。根据列数添加移位寄存器,列数无上限。
后半段制作

当时无 3D 打印条件,找木工做外壳,尺寸比预期大很多。建议用 Fusion 360 等设计紧凑外壳再 3D 打印。外壳开孔引出电源和 USB 线。

程序代码
代码见附件。核心逻辑:行扫描 + 列数据移位。代码决定滚动速度和显示内容,默认右向左滚动,稍作修改可实现其他方向。
最终效果
完成!谢谢观看 :)
完整代码
/*////////////////////////////////////////////////////////////////////////////////
* Arduino code to display scrolling characters on 6 or more 8x8 LED matrix.
* Matrix count can be increased with a small code change.
* Comments in each statement for editing.
* Coded by Prasanth K S | Contact: kksjunior@hotmail.com
*////////////////////////////////////////////////////////////////////////////////
char msg[] = "WELCOME WIZ"; // 修改显示文本
int scrollspeed = 5; // 滚动速度 (越小越快)
int x, y;
// 列控制引脚 (74HC595)
int clockPin1 = 2; // Clock Pin 11
int latchPin1 = 3; // Latch Pin 12
int dataPin1 = 4; // Data Pin 14
// 行控制引脚 (74HC595)
int clockPin2 = 5; // Clock Pin 11
int latchPin2 = 6; // Latch Pin 12
int dataPin2 = 7; // Data Pin 14
// 位图缓冲: 8 行 × 7 区域 (每区域 8 列 = 1 个 8x8 模块)
byte bitmap[8][7];
int numZones = sizeof(bitmap) / 8; // 区域数 = 模块数
int maxZoneIndex = numZones - 1;
int numCols = numZones * 8; // 总列数
// 字库定义: 每字符 5 列,额外 2 列空白间隔
byte alphabets[][8] = {
{0,0,0,0,0}, // @ as SPACE
{31, 36, 68, 36, 31}, // A
{127, 73, 73, 73, 54}, // B
{62, 65, 65, 65, 34}, // C
{127, 65, 65, 34, 28}, // D
{127, 73, 73, 65, 65}, // E
{127, 72, 72, 72, 64}, // F
{62, 65, 65, 69, 38}, // G
{127, 8, 8, 8, 127}, // H
{0, 65, 127, 65, 0}, // I
{2, 1, 1, 1, 126}, // J
{127, 8, 20, 34, 65}, // K
{127, 1, 1, 1, 1}, // L
{127, 32, 16, 32, 127}, // M
{127, 32, 16, 8, 127}, // N
{62, 65, 65, 65, 62}, // O
{127, 72, 72, 72, 48}, // P
{62, 65, 69, 66, 61}, // Q
{127, 72, 76, 74, 49}, // R
{50, 73, 73, 73, 38}, // S
{64, 64, 127, 64, 64}, // T
{126, 1, 1, 1, 126}, // U
{124, 2, 1, 2, 124}, // V
{126, 1, 6, 1, 126}, // W
{99, 20, 8, 20, 99}, // X
{96, 16, 15, 16, 96}, // Y
{67, 69, 73, 81, 97} // Z
};
void setup() {
pinMode(latchPin1, OUTPUT);
pinMode(clockPin1, OUTPUT);
pinMode(dataPin1, OUTPUT);
pinMode(latchPin2, OUTPUT);
pinMode(clockPin2, OUTPUT);
pinMode(dataPin2, OUTPUT);
// 清空位图
for (int row = 0; row < 8; row++)
for (int zone = 0; zone <= maxZoneIndex; zone++)
bitmap[row][zone] = 0;
}
// 刷新显示: 行扫描 + 列移位输出
void RefreshDisplay() {
for (int row = 0; row < 8; row++) {
int rowbit = 1 << row;
digitalWrite(latchPin2, LOW);
shiftOut(dataPin2, clockPin2, MSBFIRST, rowbit);
digitalWrite(latchPin1, LOW);
for (int zone = maxZoneIndex; zone >= 0; zone--)
shiftOut(dataPin1, clockPin1, MSBFIRST, bitmap[row][zone]);
digitalWrite(latchPin1, HIGH);
digitalWrite(latchPin2, HIGH);
delayMicroseconds(300);
}
}
// 设置/清除指定像素
void Plot(int col, int row, bool isOn) {
int zone = col / 8;
int colBitIndex = col % 8;
byte colBit = 1 << colBitIndex;
if (isOn) bitmap[row][zone] |= colBit;
else bitmap[row][zone] &= ~colBit;
}
// 逐列绘制字符、刷新、左移位图
void XProcess() {
for (int charIndex = 0; charIndex < (sizeof(msg) - 1); charIndex++) {
int alphabetIndex = msg[charIndex] - '@';
if (alphabetIndex < 0) alphabetIndex = 0;
// 每字符 5 列 + 2 列空白 = 7 列
for (int col = 0; col < 7; col++) {
for (int row = 0; row < 8; row++) {
bool isOn = 0;
if (col < 5) isOn = bitRead(alphabets[alphabetIndex][col], 7 - row) == 1;
Plot(numCols - 1, row, isOn); // 在最右列绘制,后续左移形成滚动
}
for (int refreshCount = 0; refreshCount < scrollspeed; refreshCount++)
RefreshDisplay();
// 位图左移一列 (右移位操作因最低位代表最左列)
for (int row = 0; row < 8; row++) {
for (int zone = 0; zone < numZones; zone++) {
bitmap[row][zone] >>= 1;
if (zone < maxZoneIndex)
bitWrite(bitmap[row][zone], 7, bitRead(bitmap[row][zone + 1], 0));
}
}
}
}
}
void loop() {
XProcess();
}
原理图参考
仅供参考,引脚连接请以代码注释为准。

制造工艺
- 用 Arduino 打造绚丽显示器 Ambilight 系统
- Arduino + HC-05 蓝牙控制 LED:MIT App Inventor 手机 App 开发全攻略
- 互动 LED 矩阵门显:PIR 触发节日问候 + 待机特效
- 从零构建智能 Arduino 四足机器人:完整指南
- Bolt IoT + Arduino UNO 实现 6 路 LED 无级调光
- Arduino 8×8 LED 矩阵翻页时钟 - DIY 实时时钟项目
- Arduino RGB LED调色器:三电位器混色入门项目
- Arduino Uno驱动MAX7219级联8×8 LED矩阵:从入门到动画显示
- 使用 Arduino Nano 和 RDA8057M 制作紧凑型 FM 收音机
- 户外DMX控制RGB投光灯:低成本高性能舞台灯光DIY方案
- DIY LED 轮盘赌游戏机 —— Arduino Nano 打造单人桌面街机
- Arduino 智能自动停车场系统:红外检测 + 舵机闸门 + LED 余位显示