自定义SH1106 132x64显示库中page 0位置异常问题排查
SH1106 132x64显示屏自定义库Page地址颠倒问题排查
我正在为SH1106 132x64显示屏编写自定义库。根据SH1106数据手册,默认配置下page 0应该位于屏幕顶部,但手册并未明确书面说明,仅第16页(图8)的表格有相关暗示。
我测试了多款显示屏,它们的page 0均位于底部。我尝试了各种寻址模式的组合,但都未能解决该问题。
随后我使用Adafruit SSD1306库进行显示测试,此时page 0位于顶部。
这到底是哪里出了问题?
头文件
#define SH1106_WIDTH 132 #define SH1106_HEIGHT 64 #define SH1106_COMMAND 0x00 #define SH1106_DATA 0x40 #define DISPLAY_OFF 0xAE #define DISPLAY_ON_NORMAL_MODE 0xAF #define DISPLAY_ON_RAM_CONTENT 0xA4 #define DISPLAY_ON_RAM_IGNORE 0xA5 #define SET_DISPLAY_NORMAL 0xA6 #define SET_DISPLAY_INVERSE 0xA7 #define SET_CONTRAST_CONTROL 0x81 #define SET_MEMORY_ADDRESSING_MODE 0x20 #define SET_DISPLAY_START_LINE 0x40 // Allowed Values: 0x40 to 0x7F, Reset Value: 0x40 / x100 0000 #define SET_PAGE_ADDRESS_FOR_PAGE_ADDRESSING_MODE 0xB0 #define SET_COM_OUTPUT_SCAN_DIRECTION_NORMAL_MODE 0xC0 #define SET_COM_OUTPUT_SCAN_DIRECTION_REMAPPED_MODE 0xC8 #define SET_SEGMENT_REMAP_SEG0_0 0xA0 #define SET_SEGMENT_REMAP_SEG0_131 0xA1 #define SET_MULTIPLEX_RATIO 0xA8 #define SET_DISPLAY_OFFSET 0xD3 #define SET_DISPLAY_CLOCK_DIVIDE_RATIO 0xD5 #define SET_PRECHARGE_PERIOD 0xD9 #define SET_COM_PINS_HARDWARE_CONFIGURATION 0xDA #define SET_VCOMH_DESELECT_LEVEL 0xDB #define CHARGE_PUMP_SETTING 0x8D #define DEACTIVATE_SCROLL 0x2E
C文件
uint8_t dynamicInitDataArray[] = { SH1106_COMMAND, DISPLAY_OFF, SH1106_COMMAND, SET_MULTIPLEX_RATIO, 0x3F, // Reset Value: 0x3F / xx11 1111 SH1106_COMMAND, SET_DISPLAY_OFFSET, 0x00, // No Offset SH1106_COMMAND, SET_DISPLAY_START_LINE, SH1106_COMMAND, SET_SEGMENT_REMAP_SEG0_131, SH1106_COMMAND, SET_COM_OUTPUT_SCAN_DIRECTION_NORMAL_MODE, SH1106_COMMAND, SET_COM_PINS_HARDWARE_CONFIGURATION, 0x12, // 0x02 or 0x12 (POR) SH1106_COMMAND, SET_CONTRAST_CONTROL, 0x7F, SH1106_COMMAND, SET_DISPLAY_CLOCK_DIVIDE_RATIO, 0xA0, // Suggested Ratio: 0x80 SH1106_COMMAND, CHARGE_PUMP_SETTING, 0x14, // Enable: 0x14, Disable: 0x10 SH1106_COMMAND, SET_MEMORY_ADDRESSING_MODE, 0x02, // Horizontal: 0x00, Vertical: 0x01, Page: 0x02 SH1106_COMMAND, SET_PRECHARGE_PERIOD, 0x22, SH1106_COMMAND, SET_VCOMH_DESELECT_LEVEL, 0x20, SH1106_COMMAND, SET_DISPLAY_NORMAL, SH1106_COMMAND, DISPLAY_ON_RAM_CONTENT, SH1106_COMMAND, DEACTIVATE_SCROLL }; /** * @brief This function initializes the display. * @param *hi2c: i2c-handle pointer * @param deviceAddress: i2c device address */ void SH1106_Init(I2C_HandleTypeDef *hi2c, uint8_t deviceAddress) { size_t totalBytesToTransmit = sizeof(dynamicInitDataArray) / sizeof(dynamicInitDataArray[0]); HAL_I2C_Master_Transmit(hi2c, deviceAddress, dynamicInitDataArray, totalBytesToTransmit, 1000); } /** * @brief This function sets the page. * @param *hi2c: i2c-handle pointer * @param deviceAddress: i2c device address * @param page: page number from 0-7 */ void SH1106_Set_Page_Address(I2C_HandleTypeDef *hi2c, uint8_t deviceAddress, uint8_t page) { if(page > 7) { return; // Check if page is in bounds. } uint8_t setPageAddress[2] = {SH1106_COMMAND, SET_PAGE_ADDRESS_FOR_PAGE_ADDRESSING_MODE + page}; HAL_I2C_Master_Transmit(hi2c, deviceAddress, setPageAddress, 2, 1000); }
问题原因与修复方案
问题出在COM输出扫描方向的配置上:
你当前初始化代码中使用SET_COM_OUTPUT_SCAN_DIRECTION_NORMAL_MODE(0xC0),该模式下COM引脚扫描顺序为从COM0到COM63,对应屏幕的底部到顶部——page 0对应的RAM区域会被映射到屏幕底部,和你预期的顶部位置相反。
而Adafruit SSD1306库默认配置了反转的COM扫描方向(SET_COM_OUTPUT_SCAN_DIRECTION_REMAPPED_MODE,即0xC8),此时COM扫描顺序变为从COM63到COM0,page 0就会对应屏幕顶部,和手册暗示的默认行为一致。
具体修复步骤
修改初始化数组中的COM扫描方向配置:
将:
SH1106_COMMAND, SET_COM_OUTPUT_SCAN_DIRECTION_NORMAL_MODE,
替换为:
SH1106_COMMAND, SET_COM_OUTPUT_SCAN_DIRECTION_REMAPPED_MODE,
另外需要注意,部分132x64的SH1106模组可能需要调整SET_COM_PINS_HARDWARE_CONFIGURATION的参数为0x22而非0x12,若修改COM扫描方向后仍有显示异常,可以尝试调整这个参数,但这不是page位置颠倒的直接原因。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

