ESP32-S3 驱动 64×64 P2.5 LED 灯板:HUB75 通信、位平面与刷新时序详解
前言
ESP32-S3的HUB75 通信,在应用层,点亮一个像素可能只需要一行代码:
display->drawPixel(x, y, color);
但 P2.5 HUB75 灯板并不认识坐标和 drawPixel()。这个函数只修改内存中的显示缓冲区,真正让灯珠发光的,是后台持续运行的 HUB75 刷新引擎。
本文以 ESP32-S3 和一块 64×64、1/32 扫描的 P2.5 灯板为例,详细拆解:
- HUB75 每类信号的作用;
- 一行数据如何移入和锁存;
- 第一个发送的 bit 最后去了哪里;
- RGB888 如何被拆成位平面;
- 8 MHz、约 100 Hz 和 30 FPS 分别表示什么。
1. HUB75 和 WS2812B 有什么本质区别
WS2812B 通过一根数据线接收每颗灯珠的 GRB 数据,灯珠内部自己完成 PWM 调光。
普通 HUB75 灯板则更像一组需要外部不断扫描的移位寄存器和行驱动电路。它不接收“第 120 个像素亮度为 37”这种完整命令,只会观察:
- RGB 数据线当前是 0 还是 1;
- CLK 什么时候跳变;
- LAT 什么时候锁存;
- A~E 选中了哪一个行组;
- OE 什么时候允许输出。
2. HUB75 信号线的作用
2.1 RGB1 和 RGB2
R1/G1/B1 负责上半屏,R2/G2/B2 负责下半屏。在一个 CLK 中,六根线可以同时送入上下两个像素的 RGB bit。
2.2 A、B、C、D、E
这五根线是行地址。对 1/32 扫描面板,它们可以表示 0~31 的行组地址。
例如地址 5 通常同时对应第 5 行和第 37 行,两行分别使用 RGB1 和 RGB2 数据。
2.3 CLK
CLK 是移位时钟。每个有效脉冲会把当前六根 RGB 线上的 bit 推入移位链。对于一行 64 列的面板,一个位平面、一组上下行需要 64 个 CLK。
2.4 LAT
LAT 是锁存信号。64 列数据填满移位寄存器后,给 LAT 一个脉冲,将整行数据一次性切换到输出端。
2.5 OE
OE 可以理解为输出总开关,通常低电平有效:
- OE 拉高:暂时关闭所有输出;
- OE 拉低:允许当前选中的行点亮。
更换数据和行地址时先关闭输出,可以避免中间状态变成鬼影。OE 的导通时间还参与亮度和灰度控制。
3. 一行像素如何被送进灯板
对某个位平面和某个行组,基本步骤如下:
- 设置当前列的 R1/G1/B1/R2/G2/B2。
- 产生一个 CLK,将六个 bit 同时推入。
- 重复 64 次,填满当前行的所有列。
- OE 拉高,暂时关闭显示输出。
- 触发 LAT,锁存整行数据。
- 设置 A~E,选择目标行组。
- OE 拉低并保持指定时长,显示当前行。
4. 第一个发送的 bit 最后去了哪里
假设移位链是:
DIN -> Q0 -> Q1 -> ... -> Q63
第一个 bit 最初进入 Q0,后续每来一个 CLK,它都会继续向后移一位。当 64 个 bit 全部送完时:
- 最先发送的 bit 到达 Q63;
- 最后发送的 bit 留在 Q0。
但 Q63 对应屏幕左侧还是右侧,取决于面板 PCB 走线。因此更准确的结论是:第一个数据最终会被推到移位链远端,左右映射由面板和驱动库决定。
5. 什么是位平面
颜色通道通常使用 0~255 表示亮度。例如红色亮度为 13:
13 = 00001101(B) = 8 + 4 + 1
驱动程序会把所有像素的 b0 抽出来组成第 0 个位平面,再把所有像素的 b1 抽出来组成第 1 个位平面,直到 b7。
可以把 RGB888 图像想象成 8 张只有 0 和 1 的透明片。每一层同时包含 R、G、B 对应位的数据,不是将三个通道分成 24 轮顺序发送。
位权从低到高为:
b0 b1 b2 b3 b4 b5 b6 b7
1 2 4 8 16 32 64 128
高位平面需要更长的显示时间。驱动器快速轮播这些平面,人眼就会将它们融合成最终亮度。
6. 8 个位平面需要多少 CLK
一个位平面的一个行组需要 64 个 CLK,因此 8 个位平面需要:
64列 × 8个位平面 = 512个CLK/行组
1/32 扫描的整屏基础移位次数为:
64列 × 8个位平面 × 32个行组 = 16384个CLK
实际还存在 LAT、OE、位权时间、DMA 描述符和低位平面合并等开销,所以不能只用 CLK / 16384 粗暴当作最终刷新率。
7. 8 MHz、约 100 Hz 和 30 FPS 的区别
7.1 8 MHz:CLK 时钟
matrixConfig.i2sspeed = HUB75_I2S_CFG::HZ_8M;
8 MHz 表示移位时钟周期约为 125 ns,描述数据推入面板的速度。
7.2 约 100 Hz:HUB75 扫描刷新率
在本项目的 64×64、8 bit 色深、1/32 扫描和当前库配置下,计算刷新率约为 100 Hz。
该数值不是所有 P2.5 灯板的固定参数,它会受面板尺寸、扫描方式、色深、CLK 和驱动策略影响。
7.3 30 FPS:应用画面更新率
constexpr uint16_t TARGET_FPS = 30;
30 FPS 表示流体算法每秒生成 30 张新画面。在两张画面之间,HUB75 驱动仍然按约 100 Hz 重复扫描当前缓冲区。
8. 驱动库替应用程序做了什么
本项目使用 ESP32 HUB75 DMA 类驱动库。它主要完成:
- 将 RGB888 拆成位平面;
- 将 x/y 坐标映射到行、列和上下半屏;
- 组织 RGB、CLK、LAT、OE 和行地址时序;
- 利用 I2S 并行外设和 DMA 持续输出;
- 在刷新率、色深、内存和亮度之间折中。
总结
HUB75 的核心不是一条“发送完整像素数据”的串行协议,而是一套由完整时序配合起来的扫描机制:
拆分位平面
-> 设置RGB数据
-> CLK逐列移入
-> LAT锁存
-> A~E选行
-> OE控制点亮时间
-> 快速重复
应用程序可以继续使用成熟库,但理解这条底层链路后,面对错行、偏色、鬼影、闪烁和刷新率不足时,就能更快找到排查方向。
我是阿白,感谢您的观看。
更多推荐


所有评论(0)