# OLED 驱动：SSD1306 与 CH1116

两套包文件名都为 OLED.c、OLED.h、OLED_STM32.c、OLED_STM32.h，函数也相同。**每个工程只能选择一套，不能同时编译两套。** 下载包已预设控制器，不需要自己切换宏。

| 下载包 | 屏幕配置 | 底层差异 |
| --- | --- | --- |
| OLED-SSD1306-v1.4.0.zip | I²C，128×64 或 128×32 | 8D 14 内部电荷泵，水平寻址，21/22 地址窗口 |
| OLED-CH1116-v1.4.0.zip | I²C，128×64 | AD 8B 内部升压，B0–B7 逐页寻址，高低列地址；默认列偏移 2 |

两套默认 hi2c1、高度 64；SSD1306 使用 0x78，CH1116 使用 0x7A（8 位写地址）；修改 OLED_STM32.h 可切换句柄与地址。SSD1306 的 32 行屏需把高度改为 32；本包 CH1116 仅支持 64 行。使用模块内部电源电路，外部高压供电面板与 SPI 模块不在本次支持范围。

## 如何选择

先看购买页面、模块说明或卖家提供的控制器型号。**不能仅凭屏幕尺寸、0x78/0x7A 地址或 I²C 应答判断芯片型号**，两者可能具有同一地址。

替换现有驱动时，用选中的包覆盖工程原有的 4 个驱动文件，清理并重新编译。别把另一个包新增到另一个工程分组，否则会产生重复定义。不要在通电状态更换接线。

## 先做一个不依赖字库的测试

将包内 QUICK_TEST.h 也复制到 BSP 文件夹，并确认 Keil 的 Include Paths 已包含 BSP。main.c 包含：

```c
#include "OLED_STM32.h"
#include "QUICK_TEST.h"

/* 放在全局 USER CODE PV 区域，方便 Keil Watch 查看 */
volatile int oled_init_status = -99;
volatile int oled_test_status = -99;
```

在 CubeMX 已生成的 MX_I2Cx_Init() 之后、USER CODE 2 中调用：

```c
oled_init_status = OLED_Begin();
if (oled_init_status == OLED_OK) {
    oled_test_status = OLED_QuickTest();
}
```

预期显示一个 8×8 的小笑脸。此测试不含中文字面量，不需要导出字库，可先排除 GBK/UTF-8、缺字等问题。两个值为 0 代表命令/数据发送成功，不等于已经验证了屏幕控制器型号或面板供电。-2 为通信失败，-99 为尚未调用。

## 显示文字和图片

两套都使用网站「一键配好并导出」的同一份字模，调用保持不变：

```c
OLED_Begin();
OLED_ShowText(0, 0, "你好"); /* 需包含匹配的 led_font.h */
OLED_ShowImage(0, 24);      /* 需包含匹配的 led_image.h */
```

初始化一次即可。每个显示函数自动刷新。文字必须已存在于导出字库，中文字符串必须为 UTF-8；Keil 保存为 GBK 时可使用 UTF-8 转义，例如“你好”：

```c
OLED_ShowText(0, 0, "\xE4\xBD\xA0" "\xE5\xA5\xBD");
```

上例为调用展示；实际代码建议像笑脸测试一样保存返回值，不要忽略错误。

## CH1116 显示位置有偏移时

CH1116 RAM 宽度为 132 列，128 像素模块可能接在不同列。OLED.h 的 OLED_COLUMN_OFFSET 默认 2，可按模块资料在 0–4 之间调整后重新编译。列偏移只影响横向位置，不能用于解决 I²C 无应答。驱动按页设置 B0–B7 和列地址，不发送 SSD1306 的水平地址窗口命令。

## 验证范围与资料

已进行两种控制器的主机模拟命令/显存测试，并在 STM32F103C8T6 的 Keil ARMCC 工程副本中编译；未进行实物屏幕验证。CH1116 模块的升压电压、预充电等模拟参数可能需要按具体面板规格调整。

SSD1306 命令参考：Solomon Systech SSD1306 数据手册（https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf）。

CH1116 命令与分页行为参考公开实现的寄存器定义：https://github.com/IvanLi-CN/ESP-IDF-CH1116-LVGL/blob/main/main/ch1116.c 。本次未能获取可用的 CH1116 原厂 PDF；没有将 SH1106 或 SSD1306 的初始化直接当作 CH1116 使用。驱动基于本项目既有代码独立实现，参考链接仅作核对记录。
