guowenxue
4 days ago 53de825c4c4d8325c02341177f62ab84897eb5ee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**********************************************************************
 * Copyright: (C)2021 LingYun IoT System Studio <www.weike-iot.com>
 * Author: GuoWenxue<guowenxue@gmail.com> 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 */