|
|
发表于 2026-9-11 10:06:41
|
显示全部楼层
首先确认一下,用的OLED屏幕是哪个尺寸的?
“手册上说是128*64分辨率”指的是SSD1306控制芯片最大支持128*64点阵分辨率,而实际用在屏幕上时,会根据不同规格的屏幕,使用全部或者一部分。
比如3楼照片里的这种 分辨率是 128*32 点阵的,就只用到了一半的行数。

之所以16*16的字符会显示成照片里那样的16*8,是因为你给128*32的屏幕用了128*64的配置程序
先说一下扫描顺序
OLED模块的厂家通常用的是奇数行和偶数行分开控制的接线方式
也就是将行(ROW)分成了两组:
(偶数行) ROW0, ROW2, ROW4, …… ROW60, ROW62
和
(奇数行) ROW1, ROW3, ROW5, …… ROW61, ROW63
而你用的这块 128*32点阵 的屏幕模块,内部同样用的是这种接线方式
但是由于只有32行,所以只用到了其中的偶数行那组(ROW0, ROW2, ROW4, …… ROW60, ROW62)
因此,当你用 128*64点阵 的驱动程序进行显示的时候
实际只有偶数行的内容能够显示出来,等于图像被隔行抽走了一半
于是就出现了 16*16 的字符变成了 16*8 的样子
所以要解决这个问题,只需要对初始化程序进行很简单的一个修改就可以
首先找到初始化函数 OLED_Init 函数,
然后找到控制指令 0xDA (如果没有,就手动添加上)
指令有两行,第一行 0xDA 是列引脚配置的指令,第二行是它的参数
通过SSD13106的数据手册里的说明,参数的第4位就是奇偶行控制的选择
如果参数是 0x12(A[4]=1),就是奇偶行都控制,是给 128*64 的屏幕用的;
如果参数是 0x02(A[4]=0),就是只控制偶数行,才是给 128*32 的屏幕用的。
所以,如果有这个设置的指令,只需要按照上面截图修改这一处配置参数就可以了
如果没有这两行指令,必须手动添加上,因为如果不配置,屏幕会使用默认配置 0x12
再举个更直观的例子,如果反过来,给 128*64 的屏幕用了 128*32的驱动
所有的内容就会只是用偶数行进行显示,于是画面就会被拉长,中间还有空行
比如16*16 的字符,就会变成 16*32 的样子了
===========================================
修改完这个指令之后,还有个地方需要修改,就是对全屏进行操作的函数。
比如清屏函数 OLED_Clear() ,在128*64 的驱动程序里,清屏函数是对八个page(64行)进行操作的,也需要对应修改成四个page(32行)。
如果清屏函数用的是水平地址模式的方式,连续发送1024个0 进行清屏的,就改成 连续发送512个0
void OLED_Clear(void)
{
unsigned int i;
OLED_address( 0, 0 );
for( i=0; i<1024; i++ ) ←这里需要修改成 512
{
OLED_WR_Byte( 0x00, OLED_DATA );
}
}
如果用的是页地址模式的方式,分八次将每一个page内容清空,就改成分四次
void OLED_Clear(void)
{
unsigned char i, n;
for( i=0; i<8; i++ ) ←这里需要修改成 4
{
OLED_address( 0, i );
for( n=0; n<128; n++ )
{
OLED_WR_Byte( 0x00, OLED_DATA );
}
}
}
修改之后,可以减少单片机的的工作量,不改也没啥,按你说的“全屏写入也是写了1024个字节”,按照水平地址模式,不过只是屏幕每次会被清空两遍(page4~page7会从page0开始重新寻址),浪费算力和发数据的时间。
填充全屏的函数,比如 OLED_Fill( dat ); 亦是如此。
除此之外,如果你的驱动程序使用的是缓存方式进行显示
还需要将缓存数组大小也从1024改成512个字节
GRAM[512] 或者 GRAM[4][128]
更新显示的函数,跟清屏函数一样,刷新范围也改成四个page,否则超出屏幕的部分(从 page4 开始的内容)会从 page0 开始重新显示,将原本内容覆盖掉
===========================================
另外,初始化函数里还有一处指令 0xA8 ,是设置屏幕行数使用率的,它下面一行的参数如果是 0x3F(十进制63),就是扫描全部64行,如果只有32行的话,可以改成 0x1F (十进制31)。
这一处指令可改可不改,对视觉效果影响不大。建议修改,给SSD1306芯片减点儿工作量。
|
|