基于stm32移植使用u8g2 库

news2024/11/17 7:22:16

前言

   前面我已经写了如何使用stm32 使用软件IIC的方法驱动OLED,但是其实我们可以有更简单的使用方法,对于SSD1306 这款OLED 显示屏来说,其实已经有开源库可以直接使用了,我们只需要将对应的库移植过来,做一些简单的修改,即可以使用。为了大家学习方面,这些文章也会在我的微信公众号同步,方便大家随时查看,欢迎大家扫码关注。

在这里插入图片描述
参考博客:https://www.cnblogs.com/frozencandles/p/16358483.html

1. 下载u8g2

https://github.com/olikraus/u8g2

2. 移植

(1) 我们使用的环境是stm32,以c语言开发为主,所以我们将csrc 拷贝到自己的stm32的工程下面,因为我们的stm32 flash 有限,所以我们需要删除开源库中使用不到的一些东西。
例如,本次使用的是 128x64 的 SSD1306 屏幕,那么只需要保留 u8x8_d_ssd1306_128x64_noname.c 文件,删除其它类似的文件即可。
同时还需要精简 u8g2_d_setup.c 和 u8g2_d_memory.c 中 U8g2 提供的驱动兼容。

在 u8g2_d_setup.c 中,只需要保留 u8g2_Setup_ssd1306_i2c_128x64_noname_f() 这一个函数即可。注意,该文件内有几个命名类似的函数:命名中无 i2c 的是 SPI 接口驱动的函数,需要根据接口选择;以 1 结尾的函数代表使用的缓存空间为 128 字节,以 2 结尾的函数代表使用的缓存为 256字节,类似以 f 结尾的函数代表使用的缓存为 1024 字节。

u8g2_d_memory.c 文件也是同理,它需要根据 u8g2_d_setup.c 中的调用情况决定用到哪些函数。由于 u8g2_Setup_ssd1306_i2c_128x64_noname_f() 函数只用到 u8g2_m_16_8_f() 这一个函数,因此只需要保留它,其余函数全部删除即可。

还有一处必要的精简是字体文件 u8x8_fonts.c 和 u8g2_fonts.c ,尤其是 u8g2_fonts.c ,该文件提供了包括汉字在内的几万个文字的多种字体,仅源文件就有 30MB ,编译后占据的内存非常大。

(2) 提供一个模拟的时序函数:


uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
	u32 n = 0;
    switch (msg)
    {
    case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
        __NOP();
        break;
    case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
        for (n = 0; n < 320; n++)
        {
            __NOP();
        }
        break;
    case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
		delay_ms(arg_int);
        break;
    case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
		delay_us(5);
        break;                    // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
    case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
        if(arg_int == 1) 
        {
            GPIO_SetBits(IIC_GPIO_Port, SCL_Pin);
        }
        else if(arg_int == 0)
        {
            GPIO_ResetBits(IIC_GPIO_Port, SCL_Pin);  
        }  
        break;                    // arg_int=1: Input dir with pullup high for I2C clock pin
    case U8X8_MSG_GPIO_I2C_DATA:  // arg_int=0: Output low at I2C data pin
        if(arg_int == 1) 
        {
            GPIO_SetBits(IIC_GPIO_Port, SDA_Pin);
        }
        else if(arg_int == 0)
        {
            GPIO_ResetBits(IIC_GPIO_Port, SDA_Pin);  
        } 
        break;                    // arg_int=1: Input dir with pullup high for I2C data pin
    case U8X8_MSG_GPIO_MENU_SELECT:
        u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);
        break;
    case U8X8_MSG_GPIO_MENU_NEXT:
        u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);
        break;
    case U8X8_MSG_GPIO_MENU_PREV:
        u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);
        break;
    case U8X8_MSG_GPIO_MENU_HOME:
        u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);
        break;
    default:
        u8x8_SetGPIOResult(u8x8, 1); // default return value
        break;
    }
    return 1;
}

(3) 接下来就可以愉快的使用了

	
	void draw(u8g2_t *u8g2)
{ 
	u8g2_ClearBuffer(u8g2); 
	
    u8g2_SetFontMode(u8g2, 1); 							
    u8g2_SetFont(u8g2, u8g2_font_unifont_t_devanagari);
	
	u8g2_DrawStr(u8g2,1,30,"name:lxy");
}

int main()
{
	u8g2_t u8g2;                                                                                    
	u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay); 
	 u8g2_InitDisplay(&u8g2);                                                                         
	 u8g2_SetPowerSave(&u8g2, 0);  
	 u8g2_ClearBuffer(&u8g2);	

      while(1)
    {
        u8g2_FirstPage(&u8g2);
        do
     {
             draw(&u8g2);
       } while (u8g2_NextPage(&u8g2));
     }

}
	

···

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

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

相关文章

单片机课程设计——基于C51电子密码锁(源代码)

本设计是基于AT89C51单片机的电子密码锁设计&#xff0c;实现电子密码锁的基本功能。我们这里实现的是硬件仿真&#xff0c;关于软件仿真可以参考其他人的文章。 单片机课程设计--基于C51电子密码锁 效果展示 我们先来看效果展示&#xff0c;公主王子请看视频&#xff1a; 课…

【Spring总结】注解开发

本篇讲的内容主要是基于Spring v2.5的注解来完成bean的定义 之前都是使用纯配置的方式来定义的bean 文章目录 前言1. Spring v2.5 注解开发定义bean第一步&#xff1a;在需要定义的类上写上注解Component第二步&#xff1a;在Spring Config中定义扫描包第三步&#xff1a;主方法…

java springboot 在测试类中声明临时Bean对象

上文 java springboot在当前测试类中添加临时属性 不影响application和其他范围 中 我们讲了怎么在测试类中设置临时属性 但是 如果我们想设置临时的Bean呢&#xff1f; 其实做过几个项目的人都会理解 我们很多功能 需要一些第三方bean才能完成 那么 我们可能存在需要用第三方b…

图书管理系统(图文详解,附源码)

前言&#xff1a;本文旨在用面向对象的思想编程实现图书管理系统&#xff0c;功能包括增删查找&#xff0c;完整源码放在文末&#xff0c;大家有需自取 目录 一.整体框架 二.书籍和书架 书籍(Book) 书架(BookRack) 三.对书籍的相关操作 操作接口(IOperation) 新增图书(A…

项目点使用Redis作为缓存技术-自用

在spring boot项目中&#xff0c;使用缓存技术只需在项目中导入相关缓存技术的依赖包&#xff0c;并在启动类上使用EnableCaching开启缓存支持即可。 例如&#xff0c;使用Redis作为缓存技术&#xff0c;只需要导入Spring data Redis的maven坐标即可。 描述 使用Redis缓存高频数…

WSA子系统(一)

WSA子系统安装教程 Windows Subsystem for Android (WSA) 是微软推出的一项功能&#xff0c;它允许用户在 Windows 11 上运行 Android 应用程序。通过在 Windows 11 上引入 WSA&#xff0c;用户可以在其 PC 上轻松运行 Android 应用程序&#xff0c;从而扩展了用户的应用程序选…

RobotFramework之用例执行时添加命令行参数(十三)

学习目录 引言 标签tag 设置变量 随机执行顺序 设置监听器 输出日志目录和文件 引言 Robot Framework 提供了许多命令行选项&#xff0c;可用于控制测试用例的执行方式以及生成的输出。本节介绍一些常用的选项语法。 标签tag 之前文章我们介绍过&#xff0c;在测试套件…

Leetcode经典题目之“双指针交换元素“类题目

1 LC 27. 移除元素 class Solution {public int removeElement(int[] nums, int val) {int nnums.length;int s0;for(int i0;i<n;i){// 只有不等于目标值的时候才会进行交换&#xff0c;然后移动s指针if(nums[i]!val){swap(nums,i,s);}}return s;}void swap(int[]nums, int…

(数据结构)算法的时间复杂度

注意语句频度和时间复杂度的区别&#xff0c;语句频度是指语句执行的次数&#xff0c;不可以像时间复杂度一样近似次数和省略常数项

在线识别二维码工具

具体请前往&#xff1a;在线二维码识别解码工具--在线识别并解码二维码网址等内容

FlinkCDC数据实时同步Mysql到ES

考大家一个问题&#xff0c;如果想要把数据库的数据同步到别的地方,比如es,mongodb,大家会采用哪些方案呢&#xff1f; ::: 定时扫描同步&#xff1f; 实时日志同步? 定时同步是一个很好的方案&#xff0c;比较简单&#xff0c;但是如果对实时要求比较高的话&#xff0c;定…

HFSS螺旋线圈的设计与仿真

HFSS螺旋线圈的设计与仿真 HFSS中设计螺旋线圈的方法&#xff1a;参考文献&#xff1a; HFSS中设计螺旋线圈的方法&#xff1a; 打开软件Ansys Eletronics Desktop 2022 R1&#xff0c; 建立工程&#xff0c; File/New 插入HFSS设计&#xff0c; Project/Insert HFSS Design …

【Spring】之初识

未来的几周时间&#xff0c;大概率我会更新一下Spring家族的一些简单知识。而什么是Spring家族&#xff0c;好多同学还不是很清楚&#xff0c;我先来简单介绍一下吧&#xff1a; 所谓Spring家族&#xff0c;它其实就是一个框架&#xff0c;是基于Servlet再次进行封装的内容。为…

大模型的交互能力

摘要&#xff1a; 基础大模型显示出明显的潜力&#xff0c;可以改变AI系统的开发人员和用户体验&#xff1a;基础模型降低了原型设计和构建AI应用程序的难度阈值&#xff0c;因为它们在适应方面的样本效率&#xff0c;并提高了新用户交互的上限&#xff0c;因为它们的多模式和生…

笔记55:长短期记忆网络 LSTM

本地笔记地址&#xff1a;D:\work_file\DeepLearning_Learning\03_个人笔记\3.循环神经网络\第9章&#xff1a;动手学深度学习~现代循环神经网络 a a a a a a a a a

jbase打印完善

上一篇实现了粗略的打印元素绘制协议&#xff0c;并且写了打印示例和导出示例&#xff0c;趁着空隙时间完善一下打印。 首先元素构造函数默认初始化每个字段值 package LIS.Core.Dto;/*** 打印约定元素*/ public class PrintElement {/*** 元素类型*/public String PrintType…

OpenCV快速入门:图像形态学操作

文章目录 前言一、图像形态学基础1.1 背景介绍1.2 像素距离1.2.1 什么是像素距离&#xff1f;1.2.2 常见的像素距离度量方法1.2.3 计算像素距离的代码实现 1.3 图像连通性1.3.1 什么是图像连通性&#xff1f;1.3.2 连通类型1.3.3 连通组件标记1.3.4 连通性在图像处理中的应用 1…

2023.11.18 每日一题(AI自生成应用)【C++】【Python】【Java】【Go】 动态时间序列分析

目录 一、编程挑战&#xff1a;动态时间序列分析 实际应用&#xff1a; 实现提示&#xff1a; 二、实现 1. C 2. Python 3. JAVA 4. Go 一、编程挑战&#xff1a;动态时间序列分析 问题描述&#xff1a; 假设你是一名软件工程师&#xff0c;需要开发一个应用来分析和预…

内容运营策略:个性化推荐

一、推荐系统流程 典型的推荐系统包括3个部分&#xff0c;即召回层&#xff08; Recall )、排序层&#xff08; Rank )和重排层&#xff08; ReRank )。 1&#xff0e;召回层&#xff08; Recall ) 召回层主要是从全量库中首先获取用户可能感兴趣的候选集&#xff0c;是推荐系…

「Tech初见」对epoll的理解

一、Motivation 通常&#xff0c;操作系统会为每个进程划分一个时间片的&#xff0c;在这个时间片内进程可以合法占有 cpu 进行一些计算任务。并当时间片结束后自动退回至就绪状态待命&#xff0c;等待下一次的调度 但是&#xff0c;有一种情况会使进程提前&#xff08;时间片…