搭载SH1106驱动的OLED在Nucleo F401RE上出现水平偏移的原因
SH1106 OLED水平偏移-2的原因及解决方法
问题原因
SH1106驱动IC的内部RAM包含132列(地址0~131),但市面上多数128x64的OLED模块仅使用其中128列。这类模块在硬件设计上通常将屏幕的第0列对应到SH1106 RAM的第2列,导致输入的列地址与实际显示位置存在-2的偏移。
此外,你的初始化代码中缺少了设置列地址范围的关键命令(0x21),SH1106默认会使用全部132列RAM,进一步放大了这种硬件偏移带来的显示错位。
解决方法
1. 修改初始化代码,添加列地址范围配置
在sh1106_init()函数中,添加0x21命令限定SH1106的RAM列范围为屏幕实际使用的128列(对应RAM的2~129列),这样输入的列地址0就会直接映射到屏幕的0列:
void sh1106_init(void) { // Initialize the display sh1106_sendCMD(0xAE); // Set display off sh1106_sendCMD(0xD5); // Set display clock divide ratio/oscillator frequency sh1106_sendCMD(0x80); // Set display clock divide ratio/oscillator frequency sh1106_sendCMD(0xA8); // Set multiplex ratio sh1106_sendCMD(0x3F); // 1/64 duty sh1106_sendCMD(0xD3); // Set display offset sh1106_sendCMD(0x00); // No offset sh1106_sendCMD(0x40); // Set start line address sh1106_sendCMD(0xA1); // Set segment re-map sh1106_sendCMD(0xC8); // Set COM output scan direction sh1106_sendCMD(0xDA); // Set COM pins hardware configuration sh1106_sendCMD(0x12); sh1106_sendCMD(0x81); // Set contrast control register sh1106_sendCMD(0xFF); // Maximum contrast sh1106_sendCMD(0xA4); // Set display to RAM sh1106_sendCMD(0xA6); // Set normal display sh1106_sendCMD(0xD9); // Set pre-charge period sh1106_sendCMD(0xF1); sh1106_sendCMD(0xDB); // Set VCOMH deselect level sh1106_sendCMD(0x40); sh1106_sendCMD(0x8D); // Set charge pump enable/disable sh1106_sendCMD(0x14); // Enable charge pump // 新增:配置列地址范围,适配128列屏幕 sh1106_sendCMD(0x21); // 启用列地址范围设置模式 sh1106_sendCMD(0x02); // RAM起始列设为2(对应屏幕第0列) sh1106_sendCMD(0x81); // RAM结束列设为129(对应屏幕第127列) sh1106_sendCMD(0xAF); // Set display on }
2. 修正像素设置的列地址计算逻辑
确保列地址的高低4位设置正确,对应输入的x坐标(0~127):
// 示例:设置(x=0, y=0)像素 sh1106_sendCMD(0xB0 | 0); // 设置页地址(y=0对应第0页) sh1106_sendCMD(0x00 | (0 & 0x0F)); // 设置列地址低4位 sh1106_sendCMD(0x10 | ((0 >> 4) & 0x0F)); // 设置列地址高4位 sh1106_sendData(0x01); // 点亮该页的第0位(对应y=0行)
通过以上修改,输入的坐标将与屏幕显示位置完全对应,水平偏移问题即可解决。
内容的提问来源于stack exchange,提问作者licerer
相关产品推荐
相关产品推荐

