README_zh.md
1# 小凌派-RK2206开发板基础外设开发——I2C控制OLED液晶屏显示
2
3本示例将演示如何在小凌派-RK2206开发板上使用I2C控制OLED液晶屏显示
4
5
6
7## 硬件接口说明
8
9引脚名称开发者可在硬件资源图中查看,也可在oled模块正面面查看。
10
11| 引脚名称 | 功能描述 |
12| :------- | :------------ |
13| SCL | I2C时钟信号线 |
14| SDA | I2C数据信号线 |
15| GND | 电源地引脚 |
16| VCC | 电源输入引脚 |
17
18### 硬件连接
19
20安装图如下所示:
21
22
23
24
25## 程序设计
26
27### API分析
28
29#### oled_init()
30
31```c
32unsigned int oled_init();
33```
34
35**描述:**
36
37初始化oled设备。
38
39**参数:**
40
41无
42
43**返回值:**
44
45返回0为成功,反之为失败
46
47#### oled_deinit()
48
49```c
50unsigned int oled_deinit();
51```
52
53**描述:**
54
55释放oled设备。
56
57**参数:**
58
59无
60
61**返回值:**
62
63返回0为成功,反之为失败
64
65#### oled_display_on()
66
67```c
68void oled_display_on(void);
69```
70
71**描述:**
72
73oled显示开启。
74
75**参数:**
76
77无
78
79**返回值:**
80
81无
82
83#### oled_display_off()
84
85```c
86void oled_display_off(void);
87```
88
89**描述:**
90
91oled显示关闭。
92
93**参数:**
94
95无
96
97**返回值:**
98
99无
100
101#### oled_clear()
102
103```c
104void oled_clear(void);
105```
106
107**描述:**
108
109oled清空屏幕。
110
111**参数:**
112
113无
114
115**返回值:**
116
117无
118
119#### oled_show_char()
120
121```c
122void oled_show_char(uint8_t x, uint8_t y, uint8_t chr, uint8_t chr_size);
123```
124
125**描述:**
126
127oled显示单个英文字符。
128
129**参数:**
130
131| 名字 | 描述 |
132| :------- | :---------------------------- |
133| x | 字符的X轴坐标 |
134| y | 字符的Y轴坐标 |
135| chr | 字符 |
136| chr_size | 字符的字体,包括12/16两种字体 |
137
138**返回值:**
139
140无
141
142#### oled_show_num()
143
144```c
145void oled_show_num(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size);
146```
147
148**描述:**
149
150oled显示整数。
151
152**参数:**
153
154| 名字 | 描述 |
155| :--- | :------------------------------ |
156| x | 整数数的X轴坐标 |
157| y | 整数数的Y轴坐标 |
158| num | 整数 |
159| len | 整数的位数 |
160| size | 整数字的字体,包括12/16两种字体 |
161
162**返回值:**
163
164无
165
166#### oled_show_string()
167
168```c
169void oled_show_string(uint8_t x, uint8_t y, uint8_t *p, uint8_t chr_size);
170```
171
172**描述:**
173
174oled显示英文字符串。
175
176**参数:**
177
178| 名字 | 描述 |
179| :------- | :---------------------------- |
180| x | 字符串的X轴坐标 |
181| y | 字符串的Y轴坐标 |
182| p | 字符串 |
183| chr_size | 字符的字体,包括12/16两种字体 |
184
185**返回值:**
186
187无
188
189#### oled_draw_bmp()
190
191```c
192void oled_draw_bmp(unsigned char x0,
193 unsigned char y0,
194 unsigned char x1,
195 unsigned char y1,
196 unsigned char bmp[]);
197```
198
199**描述:**
200
201oled显示图片。
202
203**参数:**
204
205| 名字 | 描述 |
206| :--- | :------------------------------- |
207| x0 | 图片的起始点X轴坐标,取值为0~127 |
208| y0 | 图片的起始点Y轴坐标,取值为0~63 |
209| x1 | 图片的结束点X轴坐标,取值为0~127 |
210| y1 | 图片的结束点Y轴坐标,取值为0~63 |
211| bmp | 图片 |
212
213**返回值:**
214
215无
216
217### OLED器件
218
219**OLED显示屏**
220
221OLED显示屏是0.96寸OLED显示屏,型号为SSD1306,像素为128 * 64。
222
223OLED液晶屏采用i2c通信方式,根据芯片手册说明,从设备地址为 `0x3C`。
224
225### 主要代码分析
226
227这部分代码为i2c初始化的代码。首先用 `I2cIoInit()` 函数将GPIO0_PC1复用为I2C1_SDA_M1,GPIO0_PC2复用为I2C1_SCL_M1。最后调用 `LzI2cInit()`函数初始化I2C1端口。
228
229```c
230if (I2cIoInit(m_i2cBus) != LZ_HARDWARE_SUCCESS)
231{
232 printf("%s, %d: I2cIoInit failed!\n", __FILE__, __LINE__);
233 return __FILE__;
234}
235if (LzI2cInit(OLED_I2C_BUS, m_i2c_freq) != LZ_HARDWARE_SUCCESS)
236{
237 printf("%s, %d: I2cIoInit failed!\n", __FILE__, __LINE__);
238 return __FILE__;
239}
240```
241
242具体i2c写操作如下:
243
244```c
245static inline void Write_IIC_Command(unsigned char IIC_Command)
246{
247 unsigned char buffer[2];
248 unsigned int ret;
249
250 /* 填充数据,第一个字节是通知OLED芯片,下一个字节是命令 */
251 buffer[0] = 0x00;
252 buffer[1] = IIC_Command;
253 ret = LzI2cWrite(OLED_I2C_BUS, OLED_I2C_ADDRESS, buffer, 2);
254 if (ret != 0)
255 {
256 printf("%s, %s, %d: LzI2cWrite failed(%d)!\n", __FILE__, __func__, __LINE__, ret);
257 }
258}
259
260static inline void Write_IIC_Data(unsigned char IIC_Data)
261{
262 unsigned char buffer[2];
263 unsigned int ret;
264
265 /* 填充数据,第一个字节是通知OLED芯片,下一个字节是数据 */
266 buffer[0] = 0x40;
267 buffer[1] = IIC_Data;
268 ret = LzI2cWrite(OLED_I2C_BUS, OLED_I2C_ADDRESS, buffer, 2);
269 if (ret != 0)
270 {
271 printf("%s, %s, %d: LzI2cWrite failed(%d)!\n", __FILE__, __func__, __LINE__, ret);
272 }
273}
274```
275
276### 配置SSD1306启动
277
278```c
279LOS_Msleep(200);
280
281Oled_WR_Byte(0xAE, OLED_CMD); //--display off
282Oled_WR_Byte(0x00, OLED_CMD); //---set low column address
283Oled_WR_Byte(0x10, OLED_CMD); //---set high column address
284Oled_WR_Byte(0x40, OLED_CMD); //--set start line address
285Oled_WR_Byte(0xB0, OLED_CMD); //--set page address
286Oled_WR_Byte(0x81, OLED_CMD); // contract control
287Oled_WR_Byte(0xFF, OLED_CMD); //--128
288Oled_WR_Byte(0xA1, OLED_CMD); //set segment remap
289Oled_WR_Byte(0xA6, OLED_CMD); //--normal / reverse
290Oled_WR_Byte(0xA8, OLED_CMD); //--set multiplex ratio(1 to 64)
291Oled_WR_Byte(0x3F, OLED_CMD); //--1/32 duty
292Oled_WR_Byte(0xC8, OLED_CMD); //Com scan direction
293Oled_WR_Byte(0xD3, OLED_CMD); //-set display offset
294Oled_WR_Byte(0x00, OLED_CMD); //
295
296Oled_WR_Byte(0xD5, OLED_CMD); //set osc division
297Oled_WR_Byte(0x80, OLED_CMD); //
298
299Oled_WR_Byte(0xD8, OLED_CMD); //set area color mode off
300Oled_WR_Byte(0x05, OLED_CMD); //
301
302Oled_WR_Byte(0xD9, OLED_CMD); //Set Pre-Charge Period
303Oled_WR_Byte(0xF1, OLED_CMD); //
304
305Oled_WR_Byte(0xDA, OLED_CMD); //set com pin configuartion
306Oled_WR_Byte(0x12, OLED_CMD); //
307
308Oled_WR_Byte(0xDB, OLED_CMD); //set Vcomh
309Oled_WR_Byte(0x30, OLED_CMD); //
310
311Oled_WR_Byte(0x8D, OLED_CMD); //set charge pump enable
312Oled_WR_Byte(0x14, OLED_CMD); //
313
314Oled_WR_Byte(0xAF, OLED_CMD); //--turn on oled panel
315```
316
317这部分代码将SSD1306的启动配置。
318
319## 编译调试
320
321### 修改 BUILD.gn 文件
322
323修改 `vendor/lockzhiner/lingpi/sample` 路径下 BUILD.gn 文件,指定 `b5_oled` 参与编译。
324
325```r
326"b5_oled",
327```
328
329在主目录下输入编译命令。
330
331```shell
332hb build -f
333```
334
335### 运行结果
336
337示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,并请使用带有LCD屏幕显示如下:
338
339```c
340========= Oled Process =============
341
342```
343
344OLED显示结果如下所示:
345
346
347