点阵工坊 · OLED 使用手册下载 Markdown

OLED 使用说明

更换文字、字体、尺寸或图片,只需更新 OLED_Content.h。 驱动、OLED_User.h、main.c 和 Keil 工程配置都不需要跟着修改。

1. 第一次安装:只做一次

网页准备好初始内容,展开「首次安装」,选择 SSD1306 或 CH1116。默认配置 I²C1、128×64;SSD1306 使用 0x78,CH1116 使用 0x7A(均为 8 位写地址);不同时再展开连接设置修改。点击 「下载首次安装包」。

先选屏幕、调整显示位置

在「点阵预览」选择屏幕:0.96 寸或 1.3 寸为 128×64,0.91 寸为 128×32。这里列的是常见规格,请以模块实际分辨率为准,控制器另行选择。CH1116 当前驱动只支持 128×64。

在预览旁输入 X、Y,或拖动坐标条,文字和图片会立即移动。左上角是 (0, 0),X 向右、Y 向下;「回到左上角」可复位。文字会从所设 X 位置换行,超出屏幕的部分裁切。下载 OLED_Content.h 后覆盖 BSP 中的同名文件,再编译烧录,位置会随内容一起更新。首次安装包也会包含当前坐标。

第一次安装时,屏幕分辨率会同步写入驱动配置。如果已安装后更换了不同分辨率的硬件,还需在 BSP/OLED_STM32.h 中把 OLED_SCREEN_HEIGHT 改为 32 或 64,与预览一致。只移动位置不需要修改驱动。

第一步:在资源管理器中新建 BSP 文件夹

先在 Keil 外,用 Windows 资源管理器打开工程所在目录,新建文件夹,命名为 BSP。以 OLED 工程为例,BSP 与 Core、Drivers、MDK-ARM 同级:

OLED/
├─ BSP/
│  ├─ OLED.c
│  ├─ OLED.h
│  ├─ OLED_STM32.c
│  ├─ OLED_STM32.h
│  ├─ OLED_User.h
│  └─ OLED_Content.h
├─ Core/
├─ Drivers/
└─ MDK-ARM/
   └─ OLED.uvprojx

解压首次安装包,将包内 BSP 文件夹中的 全部 .c 和 .h 文件复制到你创建的 BSP 文件夹。两个 .c 是驱动实现,四个 .h 是接口、配置和显示内容。只使用与你屏幕对应的一套驱动。

第二步:在 Keil 中新建 BSP 组,添加 .c 文件

Keil 的 BSP 组是工程中的文件分组,资源管理器里的 BSP 是实际存放文件的文件夹,两处都要创建。组里只添加 .c 文件;.h 文件通过下一步的包含路径使用。 同一个 .c 文件只添加一次。

第三步:设置 BSP 头文件包含路径

按上面的目录结构,.uvprojx 位于 MDK-ARM 内,所以包含路径通常显示为 ..\BSP。目录不同就通过浏览选择实际 BSP 文件夹,不要照抄路径。选择文件夹即可,不要选择某个 .h 文件;保留 CubeMX 已有的其他包含路径。

第四步:添加启动调用,编译烧录

main.c 的 USER CODE Includes 区域加:

#include "OLED_User.h"

在 CubeMX 的 MX_I2Cx_Init() 之后、USER CODE 2 区域加:

OLED_Start();

编译、烧录即可。保留 CubeMX 自动生成的时钟、GPIO 和 I²C 初始化。OLED_Start 已包含初始化与显示,不要在 while(1) 中反复调用。

2. 已经安装:以后只做这三步

完成。不用再下载驱动,不用再次添加 .c 文件,不用修改 OLED_Start()。文字切换为图片、图片切回文字,也都只换同一个 OLED_Content.h。更新内容不需要重新选择控制器,同一份内容可供 SSD1306 和 CH1116 两种驱动使用。

浏览器如果把文件保存为 OLED_Content (1).h,请恢复成 OLED_Content.h 后再覆盖。不要把新文件加到另一个头文件目录,避免工程仍使用旧文件。

内容编译进单片机固件,所以替换头文件后仍需重新编译和烧录;这不是重新移植驱动。一次更新包含当前预览中的全部文字和图片,从所设坐标显示,超出屏幕的部分会裁切。

文字、图片:看着预览调整即可

输入文字后会自动生成,不用再点生成按钮。导入图片后,图片与文字一起显示;切换「文字」「图片」只是在选择要编辑哪一项,X、Y 和尺寸分别保存。重叠时文字覆盖图片。

只想显示图片:点击「清空文字」。只想显示文字:点击「移除图片」。当前支持一张图片与一段可换行文字;图片可以事先拼成多个图标。图片与像素编辑不跨网页刷新保存,刷新后请重新导入图片。

所有内容文件都自动包含常用数字、英文字母、标点和空格。显示 25.6 变成 26.1 不需要重新取模。汉字按需生成:例如要显示「温度」「湿度」,输入包含「温湿度」的文字即可。选择 16×16 时,汉字是 16×16,数字和字母自动是 8×16,数值与汉字垂直居中对齐。行间距可在网页直接调节,0 表示不额外留空,数值越小越紧凑。

每行字号与行间距

在文字框按回车换行,下方会自动出现「第 1 行」「第 2 行」等字号设置。每行分别填写字号,例如第 1 行 20、第 2 行 12;字号单位是像素,汉字使用该尺寸,数字和字母自动使用较窄宽度。相同汉字在不同行也可以使用不同字号。

「行间距」是两行字框之间额外留出的像素数,可设为 0~32;建议从 0、1、2 试起,预览会立即变化。第二行起点 = 第一行起点 + 第一行字号高度 + 行间距。设置适用于所有换行,包含自动折行。

字号按输入框中回车分隔的行号保存;自动折行沿用当前行字号,空行也占用该行高度及间距。新增行使用下方统一尺寸;点击下方尺寸按钮或修改统一宽高,会将所有行统一设置。字号和间距在本机浏览器保存,刷新后保留。

改好后仍只下载 OLED_Content.h,覆盖 BSP 中同名文件并编译烧录。OLED_UpdateText 和温湿度显示函数会自动使用这些行设置,无需修改调用代码。实时文本超过已设置的行数时,额外行沿用最后一行字号。每次单独调用 OLED_DrawText 都从第 1 行的字号开始。

每行单独设置 X、Y

「每行字号与位置」中,每一行都有字号、X、Y。X 向右增大,Y 向下增大,左上角为 (0,0)。例如第 1 行 X=0、Y=0,第 2 行 X=40、Y=30,两行就分别从这两个位置开始显示。

坐标留空表示自动:X 跟随预览区的文字起点,Y 按上一行的实际结束位置、字号和行间距向下排列。只填写 X 或只填写 Y 也可以;已填写的坐标按屏幕绝对位置固定,调整整体文字起点或行间距不会改变该轴。自动折行仍从该行自己的 X 开始,沿用该行字号和行间距。

「恢复自动排列」清除所有行的独立坐标,字号保留。换成 128×32 屏幕时,已填写的 Y 超过 31 会自动收回到 31,仍需检查文字是否裁切。重叠时后面的文字覆盖前面的文字;建议在预览中错开。坐标跟随行号保存,新增或删除行后检查排版。

改好后重新下载 OLED_Content.h,覆盖 BSP 中同名文件并编译烧录即可。OLED_Start、OLED_SetNumber 和 OLED_Refresh 的调用都不变。OLED_ShowText / OLED_DrawText 手动指定起点时,已配置坐标相对网页原文字起点一起偏移;普通网页模板更新使用网页中的坐标。

固定文字与实时数值分开维护

固定的标题、姓名、说明只在网页输入。数值变化的位置点击「插入温度数值」「插入湿度数值」或「插入其他数值」,按钮会在光标处插入一个变量标记。例如:

智能环境监测终端
姓名:张三 学号:12345678
温度阈值:30C
温度:{{temperature}} 湿度:{{humidity}}%

双大括号中的英文是变量名,不会显示到屏幕。可以通过按钮插入,不用手写。预览区显示示例数值,可修改预览值检查长数字能否放下;真正的启动画面先显示 --,等待传感器数据,避免把示例数值当成真实测量。

调整各行字号与行间距后,下载 OLED_Content.h 并替换 BSP 内同名文件。网页「复制到传感器读取成功后的代码」会按变量名生成调用,复制到 while 循环中传感器读取成功的位置,例如:

OLED_SetNumber("temperature", temperature, 1);
OLED_SetNumber("humidity", humidity, 1);
OLED_Refresh();

引号内的英文对应网页变量名;第二个参数换成你的实际变量,最后的 1 表示保留一位小数,可填 0~3。SetNumber 只保存数值,最后 Refresh 一起刷新。中文、标题、图片、各行字号和位置会自动保留,无需自己拼接 snprintf,无需在 Keil 输入中文或开启浮点 printf。

OLED_Start() 仍在 I²C 初始化之后、while 循环之前调用一次。以后新增或修改固定文字,只改网页并替换 OLED_Content.h,再编译烧录;代码中的数值更新调用不变。新增实时变量时才需要增加一行 SetNumber;删除或改名实时变量时,同步删除或修改相应赋值调用。不要在刷新模板之后再调用 OLED_UpdateText(text),否则会用整段字符串覆盖画面。

温湿度:也可以只调用一行

点击「温湿度示例」会自动插入 temperature 和 humidity 两个变量。你可以在它们前后添加标题、姓名等任意固定文字,再调整排版。每次读取成功后,只调用:

OLED_ShowTemperatureHumidity(temperature, humidity);

它会给网页中的 temperature、humidity 赋值并刷新整幅画面,固定文字与图片保留。它与上面的两次 SetNumber 加一次 Refresh 二选一即可,不要重复调用。

这个便捷函数接收摄氏温度 -40~85、相对湿度 0~100,显示一位小数;超出范围返回 -1 并保留画面。显示其他量或其他范围时,用通用的 OLED_SetNumber。温湿度示例会重置为两行 16 像素字号;64 高屏幕示例间距为 2,32 高屏幕为 0。

更多数据:电压、光照、阈值也一样

例如网页输入「电压:{{voltage}}V」,程序调用:

OLED_SetNumber("voltage", voltage, 2);
OLED_Refresh();

需要更新英文状态文字时可调用 OLED_SetTextValue("status", "OK"),并在网页放入 {{status}},最后调用 OLED_Refresh()。网页预览值仅用于检查排版;更长数值可能折行或裁切,请按最大可能长度检查预览。

变量名使用英文字母或下划线开头,其后可用字母、数字、下划线,最长 24 字符;最多 16 个不同变量。同名变量可放在多个位置,一次赋值一起更新。数值范围为 -1000000~1000000,小数位 0~3。文本值最多 47 个 UTF-8 字节,不允许换行;中文文本值仍需预先取模。整屏拼接内容最多 1023 个 UTF-8 字节。参数、名称或长度错误返回 -1;刷新 I²C 错误返回 -2。未赋值变量保持 --。

完全自定义整段文字(按需使用)

OLED_UpdateText(text) 仍可使用,但会直接替换整段文字,包含所有固定行。通常使用网页变量配合 SetNumber / Refresh 更省事。自己在代码字符串里写中文时仍要保持 UTF-8;使用网页变量则不用在 Keil 写中文。

3. 接线与黑屏排查

STM32F103C8T6 未重映射的 I²C1:SCL→PB6、SDA→PB7,句柄 hi2c1。I²C2:SCL→PB10、SDA→PB11,句柄 hi2c2。必须与 CubeMX、实际接线和驱动配置一致。模块有 RESET 引脚时,按模块要求先复位。

SSD1306 支持 128×64 / 128×32;CH1116 支持 128×64,默认列偏移 2。控制器和地址根据模块资料选择,不能只看尺寸判断。更换硬件控制器或 I²C 接线时,才需要更换驱动或配置。

黑屏时在 Keil Watch 查看 OLED_InitResult 和 OLED_ShowResult:0 为调用成功,-1 为参数错误,-2 为 I²C 发送失败,-3 为未初始化,-99 为尚未执行。网页生成的内容已处理中文编码,无需手写 UTF-8 转义。

两个状态都为 0 仍黑屏时,要继续核对控制器型号、模块供电和复位。两套驱动均通过模拟测试与 Keil 编译,尚未在你的实物屏幕上验证。

4. 按需查看:手动组合多行内容

日常使用优先网页变量配合 OLED_SetNumber / OLED_Refresh,或 OLED_ShowTemperatureHumidity。如果需要在不同位置显示多段文字,可以主动绘制一帧:

OLED_NewFrame();                 // 清空内存画布
OLED_DrawImage(0, 0);            // 绘制网页导入的图片;没有图片就删除这行
OLED_DrawText(56, 0, "T:25.6C");
OLED_DrawText(56, 20, "H:68.2%");
OLED_ShowFrame();                // 最后一起刷新到屏幕

Draw 函数只修改内存,ShowFrame 才发送到屏幕。这样可以自由排版,也可以重复绘制同一张图片。文字每个字符的背景会覆盖该字符矩形内的图片;超出屏幕部分裁切。坐标必须是屏幕内的非负坐标。

函数用途
OLED_Start()初始化并显示网页排版,只调用一次
OLED_SetNumber(name, value, decimals)保存一个命名数值,稍后刷新
OLED_Refresh()显示网页固定文字与最新变量值
OLED_UpdateText(text)按网页文字坐标更新文字,保留图片
OLED_ShowTemperatureHumidity(t, h)一行显示实时温湿度,保留图片
OLED_ShowText(x, y, text)临时指定文字坐标并重新显示整幅画面
OLED_ShowImage(x, y)临时指定图片坐标,与网页初始文字一起显示
OLED_NewFrame()清空内容文件的内存画布
OLED_DrawText(x, y, text)向当前内存画布绘制文字
OLED_DrawImage(x, y)向当前内存画布绘制导入的图片
OLED_ShowFrame()发送整幅画布

简单 Show/Update 调用会重建画面,适用于一段动态文字。需要多段动态文字时,使用 NewFrame → 多次 Draw → ShowFrame。不要在这些 Draw 调用中间插入 ShowText 或 UpdateText,以免重建画面。

以上内容辅助函数随 OLED_Content.h 提供。在 main.c 中包含 OLED_User.h 即可使用。即使只导出图片,文字函数和常用 ASCII 字库也可用;没有导入图片时,图片函数返回 -1。未知汉字、无效参数返回 -1;I²C 错误返回 -2;未初始化返回 -3。绘制函数遇到未知字符不会提交部分文字;请检查返回值。

5. 进阶接口和资源说明

OLED.c / OLED.h 是底层驱动,OLED_STM32.c / OLED_STM32.h 是 STM32 HAL 适配。接口名都以 OLED 命名。SSD1306 与 CH1116 选择其一,不能同时编译两套。保留 CubeMX 的初始化代码,包含路径按前面的 BSP 流程设置。

网页显示 8 位 I²C 写地址:SSD1306 为 0x78,CH1116 为 0x7A。导出的 OLED_STM32.h 内使用对应的 7 位值 0x3C / 0x3D,HAL 适配层自动移位一次;无需手改地址。

内容采用列行式、阳码、低位在前,网页自动配置。驱动本身有 1024 字节帧缓冲;内容文件另用 512 或 1024 字节内存画布(对应 128×32 / 64)。字模数组是 const,通常存放在 Flash。默认 16 像素高时,95 个常用字符的像素数据约 1520 字节,每个 16×16 汉字另用 32 字节;索引还会占少量 Flash。

内容头文件建议只在 main.c 使用,避免多个 C 文件重复包含导致资源重复占用。高级底层接口的参数与声明见 OLED.h 和 OLED_STM32.h。此网页支持 I²C 版本,不提供 Arduino 或 SPI 接入。

字体由本机系统渲染,不同电脑的字形可能略有不同;图片在本地处理。网页预览不会自动发送到开发板,更新头文件后仍需编译、烧录。

模板功能另使用 1024 字节整屏文本缓冲和每个变量 48 字节存储;默认启动值为 --。