- 机器人等级考试
为什么SSD1306的y坐标必须是8的倍数?
- @ 2026-4-5 16:40:28
📊 为什么SSD1306的y坐标必须是8的倍数?
一、核心原因:SSD1306的页式(Page-based)显存结构
SSD1306驱动的128×64 OLED屏幕,显存不是按「像素行」存储的,而是按页(Page) 组织的,这是硬件设计的底层逻辑:
- 页的定义:屏幕被垂直划分为 8个页(Page 0 ~ Page 7),每个页固定对应 8行像素(1页=8行)
- Page 0:y=0 ~ y=7
- Page 1:y=8 ~ y=15
- ...
- Page 7:y=56 ~ y=63
- 字节与页的对应:每个页的一行像素,用 1个字节(8位) 存储,1位对应1个像素的亮灭(1=亮,0=灭)
- 1个字节刚好控制1行里的8个像素,1个页(8行)就用8×128个字节存储整页数据
- 函数的y参数本质:
ssd1306_drawXBitmap里的y,不是像素行号,而是「页号」- 要显示在y=0~7的像素区域,y参数填
0(0/8=0) - 要显示在y=8~15的像素区域,y参数填
1(8/8=1) - 以此类推,y参数必须是整数,因此实际像素y坐标必须是8的倍数,才能对应到完整的页
- 要显示在y=0~7的像素区域,y参数填
二、举个例子,一眼看懂
假设你要显示一个高度为16的位图:
- 实际像素y坐标:
16(从第16行开始显示) - 函数y参数:
16 / 8 = 2(对应Page 2,y=16~23) - 位图高度16,会自动占用 Page 2(16~23行) + Page 3(24~31行) 两个页,完美覆盖16行像素
如果y坐标不是8的倍数(比如y=5):
5 / 8 = 0.625,不是整数,无法对应到具体的页,硬件无法定位显存位置,会出现显示错乱、花屏、内容错位的问题
三、补充:x坐标为什么没有这个限制?
x轴是按列(Column) 寻址的,每列对应1个像素,128列对应x=0~127,没有按字节分组的限制,因此x坐标可以是0~127的任意整数,不需要是8的倍数。
四、实际开发的注意事项
- y坐标计算:实际像素y坐标 ÷ 8 = 函数的y参数,结果必须是整数
- 比如要垂直居中显示高度为16的位图:
- 屏幕总高度64,起始像素y = (64 - 16) / 2 = 24
- 函数y参数 = 24 / 8 = 3
- 比如要垂直居中显示高度为16的位图:
- 位图高度要求:位图高度也建议是8的倍数(如8、16、32、64),否则会出现页内像素截断、显示不全的问题
- 非8倍数y坐标的解决方案:如果需要精细定位,只能通过软件偏移(比如在图片数据里加空白行),硬件本身不支持非页对齐的y坐标
1 条评论
-
admin SU @ 2026-4-5 16:40:43已修改
📋 128×64 OLED 屏幕 y 坐标速查表(SSD1306 专用)
一、核心对应关系(页号 = 像素y ÷ 8)
SSD1306 屏幕总高度 64 像素(y=0~63),垂直划分为 8 个页(Page 0~7),每个页对应 8 行像素,函数入参 y = 像素起始y ÷ 8(必须为整数)
页号(函数y参数) 对应像素y范围 适用场景示例 0 0 ~ 7 屏幕最顶部显示(标题栏、图标) 1 8 ~ 15 第2行文字/图形 2 16 ~ 23 第3行文字/图形 3 24 ~ 31 屏幕垂直居中区域(常用) 4 32 ~ 39 下半部分上半区 5 40 ~ 47 第6行文字/图形 6 48 ~ 55 第7行文字/图形 7 56 ~ 63 屏幕最底部显示(状态栏、版权信息)
二、常用位图高度的垂直居中速查
直接套用,不用再计算!
位图高度h 屏幕总高度 像素起始y(居中) 函数y参数(y÷8) 占用页号 8 64 (64-8)/2 = 28 ❌(非8倍数,不支持) - 无(需调整h为16) 16 (64-16)/2 = 24 ✅ 24÷8 = 3 Page 3、4 32 (64-32)/2 = 16 ✅ 16÷8 = 2 Page 2、3、4、5 64 0 ✅ 0÷8 = 0 全部8个页(全屏) ⚠️ 注意:位图高度h也建议为8的倍数,否则会出现页内像素截断、显示不全的问题。如果h不是8的倍数,需要在图片数据中补空白行,让总高度凑成8的倍数。
三、常用文字行高对应(8x16 字体为例)
少儿编程中最常用的 8x16 中文字体,每个字高度 16 像素(占2个页),行高对应如下:
文字行数 像素起始y 函数y参数 对应页号 第1行 0 Page 0、1 第2行 16 2 Page 2、3 第3行 32 4 Page 4、5 第4行 48 6 Page 6、7
四、代码示例(直接套用)
1. 居中显示 64×16 位图
// 屏幕128×64,位图宽64、高16,水平+垂直居中 // x = (128-64)/2 = 32,y = (64-16)/2 = 24 → 函数y=24/8=3 ssd1306_drawXBitmap(32, 3, 64, 16, image_data);2. 底部显示 64×8 状态栏
// 位图高8,像素起始y=64-8=56 → 函数y=56/8=7 ssd1306_drawXBitmap(0, 7, 64, 8, status_bar_data);
五、避坑小贴士
- y参数不是像素坐标:函数里的y是「页号」,不是像素行号,千万不要直接填像素y!
- 非8倍数y的处理:如果需要精细定位,只能在图片数据里加空白行,硬件不支持非页对齐的y坐标
- x坐标无限制:x轴按列寻址,0~127任意整数都可以,不需要是8的倍数
- 高度溢出检查:位图高度h + 像素起始y ≤ 64,否则会超出屏幕显示不全
- 1