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