ESP-C3入门21. I2C接口点亮1306驱动的OLED屏

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.h
    • 2. font8x8_basic.h
    • 3. 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 库的一些主要特点和功能:

  1. OLED 控制:该库允许你控制 SSD1306 驱动的 OLED 显示屏,包括初始化、绘制图像、显示文本等。
  2. 支持 I2C 和 SPI 接口:该库支持使用 I2C 和 SPI 接口来与 OLED 显示屏通信。你可以根据你的项目需要选择适当的接口。
  3. 支持多种显示模式:Espressif/ssd1306 库支持多种显示模式,如水平、垂直滚动、反显等。
  4. 使用 C 语言:该库是用 C 语言编写的,与 ESP-IDF 框架相匹配,可在 ESP32 和 ESP8266 上使用。
  5. 开源: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 pointsU+0000 - U+007F (basic latin)To make it easy to use with SSD1306's 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(" },   // U+00%.2X (%c)\n", code, code); }}}
*/uint8_t font8x8_basic_tr[128][8] = {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0000 (nul){ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0001{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0002{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0003{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0004{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0005{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0006{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0007{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0008{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0009{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+000A{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+000B{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+000C{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+000D{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+000E{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+000F{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0010{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0011{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0012{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0013{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0014{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0015{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0016{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0017{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0018{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0019{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+001A{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+001B{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+001C{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+001D{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+001E{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+001F{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0020 (space){ 0x00, 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00 },   // U+0021 (!){ 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00 },   // U+0022 ("){ 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 },   // U+0023 (#){ 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 },   // U+0024 ($){ 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 },   // U+0025 (%){ 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 },   // U+0026 (&){ 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 },   // U+0027 ('){ 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 },   // U+0028 ((){ 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 },   // U+0029 ()){ 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 },   // U+002A (*){ 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 },   // U+002B (+){ 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 },   // U+002C (,){ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 },   // U+002D (-){ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 },   // U+002E (.){ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 },   // U+002F (/){ 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 },   // U+0030 (0){ 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 },   // U+0031 (1){ 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 },   // U+0032 (2){ 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 },   // U+0033 (3){ 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 },   // U+0034 (4){ 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 },   // U+0035 (5){ 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 },   // U+0036 (6){ 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 },   // U+0037 (7){ 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 },   // U+0038 (8){ 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 },   // U+0039 (9){ 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 },   // U+003A (:){ 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 },   // U+003B (;){ 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 },   // U+003C (<){ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 },   // U+003D (=){ 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 },   // U+003E (>){ 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 },   // U+003F (?){ 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 },   // U+0040 (@){ 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 },   // U+0041 (A){ 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 },   // U+0042 (B){ 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 },   // U+0043 (C){ 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 },   // U+0044 (D){ 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 },   // U+0045 (E){ 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 },   // U+0046 (F){ 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 },   // U+0047 (G){ 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 },   // U+0048 (H){ 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 },   // U+0049 (I){ 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 },   // U+004A (J){ 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 },   // U+004B (K){ 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 },   // U+004C (L){ 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 },   // U+004D (M){ 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 },   // U+004E (N){ 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 },   // U+004F (O){ 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 },   // U+0050 (P){ 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 },   // U+0051 (Q){ 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 },   // U+0052 (R){ 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 },   // U+0053 (S){ 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 },   // U+0054 (T){ 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 },   // U+0055 (U){ 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 },   // U+0056 (V){ 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 },   // U+0057 (W){ 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 },   // U+0058 (X){ 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 },   // U+0059 (Y){ 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 },   // U+005A (Z){ 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 },   // U+005B ([){ 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 },   // U+005C (\){ 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 },   // U+005D (]){ 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 },   // U+005E (^){ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },   // U+005F (_){ 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 },   // U+0060 (`){ 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 },   // U+0061 (a){ 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 },   // U+0062 (b){ 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 },   // U+0063 (c){ 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 },   // U+0064 (d){ 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 },   // U+0065 (e){ 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 },   // U+0066 (f){ 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 },   // U+0067 (g){ 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 },   // U+0068 (h){ 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 },   // U+0069 (i){ 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 },   // U+006A (j){ 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 },   // U+006B (k){ 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 },   // U+006C (l){ 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 },   // U+006D (m){ 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 },   // U+006E (n){ 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 },   // U+006F (o){ 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 },   // U+0070 (p){ 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 },   // U+0071 (q){ 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 },   // U+0072 (r){ 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 },   // U+0073 (s){ 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 },   // U+0074 (t){ 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 },   // U+0075 (u){ 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 },   // U+0076 (v){ 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 },   // U+0077 (w){ 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 },   // U+0078 (x){ 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 },   // U+0079 (y){ 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 },   // U+007A (z){ 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 },   // U+007B ({){ 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 },   // U+007C (|){ 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 },   // U+007D (}){ 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 },   // U+007E (~){ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }    // U+007F
};#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 "SSD1306"void 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*newlines+1];int j=0;for(int page=0;page<newlines;page++){for(int i=0;i<columns;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*page+1];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.5"

2. 下载源码加入工程

在这里插入图片描述
需要适当修改引用头的路径

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);
}

运行效果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/41027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低功耗、5Mbps、RS-422 接口电路MS2583/MS2583M

MS2583/MS2583M 是一款低功耗、 5Mbps 、高 ESD 能力的 RS422 通讯接口电路。 在接收状态下&#xff0c;其功耗仅为 0.3mA 左右。 A/B 端 ESD 耐压可达 15kV &#xff0c;且无自激现象。当输出短路发生大电 流导致电路温度过高时&#xff0c;开启内部过温保护电路&…

vue中的路由缓存和解决方案

路由缓存的原因 解决方法 推荐方案二&#xff0c;使用钩子函数beforeRouteUpdate&#xff0c;每次路由更新前执行

MFC第三十天 通过CToolBar类开发文字工具栏和工具箱、GDI+边框填充以及基本图形的绘制方法、图形绘制过程的反色线模型和实色模型

文章目录 CControlBar通过CToolBar类开发文字工具栏和工具箱CMainFrame.hCAppCMainFrm.cppCMainView.hCMainView.cppCEllipse.hCEllipse.cppCLine.hCLine.cppCRRect .hCRRect .cpp CControlBar class AFX_NOVTABLE CControlBar : public CWnd{DECLARE_DYNAMIC(CControlBar)pro…

OC调用Swift编写的framework

一、前言 随着swift趋向稳定&#xff0c;越来越多的公司都开始用swift来编写苹果相关的业务了&#xff0c;关于swift的利弊这里就不多说了。这里详细介绍OC调用swift编写的framework库的步骤 二、制作framework 1、新建项目&#xff0c;选择framework 2、填写framework的名称…

AutoHotkey:定时删除目录下指定分钟以前的文件,带UI界面

删除指定目录下&#xff0c;所有在某个指定分钟以前的文件&#xff0c;可以用来清理经常生成很多文件的目录&#xff0c;但又需要保留最新的一部分文件 支持拖放目录到界面 能够记忆设置&#xff0c;下次启动后不用重新设置&#xff0c;可以直接开始 应用场景比如&#xff1a…

WinForm内嵌Unity3D

Unity3D可以C#脚本进行开&#xff0c;使用vstu2013.msi插件&#xff0c;可以实现在VS2013中的调试。在开发完成后&#xff0c;由于项目需要&#xff0c;需要将Unity3D嵌入到WinForm中。WinForm中的UnityWebPlayer Control可以载入Unity3D。先看效果图。 一、为了能够动态设置ax…

【boost网络库从青铜到王者】第五篇:asio网络编程中的同步读写的客户端和服务器示例

文章目录 1、简介2、客户端设计3、服务器设计3.1、session函数3.2、StartListen函数3、总体设计 4、效果测试5、遇到的问题5.1、服务器遇到的问题5.1.1、不用显示调用bind绑定和listen监听函数5.1.2、出现 Error occured!Error code : 10009 .Message: 提供的文件句柄无效。 [s…

Failed to execute goal org.apache.maven.plugins

原因&#xff1a; 这个文件D:\java\maven\com\ruoyi\pg-student\maven-metadata-local.xml出了问题 解决&#xff1a; 最简单的直接删除D:\java\maven\com\ruoyi\pg-student\maven-metadata-local.xml重新打包 或者把D:\java\maven\com\ruoyi\pg-student这个目录下所有文件…

2023年京东宠物食品行业数据分析(京东大数据)

宠物食品市场需求主要来自于养宠规模&#xff0c;近年来由于我国宠物数量及养宠人群的规模均在不断扩大&#xff0c;宠物相关产业和市场规模也在蓬勃发展&#xff0c;宠物食品市场也同样保持正向增长。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;2023年1月-7月&am…

接口自动化测试(添加课程接口调试,调试合同上传接口,合同列表查询接口,批量执行)

1、我们把信息截取一下 1.1 添加一个新的请求 1.2 对整个请求进行保存&#xff0c;Ctrl S 2、这一次我们添加的是课程添加接口&#xff0c;以后一个接口完成&#xff0c;之后Ctrl S 就能够保存 2.1 选择方法 2.2 设置请求头&#xff0c;参数数据后期我们通过配置设置就行 3、…

收银一体化-亿发2023智慧门店新零售营销策略,实现全渠道运营

伴随着互联网电商行业的兴起&#xff0c;以及用户理念的改变&#xff0c;大量用户从线下涌入线上&#xff0c;传统的线下门店人流量急剧收缩&#xff0c;门店升级几乎成为了每一个零售企业的发展之路。智慧门店新零售收银解决方案是针对传统零售企业面临的诸多挑战和问题&#…

Mathematica 与 Matlab 常见复杂指令集汇编

Mathematica 常见指令汇编 Mathematica 常见指令 NDSolve 求解结果的保存 sol NDSolve[{y[x] x^2, y[0] 0, g[x] -y[x]^2, g[0] 1}, {y, g}, {x, 0, 1}]; numericSoly sol[[1, 1, 2]]; numericSolg sol[[1, 2, 2]]; data Table[{x, numericSoly[x], numericSolg[x]},…

JVM——类加载器

回顾一下类加载过程 类加载过程&#xff1a;加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。 一个非数组类的加载阶段&#xff08;加载阶段获取类的二进制字节流的动作&#xff09;是可控性最强的阶段&#xff0c;这一步我们可以去完成还可以自定义…

【计算机网络篇】UDP协议

✅作者简介&#xff1a;大家好&#xff0c;我是小杨 &#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; UDP协议 1&#xff0c;UDP 简介 UDP&#xff08;User Datagram Protocol&#xff09;是一种无连…

Flink学习笔记(一)

流处理 批处理应用于有界数据流的处理&#xff0c;流处理则应用于无界数据流的处理。 有界数据流&#xff1a;输入数据有明确的开始和结束。 无界数据流&#xff1a;输入数据没有明确的开始和结束&#xff0c;或者说数据是无限的&#xff0c;数据通常会随着时间变化而更新。 在…

Kaptcha的基本应用

Kaptcha Kaptcha 是一个用于生成和验证验证码的 Java 库&#xff0c;提供了丰富的生成和验证功能&#xff0c;并支持自定义配置。它可以用于增加应用程序的安全性&#xff0c;防止机器人和恶意攻击。 Kaptcha 可以生成各种类型的验证码&#xff0c;包括数字、字母、数字字母组…

KDD 2023 获奖论文公布,港中文、港科大等获最佳论文奖

ACM SIGKDD&#xff08;国际数据挖掘与知识发现大会&#xff0c;KDD&#xff09;是数据挖掘领域历史最悠久、规模最大的国际顶级学术会议&#xff0c;也是首个引入大数据、数据科学、预测分析、众包等概念的会议。 今年&#xff0c;第29届 KDD 大会于上周在美国加州长滩圆满结…

HTTP--Request详解

请求消息数据格式 请求行 请求方式 请求url 请求协议/版本 GET /login.html HTTP/1.1 请求头 客户端浏览器告诉服务器一些信息 请求头名称: 请求头值 常见的请求头&#xff1a; User-Agent&#xff1a;浏览器告诉服务器&#xff0c;我访问你使用的浏览器版本信息 可…

【日常积累】HTTP和HTTPS的区别

背景 在运维面试中&#xff0c;经常会遇到面试官提问http和https的区别&#xff0c;今天咱们先来简单了解一下。 超文本传输协议HTTP被用于在Web浏览器和网站服务器之间传递信息&#xff0c;HTTP协议以明文方式发送内容&#xff0c;不提供任何方式的数据加密&#xff0c;如果…

09- DMA(DirectMemoryAccess直接存储器访问)

DMA 09 、DMA(DirectMemoryAccess直接存储器访问)DMA配置流程 09 、DMA(DirectMemoryAccess直接存储器访问) DMA配置流程 dma.c文件 main.c文件 详见《stm32中文参考手册》表57。