找回密码
 立即注册
查看: 141|回复: 1

关于SSD1306和SSD1315屏幕页地址模式下的寻址问题

[复制链接]

49

主题

611

回帖

5448

积分

荣誉版主

积分
5448
发表于 2026-10-21 11:24:43 | 显示全部楼层 |阅读模式
关于最近坛友Houppen在使用SSD1315的OLED屏幕时发现的,
在页地址模式下,列坐标越界之后,页地址定位异常的现象,
截图202610211124288801.jpg


于是用SSD1306和SSD1315的屏幕做了下实验,发现的确存在这样的问题。并且找了下造成这种问题的原因。

SSD1306和SSD1315的数据手册里,
横向的寻址方式有两种:

( 0x20, 0x00 ) 水平地址模式;
( 0x20, 0x02 ) 页地址模式;

定位方式,也分为两种:

用于水平地址模式的
( 0x21, 起始列地址, 结束列地址 )
( 0x22, 起始页地址, 结束页地址 )

和用于页地址模式的
( 0x00+列地址低四位, 0x10+列地址高四位 )
( 0xB0+页地址 )


在定位指令的说明部分,也分别有使用条件的限制要求

指令 0x21 和 0x22,只能用于 水平地址模式 或者 垂直地址模式。
截图202610211107479490.jpg

指令 0x00、0x10、0xB0,只能用于 页地址模式
截图202610211108252531.jpg

连续填充数据的时候,两种寻址方式也有区别。

在水平地址模式下,
连续填充数据的时候,列地址会自动加1。
当列地址达到设置的结束列边界后,列地址会自动回到起始列地址,同时,页地址也会自动加1。
当列地址和页地址都达到设置的结束边界后,列地址和页地址都会自动回到设置的起始地址。

在页地址模式下
连续填充数据的时候,列地址会自动加1。
当列地址达到最大列地址后,会回到设置的起始列的位置。
页地址保持不变。


截图202610211108451232.jpg

由于SSD1306属于早期不完善版本,而SSD1315则相对比较完善,
所以两者对于指令的执行效果也是有很大区别的,
其中就包括了对于“列地址越界后”的显示结果。

用一段测试代码做了下实验

先发送64个0xFF,连续点亮64列,
然后发送64个0xAA,接着连续点亮64列;
最后发送32个0x66,接着连续点亮32列。

由于三种图案总共连续发送了160个数据,所以必然存在越界情况。

  1. for( i=0; i<64; i++ )
  2.     OLED_WR_Byte ( 0xFF, OLED_DATA );
  3. for( i=0; i<64; i++ )
  4.     OLED_WR_Byte ( 0xAA, OLED_DATA );
复制代码


在这之前将寻址模式分别设置为 水平地址模式 和 页地址模式,然后进行试运行。

实验1-1、设置为水平地址模式,不指定显示范围
  1. OLED_WR_Byte ( 0x20, OLED_CMD ); // 水平地址模式
  2. OLED_WR_Byte ( 0x00, OLED_CMD );
复制代码

由于列地址越界,SSD1306的屏幕的显示发生了异常,
页地址发生了混乱,起始页跑到了第7页,越界部分则在第0页的起始位置开始显示。

而SSD1315的屏幕,则显示出了正确的结果,
从第0页的第0列开始显示,填满一页之后,拐到下面一页的第0列继续显示。
说明 SSD1315 正确调用了 默认设置的 0~127列 和 0~7页。

截图202610211109201551.jpg


实验1-2、设置为水平地址模式,添加设置显示边界的指令
  1. OLED_WR_Byte( 0x20, OLED_CMD); // 水平地址模式
  2. OLED_WR_Byte( 0x00, OLED_CMD);
  3. OLED_WR_Byte( 0x21, OLED_CMD);  // 设置列地址范围:0~127
  4. OLED_WR_Byte( 0, OLED_CMD);
  5. OLED_WR_Byte( 127, OLED_CMD);
  6. OLED_WR_Byte( 0x22, OLED_CMD);  // 设置页地址范围:0~7
  7. OLED_WR_Byte( 0x00, OLED_CMD);
  8. OLED_WR_Byte( 0x07, OLED_CMD);
复制代码

此时,两个型号的屏幕在正确位置显示了160个数据
在屏幕第0页、第0列的位置开始显示,填满一页之后,拐到下面一页的第0列继续显示。

截图202610211109416598.jpg


实验1-3、将实验1-2的起始列地址设置为64
OLED_WR_Byte( 0x21, OLED_CMD);  // 设置列地址范围:0~127
OLED_WR_Byte( 64, OLED_CMD);
OLED_WR_Byte( 127, OLED_CMD);

两个型号的屏幕也都在指定范围内显示出了内容
截图202610211110034765.jpg


实验2-1、设置为页地址模式,指定页地址为第4页,不指定起始列地址(默认使用第0列)
  1. OLED_WR_Byte ( 0x20, OLED_CMD );
  2. OLED_WR_Byte ( 0x02, OLED_CMD ); // 页地址模式
复制代码


这次,SSD1306 表现良好,
在屏幕第4页、第0列的位置开始显示,填满一页之后,回到第4页、第0列继续显示,覆盖掉了前面32列的内容。

而 SSD1315 则因为列地址越界,出现了显示异常,
在屏幕第4页、第0列的位置开始显示,填满一页之后,回到了第0页、第0列继续显示,
并没有像手册里说的在同一页的起始列继续显示。

截图202610211110274103.jpg

实验2-2、设置为页地址模式,指定页地址为第4页,并将起始列地址设置为64(跟1楼的设置相同)
显示结果依旧是

SSD1306 表现良好,
在屏幕第4页、第64列的位置开始显示,填满一页之后,回到第4页、第0列继续显示,覆盖掉了前面96列的内容。

而 SSD1315 因为页地址越界,出现了异常。
在屏幕第4页、第64列的位置开始显示,填满一页之后,跑到了第0页、第0列继续显示剩下的96列内容。

截图202610211110463978.jpg


实验3-1、同时使用两种定位方式,
显示范围为起始列64,结束列127;
指定其实页地址为第4页,起始列地址设置为第0列


结果无论是水平地址模式还是页地址模式,初始列地址都会出现异常,
起始列都会变成屏幕的第0列,而不是设置的起始列,之后的数据才会按照设置规则进行显示
且 SSD1315 均有越界异常现象。

水平地址模式
截图202610211111078479.jpg


页地址模式
截图202610211111286120.jpg

==========================================

结论是

1、
SSD1315 的屏幕,在列地址模式下,或者使用了列地址模式的定位指令后,都不允许列地址超出显示边界,
否则就会在第一次越界之后,页地址就会跑到第0页。
SSD1306 的屏幕则没有这种问题。

2、
水平地址模式 和 页地址模式 对应的定位指令,不能混用,更不能共用。
否则页地址和列地址会出现异常。

所以如果用的是 SSD1315 主控的OLED屏幕,最佳建议是


水平地址模式下,
最好使用 设置显示范围的指令 0x21、0x22 。
用法跟TFT彩屏相同,先设置区域,再连续填入要显示的数据。
如果一定想要使用指令 0x00、0x01、0xB0 进行定位,那么需要注意在连续发送数据的时候,不能超出屏幕设置的右边界。

页地址模式下,
使用指定起始列地址和起始页地址的指令 0x00、0x01、0xB0。
也就是常见的OLED屏幕使用的定位方法。
这种方法对SH1106等OLED屏幕也有很好的兼容性。





能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复

使用道具 举报 送花

已绑定手机

2

主题

154

回帖

470

积分

中级会员

积分
470
发表于 2026-10-22 11:57:19 | 显示全部楼层
很有用的知识,学习了,感谢分享。
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-11-7 13:18 , Processed in 0.070860 second(s), 49 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表