俄罗斯视频网站开发,中国建设部,专业微网站建设公司首选公司,买卖链接网ESP-C3入门21. 点亮1306驱动的OLED屏 一、Espressif/ssd1306 驱动简介1. 驱动介绍2. OLED充电泵概念 二、I2C 通讯步骤1. 初始化 I2C 总线 (i2c_master_init()函数)#xff1a;2. 创建 I2C 命令句柄 (i2c_cmd_handle_t cmd i2c_cmd_link_create())#xff1a;3. 发送启动信号… ESP-C3入门21. 点亮1306驱动的OLED屏 一、Espressif/ssd1306 驱动简介1. 驱动介绍2. OLED充电泵概念 二、I2C 通讯步骤1. 初始化 I2C 总线 (i2c_master_init()函数)2. 创建 I2C 命令句柄 (i2c_cmd_handle_t cmd i2c_cmd_link_create())3. 发送启动信号 (i2c_master_start(cmd))4. 写入字节数据 (i2c_master_write_byte(cmd, data, ACK))5. 写入命令和数据6. 发送停止信号 (i2c_master_stop(cmd))7. 执行 I2C 命令序列 (i2c_master_cmd_begin(I2C_NUM_0, cmd, timeout))8. 删除命令句柄 (i2c_cmd_link_delete(cmd)) 三、通讯demo点亮OLED屏1. ssd1366.h2. font8x8_basic.h3. i2c 操作示例 main.c 四、Espressif 官方的 ssd1306驱动使用方法1. 使用idf.py命令加载库2. 下载源码加入工程3. main.c 实例 一、Espressif/ssd1306 驱动简介
1. 驱动介绍
地址 https://components.espressif.com/components/espressif/ssd1306
Espressif/ssd1306 是 Espressif Systems 开发的用于 SSD1306 驱动芯片的库用于在 ESP32 和 ESP8266 上控制 SSD1306 型号的 OLED 显示屏。这个库提供了一组函数和接口使得开发者可以在 ESP-IDF 框架中方便地控制和管理这种类型的 OLED 显示屏。
以下是 Espressif/ssd1306 库的一些主要特点和功能
OLED 控制该库允许你控制 SSD1306 驱动的 OLED 显示屏包括初始化、绘制图像、显示文本等。支持 I2C 和 SPI 接口该库支持使用 I2C 和 SPI 接口来与 OLED 显示屏通信。你可以根据你的项目需要选择适当的接口。支持多种显示模式Espressif/ssd1306 库支持多种显示模式如水平、垂直滚动、反显等。使用 C 语言该库是用 C 语言编写的与 ESP-IDF 框架相匹配可在 ESP32 和 ESP8266 上使用。开源Espressif/ssd1306 是开源项目你可以在 GitHub 上找到它的源代码查看其源代码、示例和文档。
2. OLED充电泵概念
“Set Charge Pump Enable” 是 OLED 显示屏初始化过程中的一个命令用于控制显示屏内部的电荷泵电路是否启用。电荷泵电路是一种电路可以将较低的电压转换为较高的电压从而在不增加外部电源电压的情况下为OLED显示屏提供所需的高压驱动。
在OLED显示屏中显示像素需要一定的驱动电压通常比较高。电荷泵电路的作用是通过将低电压转换为高电压为显示屏提供驱动所需的电压。这样可以减少对外部电源的依赖使得OLED显示屏可以使用更低的外部电压进行工作。
在Set Charge Pump Enable 命令中设置充电泵为启用状态可以确保OLED显示屏的驱动电路正常工作从而正常显示图像和文字。如果充电泵未启用可能会导致显示屏无法正常驱动造成屏幕无法显示或显示异常的问题。
二、I2C 通讯步骤
在 ESP-IDF 中使用 I2C 进行通信的步骤如下
1. 初始化 I2C 总线 (i2c_master_init()函数)
首先配置 I2C 总线的基本参数例如模式、SDA 和 SCL 引脚、上拉电阻等。使用 i2c_param_config() 函数设置这些参数然后调用 i2c_driver_install() 安装 I2C 驱动。
2. 创建 I2C 命令句柄 (i2c_cmd_handle_t cmd i2c_cmd_link_create())
使用 i2c_cmd_link_create() 函数创建一个用于构建 I2C 命令序列的命令句柄。
3. 发送启动信号 (i2c_master_start(cmd))
在开始通信前发送启动信号表示新的传输事务即将开始。
4. 写入字节数据 (i2c_master_write_byte(cmd, data, ACK))
通过 i2c_master_write_byte() 函数将字节数据写入 I2C 总线。data 参数是要发送的数据字节ACK 参数用于控制是否发送应答信号。
5. 写入命令和数据
利用连续的 i2c_master_write_byte() 调用写入 OLED 屏幕的控制命令和显示数据。
6. 发送停止信号 (i2c_master_stop(cmd))
传输完成后发送停止信号表示通信结束。
7. 执行 I2C 命令序列 (i2c_master_cmd_begin(I2C_NUM_0, cmd, timeout))
使用 i2c_master_cmd_begin() 函数将构建的命令序列发送到 I2C 总线并等待执行结果。
8. 删除命令句柄 (i2c_cmd_link_delete(cmd))
在通信完成后使用 i2c_cmd_link_delete() 函数释放创建的命令句柄以备后续使用。
这些步骤允许ESP32与 OLED 屏幕或其他外部设备进行可靠的通信。
三、通讯demo点亮OLED屏
下面的示例用到 两个网上的头文件 内容里写了引用链接。
1. ssd1366.h
#ifndef MAIN_SSD1366_H_
#define MAIN_SSD1366_H_// Following definitions are bollowed from
// http://robotcantalk.blogspot.com/2015/03/interfacing-arduino-with-ssd1306-driven.html// SLA (0x3C) WRITE_MODE (0x00) 0x78 (0b01111000)
#define OLED_I2C_ADDRESS 0x3C// Control byte
#define OLED_CONTROL_BYTE_CMD_SINGLE 0x80
#define OLED_CONTROL_BYTE_CMD_STREAM 0x00
#define OLED_CONTROL_BYTE_DATA_STREAM 0x40// Fundamental commands (pg.28)
#define OLED_CMD_SET_CONTRAST 0x81 // follow with 0x7F
#define OLED_CMD_DISPLAY_RAM 0xA4
#define OLED_CMD_DISPLAY_ALLON 0xA5
#define OLED_CMD_DISPLAY_NORMAL 0xA6
#define OLED_CMD_DISPLAY_INVERTED 0xA7
#define OLED_CMD_DISPLAY_OFF 0xAE
#define OLED_CMD_DISPLAY_ON 0xAF// Addressing Command Table (pg.30)
#define OLED_CMD_SET_MEMORY_ADDR_MODE 0x20 // follow with 0x00 HORZ mode Behave like a KS108 graphic LCD
#define OLED_CMD_SET_COLUMN_RANGE 0x21 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x7F COL127
#define OLED_CMD_SET_PAGE_RANGE 0x22 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x07 PAGE7// Hardware Config (pg.31)
#define OLED_CMD_SET_DISPLAY_START_LINE 0x40
#define OLED_CMD_SET_SEGMENT_REMAP 0xA1
#define OLED_CMD_SET_MUX_RATIO 0xA8 // follow with 0x3F 64 MUX
#define OLED_CMD_SET_COM_SCAN_MODE 0xC8
#define OLED_CMD_SET_DISPLAY_OFFSET 0xD3 // follow with 0x00
#define OLED_CMD_SET_COM_PIN_MAP 0xDA // follow with 0x12
#define OLED_CMD_NOP 0xE3 // NOP// Timing and Driving Scheme (pg.32)
#define OLED_CMD_SET_DISPLAY_CLK_DIV 0xD5 // follow with 0x80
#define OLED_CMD_SET_PRECHARGE 0xD9 // follow with 0xF1
#define OLED_CMD_SET_VCOMH_DESELCT 0xDB // follow with 0x30// Charge Pump (pg.62)
#define OLED_CMD_SET_CHARGE_PUMP 0x8D // follow with 0x14#endif /* MAIN_SSD1366_H_ */2. font8x8_basic.h
/** font8x8_basic.h** Created on: 2017/05/03* Author: yanbe*/#ifndef MAIN_FONT8X8_BASIC_H_
#define MAIN_FONT8X8_BASIC_H_/*Constant: font8x8_basic_trContains an 90 digree transposed 8x8 font map for unicode pointsU0000 - U007F (basic latin)To make it easy to use with SSD1306s GDDRAM mapping and API,this constant is an 90 degree transposed.The original version written by Marcel Sondaar is availble at:https://github.com/dhepper/font8x8/blob/master/font8x8_basic.hConversion is done via following procedure:for (int code 0; code 128; code) {uint8_t trans[8];for (int w 0; w 8; w) {trans[w] 0x00;for (int b 0; b 8; b) {trans[w] | ((font8x8_basic[code][b] (1 w)) w) b;}}for (int w 0; w 8; w) {if (w 0) { printf( { ); }printf(0x%.2X, trans[w]);if (w 7) { printf(, ); }if (w 7) { printf( }, // U00%.2X (%c)\n, code, code); }}}
*/uint8_t font8x8_basic_tr[128][8] {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0000 (nul){ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0001{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0002{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0003{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0004{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0005{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0006{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0007{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0008{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0009{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U000A{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U000B{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U000C{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U000D{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U000E{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U000F{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0010{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0011{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0012{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0013{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0014{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0015{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0016{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0017{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0018{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0019{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U001A{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U001B{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U001C{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U001D{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U001E{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U001F{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0020 (space){ 0x00, 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00 }, // U0021 (!){ 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00 }, // U0022 (){ 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 }, // U0023 (#){ 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 }, // U0024 ($){ 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 }, // U0025 (%){ 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 }, // U0026 (){ 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U0027 (){ 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 }, // U0028 ((){ 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 }, // U0029 ()){ 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 }, // U002A (*){ 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // U002B (){ 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 }, // U002C (,){ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 }, // U002D (-){ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }, // U002E (.){ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 }, // U002F (/){ 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 }, // U0030 (0){ 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 }, // U0031 (1){ 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 }, // U0032 (2){ 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 }, // U0033 (3){ 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 }, // U0034 (4){ 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 }, // U0035 (5){ 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 }, // U0036 (6){ 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 }, // U0037 (7){ 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 }, // U0038 (8){ 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 }, // U0039 (9){ 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }, // U003A (:){ 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 }, // U003B (;){ 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 }, // U003C (){ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 }, // U003D (){ 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 }, // U003E (){ 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 }, // U003F (?){ 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 }, // U0040 (){ 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 }, // U0041 (A){ 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 }, // U0042 (B){ 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 }, // U0043 (C){ 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // U0044 (D){ 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 }, // U0045 (E){ 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 }, // U0046 (F){ 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 }, // U0047 (G){ 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 }, // U0048 (H){ 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 }, // U0049 (I){ 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 }, // U004A (J){ 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 }, // U004B (K){ 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 }, // U004C (L){ 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 }, // U004D (M){ 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 }, // U004E (N){ 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 }, // U004F (O){ 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 }, // U0050 (P){ 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 }, // U0051 (Q){ 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 }, // U0052 (R){ 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 }, // U0053 (S){ 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 }, // U0054 (T){ 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 }, // U0055 (U){ 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 }, // U0056 (V){ 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 }, // U0057 (W){ 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 }, // U0058 (X){ 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 }, // U0059 (Y){ 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 }, // U005A (Z){ 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 }, // U005B ([){ 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 }, // U005C (\){ 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 }, // U005D (]){ 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 }, // U005E (^){ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, // U005F (_){ 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 }, // U0060 (){ 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 }, // U0061 (a){ 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 }, // U0062 (b){ 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 }, // U0063 (c){ 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 }, // U0064 (d){ 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 }, // U0065 (e){ 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 }, // U0066 (f){ 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 }, // U0067 (g){ 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 }, // U0068 (h){ 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 }, // U0069 (i){ 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 }, // U006A (j){ 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 }, // U006B (k){ 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 }, // U006C (l){ 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 }, // U006D (m){ 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 }, // U006E (n){ 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 }, // U006F (o){ 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 }, // U0070 (p){ 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 }, // U0071 (q){ 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 }, // U0072 (r){ 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 }, // U0073 (s){ 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 }, // U0074 (t){ 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 }, // U0075 (u){ 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 }, // U0076 (v){ 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 }, // U0077 (w){ 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 }, // U0078 (x){ 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 }, // U0079 (y){ 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 }, // U007A (z){ 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 }, // U007B ({){ 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 }, // U007C (|){ 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // U007D (}){ 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 }, // U007E (~){ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // U007F
};#endif /* MAIN_FONT8X8_BASIC_H_ */
3. i2c 操作示例 main.c
#include string.h#include driver/gpio.h
#include driver/i2c.h
#include esp_err.h
#include esp_log.h
#include freertos/task.h#include sdkconfig.h #include oled/include/ssd1366.h
#include oled/include/font8x8_basic.h#define SDA_PIN GPIO_NUM_4
#define SCL_PIN GPIO_NUM_5#define tag SSD1306void i2c_master_init() {i2c_config_t i2c_config {.mode I2C_MODE_MASTER,.sda_io_num SDA_PIN,.scl_io_num SCL_PIN,.sda_pullup_en GPIO_PULLUP_ENABLE,.scl_pullup_en GPIO_PULLUP_ENABLE,.master.clk_speed 100000,.clk_flags I2C_SCLK_SRC_FLAG_FOR_NOMAL};i2c_param_config(I2C_NUM_0, i2c_config);i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
}void ssd1306_init() {esp_err_t espRc;i2c_cmd_handle_t cmd i2c_cmd_link_create();// 向 I2C 总线发送启动信号表示一个新的传输事务即将开始。i2c_master_start(cmd);// 写入一个字节到 I2C 总线。这里使用 OLED 模块的 I2C 地址左移一位并加上写入标志指示写入操作i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS 1) | I2C_MASTER_WRITE, true);// 写入 OLED 控制命令流的字节表示后续的字节是控制命令。i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);// 写入 OLED 控制命令设置充电泵i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP, true);// 写入参数字节i2c_master_write_byte(cmd, 0x14, true);// 写入 OLED 控制命令设置段重映射即左右反转i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP, true); // reverse left-right mapping// 写入 OLED 控制命令设置行扫描模式即上下反转i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE, true); // reverse up-bottom mapping// 写入 OLED 控制命令打开 OLED 显示i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true);// 向 I2C 总线发送停止信号表示传输事务结束。i2c_master_stop(cmd);// 执行 I2C 命令序列将前面构建的命令发送到 I2C 总线上。返回的 espRc 变量会保存执行结果。espRc i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);if (espRc ESP_OK) {ESP_LOGI(tag, OLED configured successfully);} else {ESP_LOGE(tag, OLED configuration failed. code: 0x%.2X, espRc);}// 释放创建的 I2C 命令句柄以便后续的使用i2c_cmd_link_delete(cmd);
}void task_ssd1306_display_text(void *arg_text) {char *text (char *)arg_text;uint8_t text_len strlen(text);i2c_cmd_handle_t cmd;uint8_t cur_page 0;// 重置起始位置cmd i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS 1) | I2C_MASTER_WRITE, true);i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);i2c_master_write_byte(cmd, 0x00, true); // reset columni2c_master_write_byte(cmd, 0x10, true);i2c_master_write_byte(cmd, 0xB0 | cur_page, true); // reset pagei2c_master_stop(cmd);i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);i2c_cmd_link_delete(cmd);for (uint8_t i 0; i text_len; i) {if (text[i] \n) {// 换行cur_page;if (cur_page 8) {break; // 显示完整文本超出屏幕范围退出}cmd i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS 1) | I2C_MASTER_WRITE, true);i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);i2c_master_write_byte(cmd, 0x00, true); // reset columni2c_master_write_byte(cmd, 0x10, true);i2c_master_write_byte(cmd, 0xB0 | cur_page, true); // increment pagei2c_master_stop(cmd);i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);i2c_cmd_link_delete(cmd);} else {// 显示字符cmd i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS 1) | I2C_MASTER_WRITE, true);i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true);i2c_master_write(cmd, font8x8_basic_tr[(uint8_t)text[i]], 8, true);i2c_master_stop(cmd);i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);i2c_cmd_link_delete(cmd);}}vTaskDelete(NULL);
}
void generate_string(int columns, int newlines, char* ret) {char buffer[columns*newlines1];int j0;for(int page0;pagenewlines;page){for(int i0;icolumns;i){buffer[j] ;j;}buffer[j]\n;j;}buffer[j] \0;strcpy(ret, buffer);
}void app_main(void) {i2c_master_init();ssd1306_init();// 清屏操作const int columns 16;const int page 8;char space[columns*page1];generate_string(columns, page, space);// 清除屏幕内容xTaskCreate(task_ssd1306_display_text, ssd1306_display_text, 2048, (void *)space, 6, NULL);// 间隔一会防止进程有干扰vTaskDelay(500/portTICK_PERIOD_MS);xTaskCreate(task_ssd1306_display_text, ssd1306_display_text, 2048,(void *) Hello world!\nMulitine is OK!\nAnother line, 6, NULL);while(1){vTaskDelay(1);}
}四、Espressif 官方的 ssd1306驱动使用方法
1. 使用idf.py命令加载库
idf.py add-dependency espressif/ssd1306^1.0.52. 下载源码加入工程 需要适当修改引用头的路径
3. main.c 实例
#include stdio.h
#include oled/include/ssd1306.h
#include math.h#define I2C_MASTER_SCL_IO 5
#define I2C_MASTER_SDA_IO 4
#define I2C_MASTER_NUM I2C_NUM_0
#define I2C_MASTER_FREQ_HZ 100000static ssd1306_handle_t ssd1306_dev NULL;void draw_circle(int center_x, int center_y, int radius, uint8_t color) {for (int i 0; i 360; i) {float angle i * M_PI / 180.0;int x center_x radius * cos(angle);int y center_y radius * sin(angle);ssd1306_fill_point(ssd1306_dev, x, y, color);}
}void draw_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color) {ssd1306_draw_line(ssd1306_dev, x0, y0, x1, y1);ssd1306_draw_line(ssd1306_dev, x1, y1, x2, y2);ssd1306_draw_line(ssd1306_dev, x2, y2, x0, y0);
}void app_main(void)
{i2c_config_t conf;conf.mode I2C_MODE_MASTER;conf.sda_io_num (gpio_num_t)I2C_MASTER_SDA_IO;conf.sda_pullup_en GPIO_PULLUP_ENABLE;conf.scl_io_num (gpio_num_t)I2C_MASTER_SCL_IO;conf.scl_pullup_en GPIO_PULLUP_ENABLE;conf.master.clk_speed I2C_MASTER_FREQ_HZ;conf.clk_flags I2C_SCLK_SRC_FLAG_FOR_NOMAL;i2c_param_config(I2C_MASTER_NUM, conf);i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);ssd1306_dev ssd1306_create(I2C_MASTER_NUM, SSD1306_I2C_ADDRESS);ssd1306_init(ssd1306_dev);ssd1306_clear_screen(ssd1306_dev, 0x00);char data_str[10] {0};sprintf(data_str, C STR);ssd1306_draw_string(ssd1306_dev, 70, 16, (const uint8_t *)data_str, 16, 1);// 绘制圆draw_circle(30, 40, 20, 1);// 绘制三角形draw_triangle(80, 10, 100, 40, 60, 50, 1);ssd1306_refresh_gram(ssd1306_dev);
}
运行效果