MM32F3273G8P火龙果开发板MindSDK开发教程17 -U8g2库的移植

news2024/12/22 22:25:19

MM32F3273G8P火龙果开发板MindSDK开发教程17 -U8g2 OLED库的移植

1、U8g2简介

手头正好有一块0.96寸的OLED屏,驱动芯片为ssd1306,心想怎么才能显示更为炫彩的图像。无意间,接触到U8g2图形库,遂决定将其移植到自己的工程中。
U8g2 是一个用于嵌入式设备的单色图形库。U8g2支持单色OLED和LCD,并支持如SSD1306等多种类型的OLED驱动。
github下载地址

2、准备工作

我这块屏是i2c接口的,u8g2即支持软件模拟i2c,也支持硬件i2c。之前的工程里关于PC6 PC7软硬件i2c都有适配,这里用模拟i2c,因为简单,bug少啊。
软件i2c pc6 pc7gpio的配置代码如下:

void BOARD_I2C1_Init(void)
{
#if I2C_MODE == USE_HARD_I2C    
    GPIO_Init_Type gpio_init;
    /* PC6 - I2C1_SCL. */
    gpio_init.Pins  = GPIO_PIN_6;
    gpio_init.PinMode  = GPIO_PinMode_AF_OpenDrain;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &gpio_init);
    GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_4);

    /* PC7 - I2C1_SDA. */
    gpio_init.Pins  = GPIO_PIN_7;
    gpio_init.PinMode  = GPIO_PinMode_AF_OpenDrain;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &gpio_init);
    GPIO_PinAFConf(GPIOC, gpio_init.Pins, GPIO_AF_4);

    /* Setup I2C initialization values. */
    I2C_Master_Init_Type i2c_init;
    i2c_init.ClockFreqHz = CLOCK_APB1_FREQ;
    i2c_init.BaudRate = I2C_BaudRate_100K;

    /* Initialize I2C master. */
    I2C_InitMaster(I2C1, &i2c_init);

    /* The target device address needs to be configured before enabling. */
    I2C_SetTargetAddr(I2C1, MSA311_I2CADDR_DEFAULT_7);

    /* Enable I2C. */
    I2C_Enable(I2C1, true);

#elif I2C_MODE == USER_SW_I2C 
    GPIO_Init_Type gpio_init;
    gpio_init.Pins  = SWI2C1_SCL_PIN;
    gpio_init.PinMode  = GPIO_PinMode_Out_OpenDrain;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(SWI2C1_SCL_PORT, &gpio_init);
    GPIO_PinAFConf(SWI2C1_SCL_PORT, gpio_init.Pins, GPIO_AF_15); /* disable the alternative functions. */

    /* PC7 - I2C1_SDA. */
    gpio_init.Pins  = SWI2C1_SDA_PIN;
    gpio_init.PinMode  = GPIO_PinMode_Out_OpenDrain;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(SWI2C1_SDA_PORT, &gpio_init);
    GPIO_PinAFConf(SWI2C1_SDA_PORT, gpio_init.Pins, GPIO_AF_15); /* disable the alternative functions. */

    SWI2C1_SDA_HIGH; 
	SWI2C1_SCL_HIGH;
#endif    
}

.h文件

#define I2C_MODE        USER_SW_I2C

#if I2C_MODE == USER_SW_I2C
// PC6 scl PC7 sda
#define SWI2C1_SCL_PORT     GPIOC
#define SWI2C1_SCL_PIN      GPIO_PIN_6
#define SWI2C1_SCL_HIGH 	GPIO_WriteBit(SWI2C1_SCL_PORT,SWI2C1_SCL_PIN,1u)
#define SWI2C1_SCL_LOW 		GPIO_WriteBit(SWI2C1_SCL_PORT,SWI2C1_SCL_PIN,0u)

#define SWI2C1_SDA_PORT     GPIOC
#define SWI2C1_SDA_PIN      GPIO_PIN_7
#define SWI2C1_SDA_HIGH 	GPIO_WriteBit(SWI2C1_SDA_PORT,SWI2C1_SDA_PIN,1u)
#define SWI2C1_SDA_LOW		GPIO_WriteBit(SWI2C1_SDA_PORT,SWI2C1_SDA_PIN,0u)
#define SWI2C1_SDA_READ     GPIO_ReadInDataBit(SWI2C1_SDA_PORT,SWI2C1_SDA_PIN)
#define BIT0     0x01
#define BIT7     0x80
#endif

注意将gpio设置为开漏模式。

3、移植u8g2

将下载的u8g2解压,我们只需要csrc文件夹的文件,其余可以先不关注。
由于u8g2支持的驱动种类繁多,所以我们只需要找到我们对应的驱动文件即可。

a、我们的驱动芯片是ssd1306,128*64,所以我们对应的驱动文件为u8x8_d_ssd1306_128x64_noname.c,其余以u8xu8_d_xxx命名的文件都全部是删除掉。

删掉后的代码视图:
在这里插入图片描述

b、精剪u8g2_d_setup.c文件,只保留u8g2_Setup_ssd1306_i2c_128x64_noname_f这一个函数。

如图:
在这里插入图片描述

c、精剪u8g2_d_memory.c,因为u8g2_Setup_ssd1306_i2c_128x64_noname_f,只调用了u8g2_m_16_8_f函数,所以u8g2_d_memory.c只保留着一个函数。

如图:
在这里插入图片描述

d、添加u8x8_gpio_and_delay函数,软件模拟i2c按照下面这样填充这个函数

uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
    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 (uint16_t n = 0; n < 320; n++)
                __NOP();
            break;
        case U8X8_MSG_DELAY_MILLI:   // delay arg_int * 1 milli second
            BOARD_Delay1Ms(1);
            break;
        case U8X8_MSG_DELAY_I2C:     // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
            BOARD_Delay1Us(3);
            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
            arg_int ? GPIO_WriteBit(SWI2C1_SCL_PORT,SWI2C1_SCL_PIN,1u) : GPIO_WriteBit(SWI2C1_SCL_PORT,SWI2C1_SCL_PIN,0u);  
            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
            arg_int ? GPIO_WriteBit(SWI2C1_SDA_PORT,SWI2C1_SDA_PIN,1u) : GPIO_WriteBit(SWI2C1_SDA_PORT,SWI2C1_SDA_PIN,0u);  
            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;
}

主要是延时函数,以及scl sda对应的gpio的控制。

e、最后将裁减的文件放到device/u8g2文件下,并在Makefile里添加u8g2的编译选项。

4、u8g2的使用

void u8g2Init(u8g2_t *u8g2)
{
    u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay);  // 初始化 u8g2 结构体
    u8g2_InitDisplay(u8g2); // 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
    u8g2_SetPowerSave(u8g2, 0); // 打开显示器
    u8g2_ClearBuffer(u8g2);
}

void draw(u8g2_t *u8g2)
{
    u8g2_SetFontMode(u8g2, 1); /*字体模式选择*/
    u8g2_SetFontDirection(u8g2, 0); /*字体方向选择*/
    u8g2_SetFont(u8g2, u8g2_font_inb24_mf); /*字库选择*/
    u8g2_DrawStr(u8g2, 0, 20, "U");
    
    u8g2_SetFontDirection(u8g2, 1);
    u8g2_SetFont(u8g2, u8g2_font_inb30_mn);
    u8g2_DrawStr(u8g2, 21,8,"8");
        
    u8g2_SetFontDirection(u8g2, 0);
    u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
    u8g2_DrawStr(u8g2, 51,30,"g");
    u8g2_DrawStr(u8g2, 67,30,"\xb2");
    
    u8g2_DrawHLine(u8g2, 2, 35, 47);
    u8g2_DrawHLine(u8g2, 3, 36, 47);
    u8g2_DrawVLine(u8g2, 45, 32, 12);
    u8g2_DrawVLine(u8g2, 46, 33, 12);
  
    u8g2_SetFont(u8g2, u8g2_font_4x6_tr);
    u8g2_DrawStr(u8g2, 1,54,"github.com/olikraus/u8g2");
}

main函数调用:

// BOARD_InitPins();
	u8g2_t u8g2;
    u8g2Init(&u8g2);	

	while(1)
	{
		// Msa311_GetXYZData();
        // BOARD_Delay1Ms(1000);
		u8g2_FirstPage(&u8g2);
		do
		{
				draw(&u8g2);
		} while (u8g2_NextPage(&u8g2));
	}	

烧录后,可以看见u8g2官方的logo了。

5、现象

在这里插入图片描述

6、代码

移植好的代码

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

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

相关文章

2023软件测试面试避坑指南

今年2023整体IT行业不景气&#xff0c;大厂小厂裁员不断&#xff0c;因岗位稀缺&#xff0c;匹配性&#xff0c;竞争大&#xff0c;被裁以后面临房贷、车贷等压力&#xff0c;不得不看下银行卡&#xff0c;还能够支撑多久&#xff0c;得赶紧地找下一家&#xff0c;但偏偏事与愿…

深入学习 Mybatis 的四大组件源码

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…

JavaScript之ES6高级语法(一)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 ES6高级语法&#xff08;一&#xff09; 前言一、垃圾回收机制&#xff08;Garbage Collection&#xff09;1.1、引用计数法…

看病排队问题

目录 一、代码 二、功能函数介绍 三、运行截图 一、代码 #define _CRT_SECURE_NO_WARNINGS 1//不用VS删除这一行 #include<stdio.h> #include<stdlib.h> struct LinkQueue {int data;struct LinkQueue* next; };struct Node {LinkQueue* frount;LinkQueue* re…

docker无法启动 -> 缺少libseccomp

systemctl status docker.servicejournalctl -u dockeryum install -y libseccomplibseccomp是一个用于Linux操作系统的安全计算模式&#xff08;seccomp&#xff09;的用户空间库。seccomp是一种Linux内核特性&#xff0c;允许限制进程可以执行的系统调用&#xff0c;以增加应…

C语言中的基本数据类型

C语言中的基本数据类型分别为以下几种 整型、浮点型、字符类型 整型又分为整型int、短整型short、长整型long 浮点型分为单精度浮点型float、双精度浮点型double 1、短整型short 2.整型 3.长整型 短整型、长整型、整形都是表示整形的&#xff0c;并且输出结果也都为10&…

教你如何批量关闭窗口,省时又省力!

哈喽哈喽&#xff0c;大家好&#xff0c;今天我们来分享一个小功能。 在实际的应用场景中&#xff0c;我们可能需要打开多个窗口&#xff0c;在关闭窗口时&#xff0c;逐个关闭窗口可能比较繁琐&#xff0c;而且有些窗口虽然不再显示了&#xff0c;但可能是隐藏的。在这种情况…

Flutter 库:强大的工具及扩展——nb_utils

Flutter 库&#xff1a;强大的工具及扩展——nb_utils 文章目录 Flutter 库&#xff1a;强大的工具及扩展——nb_utils一、概述1、简介2、功能3、官方资料 二、基本使用1、安装2、基本使用第一步&#xff1a;在 main.dart 中初始化第二步&#xff1a;在您的 MaterialApp 或 Cup…

java的字符输入流

字符流的底层也是字节流。字符流字节流字符集。 特点是输入流一次读一个字节&#xff0c;遇到中文时&#xff0c;一次读多个字节&#xff08;读多少个与字符集有关&#xff09;&#xff1b;输出流底层会把数据按照指定的编码方式进行编码&#xff0c;变成字节再写到文件中。 字…

15个提效的设计类AI生成工具推荐

最近越来越多的AI工具如雨后春笋般涌现。我相信很多设计师会开始使用人工智能工具来帮助我们提高工作效率。 本文整理了15种易于使用的设计类AI工具 即时 AI 即时 AI 是通过自然语言描述&#xff0c;快速生成可编辑的 UI 设计稿的设计工具。 输入文字描述后&#xff0c;即可…

C语言:使用函数完成整型数组的打印、元素逆置、初始化

题目&#xff1a; 创建一个整形数组&#xff0c;完成对数组的操作 1. 实现 函数init() -- 初始化数组为全0 2. 实现 函数print() -- 打印数组的每个元素 3. 实现 函数reverse() -- 函数完成数组元素的逆置 要求&#xff1a;自己设计以上函数的参数&#xff0c;返回值。 思路&a…

AB32VG1:SDK_AB53XX_V061(4)蓝牙音频测试笔记

文章目录 1. 淘宝上两种开发板&#xff0c;有一种的蓝牙功能不正常2. 蓝牙音频测试2.1 《config.h》和《Boombox.setting》两个配置以哪个为准2.2 codeblocks更换链接库2.2.1 这样进入build options是错的2.2.2 build options正确打开方式 2.3.编译工程&#xff0c;下载运行2.3…

kafka 报错 - Cannot assign requested address

背景 在华为云服务器上跑了 zookeeper 和 kafka 的 broker&#xff0c;想内外网分流&#xff0c;重点就是做不到从外网去消费&#xff0c;比如用自己的 windows 笔记本去消费。 配置 server.properties 的 listener 为 broker 所在机子的的内网 IP 后&#xff0c;终于能 star…

Scala环境搭建及安装

salca环境搭建 由于scala是基于java来开发的, 编写的java类可以使用javac命令编译成.class文件被JVM加载到内存中执行 ! 那么scala可以通过scalac命令将编写的scala文件编译成.class文件一样被JVM加载到内存中,因此Scala是运行在JVM平台上的&#xff0c;所以安装Scala之前要安装…

【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之SpringBoot整合众多日志管理系统服务starter-logging

全方位攻克你的技术盲区之SpringBoot整合众多日志管理系统服务starter-logging 前提介绍Spring默认日志文件Spring的日志配置参数logging.levelmaven配置properties文件yaml文件 logging.fileapplication.yml中配置 logging.pathapplication.properties配置application.yml配置…

基于DBACAN的道路轨迹点聚类

目录 前言道路栅格化轨迹聚类参考资料 前言 很多针对道路轨迹的挖掘项目前期都需要对道路进行一段一段的分割成路段&#xff0c;然后对每一个路段来单独进行考察&#xff0c;如设定路段限速标识&#xff0c;超速概率等&#xff0c;如何对道路进行划分&#xff0c;其实是一个很…

华为OD机试真题 JavaScript 实现【滑动窗口】【2023 B卷 100分】,附详细解题思路

一、题目描述 有一个N个整数的数组&#xff0c;和一个长度为M的窗口&#xff0c;窗口从数组内的第一个数开始滑动直到窗口不能滑动为止&#xff0c;每次窗口滑动产生一个窗口和&#xff08;窗口内所有数和和&#xff09;&#xff0c;求窗口滑动产生的所有窗口和的最大值。 二…

python: read excel

""" Insurance。py edit&#xff1a; geovindu,Geovin Du,涂聚文 date 2023-06-13 保险类 """import sys import osclass Insurance:"""保险类"""def __init__(self, InsuranceName, InsuranceCost, IMonth):&quo…

STM32使用QUADSPI读写外部Nor Flash(以W25Q64为例)

使用QUADSPI读写W25Q64 QUADSPI介绍硬件连接双闪存模式禁止双闪存模式使能 QUADSPI命令序列指令阶段地址阶段交替字节阶段空指令周期阶段数据阶段 QUADSPI主要信号接口协议模式单线SPI模式双线SPI模式四线SPI模式 使用QUADSPI操作W25Q64发送命令函数状态轮询函数读ID函数QUADSP…

应用案例 | FG-200:通过Modbus将FF H1设备集成到DCS系统

一 背景 FOUNDATION Fieldbus&#xff08;FF&#xff09;协议是一种现代化的数字通信协议&#xff0c;其中FF H1协议在大型的化工、电力、石油等流程工业领域得到了广泛应用。由于FF H1协议具有诸多优势&#xff0c;例如高度可靠性、高速数据传输、强大的诊断能力和灵活的设备…