/********************************************************************** * Copyright: (C)2021 LingYun IoT System Studio * Author: GuoWenxue QQ: 281143292 * Description: ISKBoard OLED(N091-2832TSWFG02-H14, 128x32) SSD1306 driver * * ChangeLog: * Version Date Author Description * V1.0.0 2021.08.10 GuoWenxue Release initial version * V2.0.0 2026.04.29 Optimized GRAM buffered rendering ***********************************************************************/ /* SSD1306 OLED显示器内部按页(Page)组织数据: 屏幕布局(128x32): +------------------+ | Page 0 (0~7) | ← 8像素 +------------------+ | Page 1 (8~15) | ← 8像素 +------------------+ | Page 2 (16~23) | ← 8像素 +------------------+ | Page 3 (24~31) | ← 8像素 +------------------+ 字体大小说明: +---------------+---------+-------+----------+-------------+ | FONT | 宽度 | 高度 | 占用页数 | Y坐标类型 | +---------------+---------+-------+----------+-------------+ | FONT8(6x8) | 6像素 | 8像素 | 1页 | 页码(0~3) | +---------------+---------+-------+----------+-------------+ | FONT16(8x16) | 8像素 | 16像素| 2页 | 页码(0~2) | +---------------+---------+-------+----------+-------------+ | Chinese(16x16)| 16像素 | 16像素| 2页 | 页码(0~2) | +---------------+---------+-------+----------+-------------+ */ #ifndef __OLED_DRV_H #define __OLED_DRV_H #include "stm32l4xx_hal.h" #include "i2c_bitbang.h" /* OLED I2C 从设备地址 */ #define OLED_I2C_ADDR 0x3C /* 屏幕物理尺寸 */ #define X_WIDTH 128 #define Y_WIDTH 32 /* 字体大小选项 */ #define OLED_FONT16 16 /* 8×16 像素字体 */ #define OLED_FONT8 8 /* 6×8 像素字体 */ /* SSD1306 页数(128×32 屏共 4 页,每页 8 行像素) */ enum { OLED_PAGE0, /* 第0个页,控制纵坐标从 0 开始 */ OLED_PAGE1, /* 第1个页,控制纵坐标从 8 开始 */ OLED_PAGE2, /* 第2个页,控制纵坐标从 16 开始 */ OLED_PAGE3, /* 第3个页,控制纵坐标从 24 开始 */ OLED_PAGES, /* 总共 4 个页 */ }; /* 根据 SSD1306 芯片 datasheet 说明定义控制流标记 */ typedef enum { OLED_CMD = 0x00, /* Co=0, D/C#=0 -> 后面跟着命令 */ OLED_DATA = 0x40, /* Co=0, D/C#=1 -> 后面跟着全数据流 */ } oled_ctrl_t; /* * ========================================================================= * 显示控制 API * ========================================================================= */ /** * @brief 初始化 OLED 显示屏(包含寄存器流配置、本地 GRAM 格式化、以及首次总线强刷) * @param bus: 绑定的 i2c-bitbang 物理总线句柄 */ int OLED_Init(i2c_bus_t *bus); /** * @brief 清空软件 GRAM 缓冲区(全黑), 需配合 OLED_Refresh() 使用。 */ void OLED_Clear(void); /** * @brief 点亮软件 GRAM 缓冲区中所有像素(全白), 需配合 OLED_Refresh() 使用。 */ void OLED_On(void); /** * @brief 开启 OLED 显示(打开内建 Charge Pump 倍压器 + 开启显示面板) */ void OLED_Display_On(void); /** * @brief 关闭 OLED 显示(进入超低功耗硬件待机模式,显存内容保持不动) */ void OLED_Display_Off(void); /** * @brief 将软件 GRAM 缓冲区一次性突发刷新到 OLED 硬件显存中 * 每页采用单次加锁机制,极大幅度压缩总线事务开销,给其他设备留足带宽。 */ void OLED_Refresh(void); /* * ========================================================================= * 绘制 API(写缓冲区,需配合 OLED_Refresh() 显示) * ========================================================================= */ /** * @brief 在本地 GRAM 缓冲区中写入单个可打印 ASCII 字符 * * @param x 列坐标 (0 ~ X_WIDTH-1) * @param page 页坐标 (0 ~ OLED_PAGES-1) * @param chr ASCII 可打印字符 * @param char_size OLED_FONT16 (占 2 页) 或 OLED_FONT8 (占 1 页) */ void OLED_ShowChar(uint8_t x, uint8_t page, char chr, uint8_t char_size); /** * @brief 在本地 GRAM 缓冲区中写入 ASCII 字符串(到行尾自动换行) * * @param x 起始列 (0 ~ X_WIDTH-1) * @param page 起始页 (0 ~ OLED_PAGES-1) * @param str 以 '\0' 结尾的字符串指针(支持 const 静态字面量) * @param font_size OLED_FONT16 或 OLED_FONT8 */ void OLED_ShowString(uint8_t x, uint8_t page, const char *str, uint8_t font_size); /** * @brief 在本地 GRAM 缓冲区中写入一个 16×16 的标准汉字 * * @param Hzk 汉字字模二维数组只读指针(每个汉字 32 字节,分立上下两页) * @param x 起始列 (0 ~ X_WIDTH-1) * @param page 起始页 (0 ~ OLED_PAGES-1) * @param index 目标汉字在点阵数组中的索引序号 */ void OLED_ShowChinese(const uint8_t (*Hzk)[32], uint8_t x, uint8_t page, uint8_t index); /** * @brief 在本地 GRAM 缓冲区中绘制单色二进制 BMP 图像 * * @param x0 起始列 (0 ~ X_WIDTH-1) * @param page0 起始页 (0 ~ OLED_PAGES-1) * @param x_width 图像像素宽度 * @param y_width 图像像素高度(工程规范:必须为 8 的整数倍) * @param bmp 单色点阵数组指针(列行式,逆向取模) */ void OLED_DrawBMP(uint8_t x0, uint8_t page0, uint8_t x_width, uint8_t y_width, const uint8_t *bmp); /** * @brief OLED 驱动功能及综合演示函数(包含动态打字机、混排、全图爆破等) */ void oled_test_example(void); #endif /* __OLED_DRV_H */