当前位置:首页 > 技术 > 正文内容

SH1106 OLED显示开发完全指南:从基础到高级应用

访客 技术 2026年5月26日 5

SH1106 OLED显示开发完全指南:从基础到高级应用

SH1106是一款广泛应用于嵌入式系统的OLED显示驱动芯片,本文将详细介绍如何使用专门为它优化的图形库来实现各种显示功能。这个库基于成熟的GFX框架,为开发者提供了一套完整的OLED解决方案。无论你是刚接触嵌入式开发还是有经验的工程师,本指南都能帮助你快速掌握SH1106显示技术。

SH1106与SSD1306的核心区别

在深入探讨显示库之前,理解这两种驱动芯片的差异至关重要。尽管SH1106和SSD1306在外观和基本功能上相似,但它们在硬件指令集上存在显著区别,特别是SH1106缺少硬件滚动功能,这需要特定的软件适配。

关键提示:专用的SH1106库是在SSD1306库基础上修改而来,主要调整了显示刷新机制以适应SH1106的特殊需求。如果你已有SSD1306使用经验,掌握SH1106将非常容易。

为什么选择专用SH1106库?

  1. 硬件适配:针对SH1106芯片特性进行深度优化
  2. API友好:继承成熟的图形库接口,学习成本低
  3. 多尺寸支持:兼容128x64、128x32和96x16等多种分辨率
  4. 双协议支持:同时支持I2C和SPI通信接口

项目环境搭建与硬件连接

库安装步骤

首先获取显示库文件。在终端中执行以下命令:

git clone https://github.com/adafruit/Adafruit_SH1106

然后,将下载的库文件添加到你的开发环境中。

硬件连接方案

I2C连接方式(推荐初学者使用):

  • SDA线连接到主控板的SDA引脚
  • SCL线连接到主控板的SCL引脚
  • RESET引脚连接到任意数字I/O(通常使用D4)
  • VCC和GND分别接3.3V电源和地线

SPI连接方式(需要更高性能时):

  • MOSI、SCLK、DC、CS、RESET分别对应连接
  • 占用更多引脚但传输速率更快

基础初始化代码

以下是一个使用I2C接口的基本示例:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>

#define SCREEN_RESET 4
Adafruit_SH1106 oled(SCREEN_RESET);

void setup() {
  Serial.begin(9600);
  
  // 初始化OLED模块
  oled.begin(SH1106_SWITCHCAPVCC, 0x3C);
  
  // 显示欢迎界面
  oled.display();
  delay(2000);
  
  // 清除屏幕
  oled.clearDisplay();
  
  // 输出欢迎文字
  oled.setTextSize(1);
  oled.setTextColor(WHITE);
  oled.setCursor(0,0);
  oled.println("欢迎使用OLED!");
  oled.display();
}

void loop() {
  // 主循环代码
}

注意:I2C地址可能因模块而异!128x64显示屏通常使用0x3D,128x32显示屏使用0x3C。如果屏幕无显示,首先检查I2C地址设置。

图形显示核心技术

基本图形绘制

SH1106库继承了完整的图形绘制功能。以下是绘制基本图形的示例:

// 绘制单个像素点
oled.drawPixel(15, 15, WHITE);

// 绘制直线
oled.drawLine(0, 0, 127, 63, WHITE);

// 绘制空心矩形
oled.drawRect(10, 10, 50, 30, WHITE);

// 绘制填充矩形
oled.fillRect(20, 20, 40, 20, WHITE);

// 绘制圆形
oled.drawCircle(64, 32, 20, WHITE);

// 绘制填充圆形
oled.fillCircle(64, 32, 15, WHITE);

// 刷新显示
oled.display();

文本显示技巧

文本显示是OLED屏幕最常见的应用之一:

// 设置文本大小(1-8倍)
oled.setTextSize(1);  // 正常尺寸
oled.setTextSize(2);  // 双倍尺寸

// 设置文本颜色
oled.setTextColor(WHITE);        // 白色文字
oled.setTextColor(BLACK, WHITE); // 黑色文字,白色背景

// 设置光标位置
oled.setCursor(0, 0);   // 左上角
oled.setCursor(10, 20); // 指定坐标

// 输出文本内容
oled.println("温度: 26.3°C");
oled.print("湿度: ");
oled.print(68.7);
oled.println("%");

位图显示方法

虽然SH1106是单色显示屏,但仍可以显示自定义位图:

// 定义位图数据(16x16像素)
static const unsigned char PROGMEM logo_bmp[] = {
  B00000000, B11000000,
  B00000001, B11000000,
  // ... 更多位图数据
  B00000000, B00110000
};

// 显示位图
oled.drawBitmap(30, 16, logo_bmp, 16, 16, WHITE);
oled.display();

显示控制功能

// 反转显示(黑白互换)
oled.invertDisplay(true);
delay(1000);
oled.invertDisplay(false);

// 调整对比度(0-255)
oled.dim(100);  // 降低对比度
oled.dim(255);  // 最大对比度

// 清除屏幕
oled.clearDisplay();

常见问题与解决方案

问题1:误认为SH1106与SSD1306完全兼容

事实:虽然两者功能相似,但SH1106缺少硬件滚动支持。专用库中已移除相关滚动功能代码。

问题2:频繁刷新显示

优化建议:完成所有绘图操作后,再调用一次display()函数,减少通信开销。

问题3:内存使用超限

解决方案:对于复杂图形,采用分块绘制技术,先绘制一部分并显示,再绘制下一部分。

性能优化策略

  1. 批量绘制:集中所有绘图操作后统一刷新
  2. 避免延时:使用非阻塞定时器替代delay()
  3. 缓冲区复用:对重复图形进行缓存处理

实际应用案例

案例1:环境监测数据显示

void updateEnvironmentDisplay(float temp, float hum, float pressure) {
  oled.clearDisplay();
  
  oled.setTextSize(1);
  oled.setTextColor(WHITE);
  
  oled.setCursor(0, 0);
  oled.print("温度: ");
  oled.print(temp);
  oled.println("°C");
  
  oled.setCursor(0, 10);
  oled.print("湿度: ");
  oled.print(hum);
  oled.println("%");
  
  oled.setCursor(0, 20);
  oled.print("气压: ");
  oled.print(pressure);
  oled.println("hPa");
  
  // 添加温度指示条
  oled.drawRect(0, 35, 128, 10, WHITE);
  int barWidth = map((int)temp, 0, 50, 0, 128);
  oled.fillRect(0, 35, barWidth, 10, WHITE);
  
  oled.display();
}

案例2:交互式菜单系统

String menuOptions[] = {"配置", "记录", "信息", "退出"};
int currentOption = 0;

void drawMenu() {
  oled.clearDisplay();
  
  for(int i = 0; i < 4; i++) {
    oled.setCursor(10, i * 15);
    
    if(i == currentOption) {
      oled.setTextColor(BLACK, WHITE);
      oled.print("> ");
    } else {
      oled.setTextColor(WHITE);
      oled.print("  ");
    }
    
    oled.println(menuOptions[i]);
  }
  
  oled.display();
}

案例3:实时数据图表

int sensorValues[128];
int dataCounter = 0;

void addSensorValue(int value) {
  sensorValues[dataCounter] = value;
  dataCounter = (dataCounter + 1) % 128;
}

void drawDataChart() {
  oled.clearDisplay();
  
  // 绘制坐标轴
  oled.drawLine(0, 63, 127, 63, WHITE); // X轴
  oled.drawLine(0, 0, 0, 63, WHITE);    // Y轴
  
  // 绘制数据曲线
  for(int i = 0; i < 127; i++) {
    int y1 = map(sensorValues[i], 0, 100, 63, 0);
    int y2 = map(sensorValues[i+1], 0, 100, 63, 0);
    oled.drawLine(i, y1, i+1, y2, WHITE);
  }
  
  oled.display();
}

高级故障排除

问题1:屏幕闪烁

解决方案:减少display()调用频率,或实现双缓冲技术。

问题2:显示内容不清晰

解决方案:使用dim()函数调整对比度,找到最佳显示效果。

问题3:I2C通信失败

解决方案

  1. 检查接线连接
  2. 确认I2C地址(0x3C或0x3D)
  3. 使用扫描代码验证设备地址
#include <Wire.h>

void scanI2CDevices() {
  Serial.begin(9600);
  Wire.begin();
  
  Serial.println("扫描I2C设备中...");
  for(uint8_t address = 1; address < 127; address++) {
    Wire.beginTransmission(address);
    if(Wire.endTransmission() == 0) {
      Serial.print("发现设备地址: 0x");
      Serial.println(address, HEX);
    }
  }
}

结语:SH1106显示库的优势

SH1106专用库为OLED显示提供了功能强大且易于使用的解决方案。无论你需要显示简单数据还是构建复杂界面,这个库都能满足需求。

核心优势

  • 专为SH1106优化,解决与SSD1306的兼容问题
  • 基于成熟的GFX框架,API丰富且易于学习
  • 同时支持I2C和SPI通信方式
  • 代码精简,适合资源有限的嵌入式系统
  • 活跃的社区支持和丰富的示例代码

开始你的SH1106开发之旅

  1. 获取库文件
  2. 参考示例代码:examples/sh1106_128x64_i2c/sh1106_128x64_i2c.ino
  3. 研究核心实现:Adafruit_SH1106.cpp
  4. 从简单项目开始实践

最好的学习方式就是动手实践。从基础示例开始,逐步探索更复杂的功能。SH1106库的强大功能等待你去发掘!

最后建议:遇到问题时,首先检查库配置文件,特别是确保选择了正确的显示屏分辨率定义。祝你的SH1106项目开发顺利!

标签: 嵌入式开发

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。