找回密码
 立即注册
查看: 168|回复: 6

关于SSD1306和SSD1315页寻址模式的疑问

[复制链接]

1

主题

3

回帖

27

积分

新手上路

积分
27
发表于 2026-10-19 14:25:36 | 显示全部楼层 |阅读模式
前些日子接触了0.96寸OLED显示屏,设计实在是巧妙,但近日遇到个问题迟迟无法找到答案。问题是,屏幕在页寻址模式下页地址指针会在列地址指针越界归零时也一起归零,虽然在嵌入式的设计场景中从根源上就可以设计避免越界行为,且不需要类似Windows系统一样渲染屏幕外的GUI,因此这个BUG实际上对正常显示没影响,我是偶然发现这个奇怪现象的。下图是从第2页,64列开始发送128个0xFF也就是全白数据的实际情况,从左到右依次是SSD1315,SSD1306,SSD1315:
6d3a3c2dead68257904bc62020eb993f.jpg
根据SSD1306的官方手册描述,页地址指针在列地址指针溢出归零时应该是保持不变的,所以这个现象确实令我十分费解,希望有大佬能够解答
b0c07dda7641fe8f59fa708c54d82ec6.png




Attention is not my need.
回复

使用道具 举报 送花

83

主题

8317

回帖

1万

积分

超级版主

积分
17932
发表于 2026-10-19 15:57:27 | 显示全部楼层
有可能是不同厂家的设计不同,好多厂家都在做。我驱动时都是有溢出判断的,写满即停。
回复

使用道具 举报 送花

1

主题

3

回帖

27

积分

新手上路

积分
27
 楼主| 发表于 2026-10-20 11:57:45 | 显示全部楼层
梁*** 发表于 2026-10-19 15:57
有可能是不同厂家的设计不同,好多厂家都在做。我驱动时都是有溢出判断的,写满即停。 ...

感谢解答,我以为ssd1306都是一个厂家的,没想到还有这种区别。不过确实如你所说不要溢出和越界就完全没问题了。
Attention is not my need.
回复

使用道具 举报 送花

49

主题

611

回帖

5448

积分

荣誉版主

积分
5448
发表于 2026-10-20 14:25:48 | 显示全部楼层

梁工说的不同厂家,说的是屏幕模块厂家,就是把SSD1306和SSD1305屏幕做成带PCB板的模块。跟现象无关。
SSD1306和SSD1315是同一个厂家的,只是主控芯片不同,SSD1306的一些功能不如SSD1315完善。



在SSD1306和SSD1315的芯片手册里,关于0x00、0x01、0xB0 这三条指令的说明里都有醒目注释,只能用于页地址模式。
如果在水平地址模式下使用了 0x00、0x01、0xB0 指令,如果数据超出列数的显示边界,就会出现这种BUG

具体现象分析可以看这个帖子

https://www.stcaimcu.com/forum.p ... id=18574&pid=178508

虽然在SSD1306和SSD1315的芯片手册里都说明了这一点,但是由于SSD1306功能不完善,所以反倒没有这个现象,
而SSD1315则严格遵守了这个规则,所以会出现这个问题。

至于照片里的三个屏幕,都是SSD1315,分辨方法很简单,最直接的方法是看排线的宽度。SSD1306的排线宽,SSD1315的窄,你的照片里的三块屏幕,排线都是窄的。
https://www.stcaimcu.com/forum.p ... id=18574&pid=178487
另外就是SSD1306在水平地址模式下不会出现越界就错位的问题。



SSD1306功能上不如SSD1315完善的地方还有很多,比如滚屏、对比度等等
详细的内容可以看这个帖子:

SSD1306更换SH1106的问题以及SSD1306和SSD1315的几种区别
https://www.stcaimcu.com/thread-21154-1-1.html
(出处: 国芯人工智能技术交流网站)



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

使用道具 举报 送花

1

主题

3

回帖

27

积分

新手上路

积分
27
 楼主| 发表于 2026-10-20 20:04:22 | 显示全部楼层
大*** 发表于 2026-10-20 14:25
梁工说的不同厂家,说的是屏幕模块厂家,就是把SSD1306和SSD1305屏幕做成带PCB板的模块。跟现象无关。
SSD ...

谢谢解答 ,没想到这些商家页面标注的是SSD1306,实际上卖的是SSD1315,估计商家也不知道两者的具体区别。

不过我目前最疑惑的是,我仔细看了好几遍代码我确实没设定水平模式,而我不管是在复位后默认的页寻址模式下,还是主动设定为页寻址模式下,列指针溢出后都会发生页指针置零,十分奇怪。我有一个猜想,SSD1315的页寻址模式实际上是限定为某一页的水平寻址模式,结合你提到的SSD1315特性,使得其不能越界(回绕)显示,不过我手边没有SSD1306屏幕无法验证。

另外我尝试了你说的对比度,垂直和水平滚屏,确实都可以正常实现,证明就是SSD1315了,不过没想到这种特性都能被你发现,厉害了

点评

用SSD1315屏幕试验了一下,你的猜想一部分是对的,列坐标越界 会出问题的现象,确实只出现在SSD1315主控的屏幕上。 而这个问题的触发条件也找到了。 SSD1306和SSD1315的数据手册里, 横向的寻址方式有两种: ( 0x  详情 回复 发表于 2026-10-21 10:53
Attention is not my need.
回复

使用道具 举报 送花

49

主题

611

回帖

5448

积分

荣誉版主

积分
5448
发表于 2026-10-21 10:53:10 | 显示全部楼层
Houp*** 发表于 2026-10-20 20:04
谢谢解答 ,没想到这些商家页面标注的是SSD1306,实际上卖的是SSD1315,估计商家也不知道两者的具体区别 ...

用SSD1315屏幕试验了一下,你的猜想一部分是对的,列坐标越界 会出问题的现象,确实只出现在SSD1315主控的屏幕上。
而这个问题的触发条件也找到了。

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

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

定位方式,也分为两种:

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

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


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

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

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

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

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

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


截图202610210854512316.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页。

截图202610211018391114.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列继续显示。

截图202610211020242652.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);

两个型号的屏幕也都在指定范围内显示出了内容
截图202610211022433580.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列继续显示,
并没有像手册里说的在同一页的起始列继续显示。

截图202610211027143281.jpg

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

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

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

截图202610211029051935.jpg


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


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

水平地址模式
截图202610211035282997.jpg
页地址模式
截图202610211035432991.jpg

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

所以,对于你的猜测的结论是

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



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

使用道具 举报 送花

1

主题

3

回帖

27

积分

新手上路

积分
27
 楼主| 发表于 2026-10-21 14:43:46 | 显示全部楼层
大*** 发表于 2026-10-21 10:53
用SSD1315屏幕试验了一下,你的猜想一部分是对的,列坐标越界 会出问题的现象,确实只出现在SSD1315主控的 ...

十分感谢!!!
那按这么说SSD1315自身其实也不算十分完善,这个解决问题的过程也算是印证了你的签名了
Attention is not my need.
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-11-7 14:26 , Processed in 0.076212 second(s), 76 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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