用SSD1315屏幕试验了一下,你的猜想一部分是对的,列坐标越界 会出问题的现象,确实只出现在SSD1315主控的屏幕上。
而这个问题的触发条件也找到了。
SSD1306和SSD1315的数据手册里,
横向的寻址方式有两种:
( 0x20, 0x00 ) 水平地址模式;
( 0x20, 0x02 ) 页地址模式;
定位方式,也分为两种:
用于水平地址模式的
( 0x21, 起始列地址, 结束列地址 )
( 0x22, 起始页地址, 结束页地址 )
和用于页地址模式的
( 0x00+列地址低四位, 0x10+列地址高四位 )
( 0xB0+页地址 )
在定位指令的说明部分,也分别有使用条件的限制要求
指令 0x21 和 0x22,只能用于 水平地址模式 或者 垂直地址模式。
指令 0x00、0x10、0xB0,只能用于 页地址模式
连续填充数据的时候,两种寻址方式也有区别。
在水平地址模式下,
连续填充数据的时候,列地址会自动加1。
当列地址达到设置的结束列边界后,列地址会自动回到起始列地址,同时,页地址也会自动加1。
当列地址和页地址都达到设置的结束边界后,列地址和页地址都会自动回到设置的起始地址。
在页地址模式下
连续填充数据的时候,列地址会自动加1。
当列地址达到最大列地址后,会回到设置的起始列的位置。
页地址保持不变。
由于SSD1306属于早期不完善版本,而SSD1315则相对比较完善,
所以两者对于指令的执行效果也是有很大区别的,
其中就包括了对于“列地址越界后”的显示结果。
用一段测试代码做了下实验
先发送64个0xFF,连续点亮64列,
然后发送64个0xAA,接着连续点亮64列;
最后发送32个0x66,接着连续点亮32列。
由于三种图案总共连续发送了160个数据,所以必然存在越界情况。
- for( i=0; i<64; i++ )
- OLED_WR_Byte ( 0xFF, OLED_DATA );
- for( i=0; i<64; i++ )
- OLED_WR_Byte ( 0xAA, OLED_DATA );
复制代码
在这之前将寻址模式分别设置为 水平地址模式 和 页地址模式,然后进行试运行。
实验1-1、设置为水平地址模式,不指定显示范围
- OLED_WR_Byte ( 0x20, OLED_CMD ); // 水平地址模式
- OLED_WR_Byte ( 0x00, OLED_CMD );
复制代码
由于列地址越界,SSD1306的屏幕的显示发生了异常,
页地址发生了混乱,起始页跑到了第7页,越界部分则在第0页的起始位置开始显示。
而SSD1315的屏幕,则显示出了正确的结果,
从第0页的第0列开始显示,填满一页之后,拐到下面一页的第0列继续显示。
说明 SSD1315 正确调用了 默认设置的 0~127列 和 0~7页。
实验1-2、设置为水平地址模式,添加设置显示边界的指令
- OLED_WR_Byte( 0x20, OLED_CMD); // 水平地址模式
- OLED_WR_Byte( 0x00, OLED_CMD);
-
- OLED_WR_Byte( 0x21, OLED_CMD); // 设置列地址范围:0~127
- OLED_WR_Byte( 0, OLED_CMD);
- OLED_WR_Byte( 127, OLED_CMD);
-
- OLED_WR_Byte( 0x22, OLED_CMD); // 设置页地址范围:0~7
- OLED_WR_Byte( 0x00, OLED_CMD);
- OLED_WR_Byte( 0x07, OLED_CMD);
复制代码
此时,两个型号的屏幕在正确位置显示了160个数据
在屏幕第0页、第0列的位置开始显示,填满一页之后,拐到下面一页的第0列继续显示。
实验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);
两个型号的屏幕也都在指定范围内显示出了内容
实验2-1、设置为页地址模式,指定页地址为第4页,不指定起始列地址(默认使用第0列)
- OLED_WR_Byte ( 0x20, OLED_CMD );
- OLED_WR_Byte ( 0x02, OLED_CMD ); // 页地址模式
复制代码
这次,SSD1306 表现良好,
在屏幕第4页、第0列的位置开始显示,填满一页之后,回到第4页、第0列继续显示,覆盖掉了前面32列的内容。
而 SSD1315 则因为列地址越界,出现了显示异常,
在屏幕第4页、第0列的位置开始显示,填满一页之后,回到了第0页、第0列继续显示,
并没有像手册里说的在同一页的起始列继续显示。
实验2-2、设置为页地址模式,指定页地址为第4页,并将起始列地址设置为64(跟1楼的设置相同)
显示结果依旧是
SSD1306 表现良好,
在屏幕第4页、第64列的位置开始显示,填满一页之后,回到第4页、第0列继续显示,覆盖掉了前面96列的内容。
而 SSD1315 因为页地址越界,出现了异常。
在屏幕第4页、第64列的位置开始显示,填满一页之后,跑到了第0页、第0列继续显示剩下的96列内容。
实验3-1、同时使用两种定位方式,
显示范围为起始列64,结束列127;
指定其实页地址为第4页,起始列地址设置为第0列
结果无论是水平地址模式还是页地址模式,初始列地址都会出现异常,
起始列都会变成屏幕的第0列,而不是设置的起始列,之后的数据才会按照设置规则进行显示
且 SSD1315 均有越界异常现象。
水平地址模式
页地址模式
==========================================
所以,对于你的猜测的结论是
SSD1315 的屏幕,在列地址模式下,或者使用了列地址模式的定位指令后,都不允许列地址超出显示边界,
否则就会在第一次越界之后,页地址就会跑到第0页。
SSD1306 的屏幕则没有这种问题。
|