【ESP32 IDF】ESP32移植u8g2库,实现oled界面显示

news2024/11/17 5:32:33

ESP32移植u8g2库,实现oled界面显示

  • 1. 简单描述
  • 2. 环境准备
        • 1. 硬件准备
        • 2. 软件准备
  • 3. IIC屏幕 【基于 ssd1362 + 256*64 】
  • 4. SPI屏幕 【基于 ssd1306 + 128*32】

1. 简单描述

  1. 开发方式为 IDF5.0
  2. 参考连接为
    iic基于esp-idf移植使用u8g2
    spi基于esp-idf移植使用u8g2

2. 环境准备

1. 硬件准备
  1. 首先屏幕有两种通信方式:spi,iic
  2. 然后得知道你手上屏幕的型号和分辨率:
  • ssd1362 iic 淘宝连接
    在这里插入图片描述

  • ssd1306 spi 淘宝连接

2. 软件准备
  1. 使用git下载好u8g2 下载连接

3. IIC屏幕 【基于 ssd1362 + 256*64 】

  • 在idf里面新建 components 取名为 【u8g2】
  • 将下载的u8g2文件下csrc文件按照文件类型排序,将h文件放在include,c文件直接放u8g2目录下。
u8g2
    ├─include
    │      mui.h
    │      mui_u8g2.h
    │      u8g2.h
    │      u8x8.h
    └─根目录
            mui.c
            mui_u8g2.c
            u8g2_bitmap.c
            u8g2_box.c
            u8g2_buffer.c
            u8g2_button.c
            u8g2_circle.c
            u8g2_cleardisplay.c
            u8g2_d_memory.c
            u8g2_d_setup.c
            u8g2_font.c
            u8g2_fonts.c
            u8g2_hvline.c
            u8g2_input_value.c
            u8g2_intersection.c
            u8g2_kerning.c
            u8g2_line.c
            u8g2_ll_hvline.c
            u8g2_message.c
            u8g2_polygon.c
            u8g2_selection_list.c
            u8g2_setup.c
            u8log.c
            u8log_u8g2.c
            u8log_u8x8.c
            u8x8_8x8.c
            u8x8_byte.c
            u8x8_cad.c
            u8x8_capture.c
			
			[这中间有很多文件不需要拷贝]

            u8x8_debounce.c
            u8x8_display.c
            u8x8_fonts.c
            u8x8_gpio.c
            u8x8_input_value.c
            u8x8_message.c
            u8x8_selection_list.c
            u8x8_setup.c
            u8x8_string.c
            u8x8_u16toa.c
            u8x8_u8toa.c
  • 在下载的u8g2文件下csrc找到对应芯片的.c文件,比如我这就找到ssd1362,并放在我们的代码u8g2下

u8x8_d_ssd1362.c

  • 修改 CMakeLists.txt ,注意最后是一个自己芯片.c文件
idf_component_register(SRCS "mui.c"
                            "mui_u8g2.c"
                            "u8g2_bitmap.c"
                            "u8g2_box.c"
                            "u8g2_buffer.c"
                            "u8g2_button.c"
                            "u8g2.c"
                            "u8g2_circle.c"
                            "u8g2_cleardisplay.c"
                            "u8g2_d_memory.c"
                            "u8g2_d_setup.c"
                            "u8g2_font.c"
                            "u8g2_fonts.c"
                            "u8g2_hvline.c"
                            "u8g2_input_value.c"
                            "u8g2_intersection.c"
                            "u8g2_kerning.c"
                            "u8g2_line.c"
                            "u8g2_ll_hvline.c"
                            "u8g2_message.c"
                            "u8g2_polygon.c"
                            "u8g2_selection_list.c"
                            "u8g2_setup.c"
                            "u8log.c"
                            "u8log_u8g2.c"
                            "u8log_u8x8.c"
                            "u8x8_8x8.c"
                            "u8x8_byte.c"
                            "u8x8_cad.c"
                            "u8x8_capture.c"
                            "u8x8_debounce.c"
                            "u8x8_display.c"
                            "u8x8_fonts.c"
                            "u8x8_gpio.c"
                            "u8x8_input_value.c"
                            "u8x8_message.c"
                            "u8x8_selection_list.c"
                            "u8x8_setup.c"
                            "u8x8_string.c"
                            "u8x8_u16toa.c"
                            "u8x8_u8toa.c"
                            "u8x8_d_ssd1362.c"
                    INCLUDE_DIRS "include"
                    REQUIRES driver
                    REQUIRES freertos)
  • 在u8g2_d_setup.c文件找到对应函数,注释掉所有函数只留这个,别忘了不注释
    #include "u8g2.h"
    在这里插入图片描述

  • 再通过上面函数中的函数 u8g2_m_32_8_f(&tile_buf_height); 跳转到u8g2_d_memory.c文件注释其他函数

在这里插入图片描述

  • 将u8g2/u8g2.c文件内容替换如下
#include <stdio.h>
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "unistd.h"
#include "string.h"
#include "stdlib.h"
#include "esp_log.h"
#include "driver/i2c.h"
#include "u8g2.h"
#include "u8x8.h"

#define I2C_SCL_IO GPIO_NUM_17
#define I2C_SDA_IO GPIO_NUM_9
#define ACK_CHECK_EN 0x1
#define WRITE_BIT I2C_MASTER_WRITE 

static const char *TAG = "u8g2";
static __inline void delay_clock(int ts)
{
	uint32_t start, curr;
	__asm__ __volatile__("rsr %0, ccount" : "=r"(start));
	do
		__asm__ __volatile__("rsr %0, ccount" : "=r"(curr));
	while (curr - start <= ts);
}
#define delay_us(val) delay_clock(240 * val)
#define delay_100ns(val) delay_clock(24 * val)

i2c_config_t i2c_config = {
	.mode = I2C_MODE_MASTER,			 // 主机模式
	.sda_io_num = I2C_SDA_IO,			 // sda i引脚编号
	.scl_io_num = I2C_SCL_IO,			 // scl 引脚编号
	.sda_pullup_en = GPIO_PULLUP_ENABLE, // 上拉使能
	.scl_pullup_en = GPIO_PULLUP_ENABLE, // 上拉使能
	.master.clk_speed = 900000			 // 100k
};

static void _oled_i2c_init(void)
{
	ESP_LOGE(TAG, "u8g2 init start");
	i2c_param_config(I2C_NUM_1, &i2c_config);
	i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0);
	ESP_LOGE(TAG, "u8g2 init end");
}

void esp32_i2c_write(uint8_t addr, uint32_t idx, uint8_t *data)
{
	i2c_cmd_handle_t handler = i2c_cmd_link_create();
	i2c_master_start(handler);
	i2c_master_write_byte(handler, addr | WRITE_BIT, ACK_CHECK_EN);
	i2c_master_write(handler, data, idx, 2);
	i2c_master_stop(handler);
	i2c_master_cmd_begin(I2C_NUM_1, handler, 100 / portTICK_PERIOD_MS);
	i2c_cmd_link_delete(handler);
}

// u8g2用到的系统资源
uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
	switch (msg)
	{
	case U8X8_MSG_GPIO_AND_DELAY_INIT:
		_oled_i2c_init(); // 调用iic初始化
		break;
	case U8X8_MSG_DELAY_MILLI:
		vTaskDelay(arg_int);
		break;
	default:
		return 0;
	}
	return 1;
}
// u8g2用到的显示屏控制接口
uint8_t u8x8_byte_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
	static uint8_t buffer[32]; /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
	static uint8_t buf_idx;
	uint8_t *data;

	switch (msg)
	{
	case U8X8_MSG_BYTE_SEND:
		data = (uint8_t *)arg_ptr;
		while (arg_int > 0)
		{
			buffer[buf_idx++] = *data;
			data++;
			arg_int--;
		}
		break;
	case U8X8_MSG_BYTE_INIT:
		/* add your custom code to init i2c subsystem */
		break;
	case U8X8_MSG_BYTE_SET_DC:
		/* ignored for i2c */
		break;
	case U8X8_MSG_BYTE_START_TRANSFER:
		buf_idx = 0;
		break;
	case U8X8_MSG_BYTE_END_TRANSFER:
		esp32_i2c_write(u8x8_GetI2CAddress(u8x8), buf_idx, buffer);
		break;
	default:
		return 0;
	}
	return 1;
}

void u8g2Init(u8g2_t *u8g2)
{
	u8g2_Setup_ssd1362_i2c_256x64_f(u8g2, U8G2_R2, u8x8_byte_i2c, u8x8_gpio_and_delay); // 初始化 u8g2 结构体
	u8g2_InitDisplay(u8g2);																// 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
	u8g2_SetPowerSave(u8g2, 0);															// 打开显示器
	u8g2_ClearBuffer(u8g2);
	u8g2_SendBuffer(u8g2); // 清屏
	ESP_LOGI(TAG, "u8g2 init done");
}
  • 在u8g2.h文件最近添加声明
void u8g2Init(u8g2_t *u8g2);
  • main.c代码改为如下
#include "u8g2.h"
#include "u8x8.h"

static u8g2_t u8g2;

void oled_init()
{
    u8g2Init(&u8g2);
}

void showmain()
{
    u8g2_ClearBuffer(&u8g2);
    u8g2_SendBuffer(&u8g2);                        // 清屏
    u8g2_SetFont(&u8g2, u8g2_font_spleen32x64_me); // 设置英文字体
    u8g2_DrawStr(&u8g2, 64, 64, "1000");
    u8g2_DrawStr(&u8g2, 192, 64, "KG");
    u8g2_SendBuffer(&u8g2);
}

void showmain2()
{
    u8g2_ClearBuffer(&u8g2);
    u8g2_SendBuffer(&u8g2);                         // 清屏
    u8g2_SetFont(&u8g2, u8g2_font_wqy16_t_gb2312b); //
    u8g2_DrawUTF8(&u8g2, 32, 32, "总重量");
    u8g2_SendBuffer(&u8g2);
}

void app_main(void)
{
    oled_init(); // INIT

    showmain();
    showmain2();
    while (1)
    {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

4. SPI屏幕 【基于 ssd1306 + 128*32】

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

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

相关文章

插入排序——直接插入排序和希尔排序(C语言实现)

文章目录 前言直接插入排序基本思想特性总结代码实现 希尔排序算法思想特性总结代码实现 前言 本博客插入排序动图和希尔排序视频参考大佬java技术爱好者&#xff0c;如有侵权&#xff0c;请联系删除。 直接插入排序 基本思想 直接插入排序是一种简单的插入排序法&#xff…

广播和组播

1. 广播 1.1 知识点 INADDR_ANY代表本机所有地址 常用方法当你将套接字绑定到INADDR_ANY&#xff0c;它会监听所有可用的网络接口&#xff0c;这意味着它将接受来自所有本地IP地址的传入连接或数据包 1.1.1 广播的流程 广播发送端&#xff1a; ----> 添加广播属性 1、建立套…

JAVA后端自学技能实操合集

JAVA后端自学技能实操 内容将会持续更新中,有需要添加什么内容可以再评论区留言,大家一起学习FastDFS使用docker安装FastDFS(linux)集成到springboot项目中 内容将会持续更新中,有需要添加什么内容可以再评论区留言,大家一起学习 FastDFS 组名&#xff1a;文件上传后所在的 st…

MySQL中是如何insert数据的

正常insert数据&#xff0c;MySQL并不会显式加锁&#xff0c;而是通过聚簇索引的trx_id索引作为隐式锁来保护记录的。比如两个事务对一个非唯一的索引情况添加&#xff0c;会造成幻读 但在某些特殊情况下&#xff0c;隐式锁会转变为显式锁&#xff1a; 记录之间有间隙锁inser…

Qt使用Cryptopp生成HMAC-MD5

近期项目中HTTPS通讯中&#xff0c;token需要使用HMAC-MD5算法生成&#xff0c;往上找了一些资料后&#xff0c;仍不能满足自身需求&#xff0c;故次一记。 前期准备&#xff1a; ①下载Cryptopp库&#xff08;我下载的是8.8.0 Release版本&#xff09;&#xff1a;Crypto Li…

基础课19——知识图谱问答引擎

1.概念 知识图谱是一种结构化的知识表示方式&#xff0c;将实体、属性和关系以图形的形式进行表达和组织。它通过对知识进行结构化建模&#xff0c;将不同实体之间的关系进行编码&#xff0c;形成一个图结构的知识网络。知识图谱的目标是将人类的知识整合到一个统一的框架中&a…

Segment Anything--SAM框架(二)

文章目录 prologuepaper && codeImage encoderPrompt encoderLightweight mask decoderMaking the model ambiguity-aware prologue 没什么事&#xff0c;写一写SAM的paper中关于模型框架的部分和实际代码部分。 paper && code SAM有三个组件&#xff0c;如图…

图数据库知识点9 | 大数据框架与图数据架构异同

开门见山&#xff0c;直奔主题&#xff0c;接续前面的知识点&#xff1a; 【图数据库知识点1|图数据库与关系型数据库的区别&#xff1f;】 【图数据库知识点2 | 图思维方式】 【图数据库知识点3 | 图数据库解决了什么问题&#xff1f;】 【图数据库知识点4 | 图计算与图数…

TypeScript枚举类型、类型断言

一. 概念 TypeScript中的枚举是一种数据类型&#xff0c;它是一组具有预定义名称的有限值的集合。枚举类型可以使代码更加可读、可维护和易于理解。 类似对象&#xff0c;枚举是将一组无序但极度相关数组集合在一起声明存储。 二. 枚举特性 1. 内部进行了双向赋值 enum Numb…

奕碳科技亮相COP28:展现中国智慧,引领全球碳减排新篇章

11月30日,联合国气候变化框架公约第28次缔约方大会 (COP28) 在阿联酋迪拜开幕。COP28是全球气候治理的重要盛会&#xff0c;汇聚了世界各国领导人、企业界和科学界代表&#xff0c;共同探讨和制定应对全球气候变化的策略与行动计划。在这样的背景下&#xff0c;企业群体的积极参…

力扣题:字符的统计-12.7

力扣题-12.7 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;467. 环绕字符串中唯一的子字符串 解题思想&#xff1a;记录下以字母s[i]结尾的最大的字串个数&#xff0c;然后统计a-z每个字母结尾的最大字串的个数进行i相加 class Solution(object…

「Verilog学习笔记」同步FIFO

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1ns /**********************************RAM************************************/ module dual_port_RAM #(parameter DEPTH 16,parameter WIDTH 8)(in…

Anaconda建虚拟环境并在jupyter中打开

1.假设要用yaml格式创建虚拟环境 从开始里打开anaconda powersheel 输入以下 conda env create -f environment.yaml conda activate env_name activate以下虚拟环境 修改名称 如果不用yaml也可以用 conda create --name my_first_env python3.6 这个来指定 2.(base)变(…

海思3516DV500下的目标识别算法运行评估,包含yolov7,yolov8

目前在3516DV500下&#xff0c;自己训练的模型的评估实测结果。根据实际模型会有些许差异。 涉及到技术细节的部分因为商业用途&#xff0c;有部分省略。如需相关技术服务项目合作可私信联系。 我司推出的目标识别跟踪模块&#xff0c;支持热红外、可见光主流多光谱视频输入与目…

LCR 090. 打家劫舍 II(leetcode)动态规划

文章目录 前言一、题目分析二、算法原理1.状态表示2.状态转移方程3.初始化4.填表顺序5.返回值是什么 三、代码实现总结 前言 在本文章中&#xff0c;我们将要详细介绍一下LeetcodeLCR 090. 打家劫舍 II。采用动态规划解决&#xff0c;这是一道经典的多状态dp问题 一、题目分析…

微前端 -- wujie 预加载和原理 无界传参

目录 wujie 预加载和原理 原理解析 MessageChannel 无界传参 1.全局变量 2.Props 3.event bus wujie 预加载和原理 提前把无界实例创建好 runPreload 赋值给sandbox.preload 预先加载好 startApp 判断是否有preload 需要从wujie的实例导出preloadApp,参数跟startApp 一…

Grad-CAM原理

这篇是我对哔哩哔哩up主 霹雳吧啦Wz 的视频的文字版学习笔记 感谢他对知识的分享 只要大家一提到深度学习 缺乏一定的解释性 比如说在我们之前讲的分类网络当中 网络它为什么要这么预测 它针对每个类别所关注的点在哪里呢 在great cam这篇论文当中呢 就完美的解决了在cam这篇论…

《文存阅刊》期刊发表简介

《文存阅刊》以“深研文化创新&#xff0c;崇尚科学真理&#xff0c;坚持双百方针&#xff0c;打造学术精品”为办刊宗旨&#xff0c;涵盖艺术、文学、社科等多项内容&#xff0c;适应了文化市场需求&#xff0c;很好的回应了广大文化理论工作者的关切&#xff0c;为下一步打造…

QMenu风格设计qss+阴影

Qt的菜单经常在软件开发中用到&#xff0c;默认的菜单效果都不符合设计师的要求&#xff0c;本篇介绍QMenu菜单的风格设计&#xff0c;包括样式表和阴影。 1.QMenu样式表的设计 首先看一个默认的菜单 void QGraphicsDropShadowEffectDemo::slotShowDialog() {qDebug() <&l…

机器学习第15天:GBDT模型

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 ​​ 文章目录 GBDT模型介绍 Boosting 残差 GBDT的缺点 python代码实现 代码 模型参数解释 结语 GBDT模型介绍 GBDT&#xff08;Gradient Boos…