SSD1306 OLED配ESP32:I2C接线与显示实操

2026-11-05 13:19:37 10阅读

SSD1306 OLED显示屏模块实拍

给ESP32的传感器项目加一块小屏幕,是很多玩家绕不开的一步:温湿度计想直接在机器上读数,小车想显示状态码,不想天天串口监视器看着电脑跑。这时候一块SSD1306点阵OLED就是最顺手的答案,十几块钱、两条I2C线就能点亮。这份实操把接线、装库、跑通第一行字到自定义字体整条路走一遍,新手照着做大概率一次点亮。

认识SSD1306:128×64点阵,两条I2C线搞定

市面上最常见的OLED小屏就是SSD1306驱动的0.96寸和1.3寸模块,分辨率128×64,单色显示。它走I2C协议,只需要SCL、SDA两根数据线加供电,不用占一堆GPIO。模块背面通常印着I2C地址,绝大多数是0x3C,少数128×64的模块用0x3D,这个细节后面初始化代码里会用到。

ESP32这边默认的I2C引脚就是为这种外设准备的:GPIO21接SDA,GPIO22接SCL,这是芯片固件层面最合适的一对,不用自己重映射。供电直接用3.3V,现在市面上大多数模块都兼容,个别老模块标注5V的也能在3.3V逻辑下工作,实在不行走Vin引脚取5V。

接线:四根杜邦线的事

按下面这张对照表接,四根线插完就能进入软件环节:

  • VCC 接 ESP32 的 3.3V
  • GND 接 GND
  • SCL 接 GPIO 22
  • SDA 接 GPIO 21

ESP32与SSD1306 OLED的I2C接线图

接线有两个容易踩的坑。一是SCL和SDA别接反,不少模块丝印很小,插反了屏就是黑的;二是面包板上杜邦线松了会偶发花屏,看着像代码问题,其实是接触问题,先把硬件排掉再怀疑软件。

装库:两分钟搞定Adafruit全家桶

Arduino IDE的库管理器里搜"SSD1306",装"Adafruit SSD1306"这个官方库,它会提示连带安装"Adafruit GFX Library",点是。这两件套就是驱动屏幕的全部依赖,不需要再去找别的第三方包。

库管理器安装Adafruit SSD1306

库管理器安装Adafruit GFX Library

第一段代码:把Hello, world!点亮

下面这段例程来自Adafruit官方例子的精简版,整段可以照抄,只改一处都不用。代码里的尖括号头文件按平台兼容要求写成了引号形式,在Arduino工具链下两种写法对库搜索路径是等价的:

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 10);
  // Display static text
  display.println("Hello, world!");
  display.display(); 
}

void loop() {
  
}

几个初始化细节值得说透。SCREEN_WIDTH和SCREEN_HEIGHT按手里的屏写,128×64的模块就写128和64;OLED_RESET传-1表示复位脚与开发板复位共享,绝大多数四脚I2C模块都是这种接法。display.begin里那个0x3C就是I2C地址,如果你的屏是128×64但地址是0x3D,编译过了屏幕却不亮,先改这里。

烧录进去,屏幕上会先短暂出现Adafruit的启动画面,两秒后清屏,在第一行显示Hello, world!。逻辑上注意display.println只是把内容写进缓冲区,真正刷到屏幕的是display.display()这一句,忘了它就是经典的"程序跑完了屏没动静"。

ESP32驱动OLED屏点亮显示效果实拍

换字体:让小屏更像产品

GFX库自带一组FreeXxx字体,换字体只要include对应头文件再用setFont。下面这段把默认字体换成FreeSerif9pt7b,字形立刻比默认点阵字体精致不少:

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#include "Fonts/FreeSerif9pt7b.h"

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  Serial.begin(115200);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println("SSD1306 allocation failed");
    for(;;);
  }
  delay(2000);

  display.setFont(&FreeSerif9pt7b);
  display.clearDisplay();
  display.setTextSize(1);             
  display.setTextColor(WHITE);        
  display.setCursor(0,20);             
  display.println("Hello, world!");
  display.display();
  delay(2000); 
}
void loop() {
  
}

注意setFont之后想回到默认字体,调用一次display.setFont()不带参数就行。绘制函数同理:drawPixel、drawLine、drawRect、drawCircle配合fill前缀可以画填充版本,画个小车图标、进度条都够用。

排障清单:屏不亮先过这五条

报"SSD1306 allocation failed"最多,基本就是三件事:地址不对(0x3C和0x3D互换试试)、接线松了、屏幕规格和代码里写的分辨率不一致。剩下两条经验:I2C总线上同时挂多个器件时地址冲突,先用I2C扫描例程看总线上的地址列表;还有板子是ESP32-C3或S2这类引脚布局不同的型号,默认I2C引脚不一样,别照抄GPIO21/22,先查自己板子的引脚图。

这块屏跑通之后,往项目里加东西就快了:温度曲线、电池电压、Wi-Fi状态、机器人的模式指示,都是几行绘制代码的事。屏幕本身功耗低,睡眠模式下几乎不耗电,放在电池供电的小项目里也很友好。动手吧,点亮第一行字的那一刻,你的项目才算真正有了"界面"。


作者:固件烧录仔
链接:https://www.aiddithome.com/p/26ff7fcaee486.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
5条评论
板砖搬不动
1楼 · 2天前

补充一个1.3寸屏的坑:有些用的SH1106驱动,和SSD1306指令集不完全兼容,字会偏移半列,买屏前看清楚驱动型号。

只看不说话
2楼 · 2天前

尖括号改引号这个说明很贴心,烧录报错找不到头文件的人应该不少

好说好说
3楼 · 2天前

display()忘记调屏幕不动,太真实了,上周刚踩过

阿强焊点总飞
4楼 · 2天前

OLED_RESET传-1这个细节好,当年我在这卡了一下午

触底反弹的Tony
5楼 · 2天前

这套流程我上个月刚给儿子的小车项目走过一遍,卡得最久的就是0x3C这个地址,屏一直不亮还以为是模块坏了,扫了一下I2C总线才发现买的这批是0x3D。文中排障清单那段建议新手先看,能少走弯路。另外补充一句,1.3寸的模块有些用的不是SSD1306而是SH1106,驱动不通,点不亮别硬砸。