熟悉u8g2图形库C语言函数

devtools/2024/12/23 1:11:57/

前言:

前面我们已经成功移植了U8g2的图形库(0.96寸OLED):手把手移植U8g2图形库,这个文章主要熟悉u8g2图形库的常用C语言函数!需要移植的资料的可以关注一波评论区评论,我看到了就会给你发哦!这里主要是介绍一部分函数的使用说明和使用这个强大的库制作一个多功能智能手表!

手表的基本功能(部分外设传感器还没有到):自己成功移植好了库后,可以结合学习的32板子自己去做一点这种小玩具玩玩,也挺有趣的!

基于STMF103的多功能手表玩具(残缺版)

一、OLED的初始化

1.1、初始化与硬件相关的配置函数

函数:
void u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8g2_gpio_and_delay_stm32);
参数:
u8g2 : u8g2 结构体
U8G2_Rx: 屏幕的方向
U8G2_R0(正常方向) U8G2_R1(顺时针旋转90°) U8G2_R2 U8G2_R3(顺时针旋转180°)
U8G2_MIRROR 左右镜像
U8G2_MIRROR_VERTICAL 上下镜像
其他两个参数使用可以看看 手把手移植U8g2库

1.2、u8g2_InitDisplay——OLED显示初始化

函数:
void u8g2_InitDisplay(u8g2_t *u8g2);

作用:写入关键显示参数,对显示初始化

1.3、u8g2_setPowerSave——OLED打开与关闭

函数:

void u8g2_setPowerSave(u8g2_t *u8g2, uint8_t is_enable);

参数:

is_enable:

1:关闭OLED

0:打开OLED

⭐1.4、缓存区的使用

须知:在OLED上显示一个物体,不是直接给OLED发送数据的,它们中间其实有一个中介——缓存区,首先将数据存进缓存区里面,然后在使用函数发送给OLED的!

清除缓存区:

void u8g2_ClearBuffer(u8g2_t *u8g2);

发送缓存区的数据给OLED:

void u8g2_SendBuffer(u8g2_t *u8g2);

清屏函数:

void u8g2_ClearDisplay(u8g2_t *u8g2);作用和一次性使用下面两个函数一致:
void u8g2_ClearBuffer(u8g2_t *u8g2);
void u8g2_SendBuffer(u8g2_t *u8g2);

1.5、使用以上函数对OLED进行初始化和函数配置

 
#define u8         unsigned char  // ?unsigned char ????
#define MAX_LEN    128  //
#define OLED_ADDRESS  0x78 // oled
#define OLED_CMD   0x00  // 
#define OLED_DATA  0x40  // /* 填空初始化u8x8_byte_hw_i2c函数 */
uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{/* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */static uint8_t buffer[128];static uint8_t buf_idx;uint8_t *data;switch (msg){case U8X8_MSG_BYTE_INIT:{/* add your custom code to init i2c subsystem */MX_I2C2_Init(); //I2C初始化}break;case U8X8_MSG_BYTE_START_TRANSFER:{buf_idx = 0;}break;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_END_TRANSFER:{if (HAL_I2C_Master_Transmit(&hi2c2, OLED_ADDRESS, buffer, buf_idx, 1000) != HAL_OK)return 0;}break;case U8X8_MSG_BYTE_SET_DC:break;default:return 0;}return 1;
}/* 填空初始化u8x8_gpio_and_delay函数 */
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 secondsfor (uint16_t n = 0; n < 320; n++){__NOP();}break;case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli secondHAL_Delay(1);break;case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHzTims_delay_us(5);break;                    // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25uscase U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pinbreak;                    // arg_int=1: Input dir with pullup high for I2C clock pincase U8X8_MSG_GPIO_I2C_DATA:  // arg_int=0: Output low at I2C data pinbreak;                    // arg_int=1: Input dir with pullup high for I2C data pincase 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 valuebreak;}return 1;
}
void u8g2Init(u8g2_t *u8g2)
{u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_gpio_and_delay); // 初始化u8g2 结构体u8g2_InitDisplay(u8g2);   	 //对缓存进行初始化                                                // 初始化u8x8_gpio_and_delay函数u8g2_SetPowerSave(u8g2, 0);   //wake up 屏幕                                                      // 初始化u8x8_byte_hw_i2c函数u8g2_ClearBuffer(u8g2);   //清除缓存区                                                        //对驱动进行初始化
}

二、入门函数显示各种东西

通过以上的初始化就可以正式学习函数的使用,去如何显示各种各样的东西了!

2.1、u8g2_DrawXBMP——显示一张图片

函数:
void u8g2_DrawXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w,
u8g2_uint_t h, const uint8_t *bitmap);
参数:
u8g2 : u8g2 结构体 (C interface only).
x: 横坐标
y: 纵坐标
cnt: 宽度
h: 高度 .
bitmap: 指向取模数组的指针
使用例子:
首先使用下面的软件提取出 数组
 

软件设置如下:(设置不对会显示很乱)

代码:

static const unsigned char mmap[] U8X8_PROGMEM= 
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xC0,0xC7,0x07,0x00,0x40,0x4C,0x0C,0x00,
0x40,0x48,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,
0x00,0x84,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x88,0x00,0x00,0x00,0x98,0x00,0x00,
0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,/*"未命名文件",0*/
};u8g2_DrawXBMP(&u8g2, 0, 0, 25, 25, mmap);u8g2_SendBuffer(&u8g2);//发送缓冲区的数据给OLED

显示效果:

2.2、u8g2_DrawBox() —— 画实心矩形

/*** 画实心矩形,左上角坐标为(x,y),宽度为w,高度为h* @param x 左上角的x坐标* @param y 左上角的y坐标* @param w 方形的宽度* @param h 方形的高度*/
void u8g2_DrawBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
u8g2_DrawBox(&u8g2,3,7,25,15);

2.3、u8g2_DrawCircle() —— 画空心圆

函数说明:

/*** 画空心圆,圆心坐标为(x0,y0),半径为rad* @param x0 圆点的x坐标* @param y0 圆点的y坐标* @param rad 圆形的半径* @param opt 圆形选项*        U8G2_DRAW_ALL 整个圆*        U8G2_DRAW_UPPER_RIGHT 右上部分的圆弧*        U8G2_DRAW_UPPER_LEFT  左上部分的圆弧*        U8G2_DRAW_LOWER_LEFT  左下部分的圆弧*        U8G2_DRAW_LOWER_RIGHT 右下部分的圆弧*        选项可以通过 | 操作符来组合*/
void u8g2_DrawCircle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)

示例:

u8g2_DrawCircle(&u8g2,20,25,10,U8G2_DRAW_ALL);

2.4、u8g2_DrawDisc() —— 画实心圆

/*** 画实心圆,圆心坐标为(x0,y0),半径为rad* @param x0 圆点的x坐标* @param y0 圆点的y坐标* @param rad 圆形的半径* @param opt 圆形选项*        U8G2_DRAW_ALL 整个圆*        U8G2_DRAW_UPPER_RIGHT 右上部分的圆弧*        U8G2_DRAW_UPPER_LEFT  左上部分的圆弧*        U8G2_DRAW_LOWER_LEFT  左下部分的圆弧*        U8G2_DRAW_LOWER_RIGHT 右下部分的圆弧*       选项可以通过 | 操作符来组合*/
void u8g2_DrawDisc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)

2.5、u8g2_DrawFrame() —— 画空心矩形

/*** 画空心方形,左上角坐标为(x,y),宽度为w,高度为h* @param x 左上角的x坐标* @param y 左上角的y坐标* @param w 方形的宽度* @param h 方形的高度*/
void u8g2_DrawFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)

2.6、u8g2_DrawHLine() —— 绘制水平线

/*** 绘制水平线* @param x 左上角的x坐标* @param y 左上角的y坐标* @param w 水平线的长度*/void u8g2_DrawHLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len)

2.7、u8g2_DrawLine() —— 两点之间绘制线

/*** 绘制线,从坐标(x0,y0) 到(x1,y1)* @param x0 端点0的x坐标* @param y0 端点0的y坐标* @param x1 端点1的x坐标* @param y1 端点1的y坐标*/
void u8g2_DrawLine(u8g2_t *u8g2, u8g2_uint_t x1, u8g2_uint_t y1, u8g2_uint_t x2, u8g2_uint_t y2)

2.8、u8g2_DrawPixel() —— 绘制像素点

/*** 绘制像素点,坐标(x,y)* @param x 像素点的x坐标* @param y 像素点的y坐标* @Note 关联方法 setDrawColor*/
void u8g2_DrawPixel(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y)

2.9、u8g2_DrawRBox() —— 绘制圆角实心方形

/*** 绘制圆角实心方形,左上角坐标为(x,y),宽度为w,高度为h,圆角半径为r* @param x 左上角的x坐标* @param y 左上角的y坐标* @param w 方形的宽度* @param h 方形的高度* @param r 圆角半径*/
void u8g2_DrawRBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)

2.10、u8g2_DrawRFrame() —— 绘制圆角空心方形

/*** 绘制圆角空心方形,左上角坐标为(x,y),宽度为w,高度为h,圆角半径为r* @param x 左上角的x坐标* @param y 左上角的y坐标* @param w 方形的宽度* @param h 方形的高度* @param r 圆角半径*/
void u8g2_DrawRFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)

2.11、u8g2_DrawTriangle() —— 绘制实心三角形

/*** 绘制实心三角形,定点坐标分别为(x0,y0),(x1,y1),(x2,y2)*/
void u8g2_DrawTriangle(u8g2_t *u8g2, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)

2.12、u8g2_DrawVLine() —— 绘制竖直线

/*** 绘制竖直线* @param x 左上角坐标x* @param y 左上角坐标y* @param h 高度*/
void u8g2_DrawVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len)

2.14、部分图形显示效果

三、动态显示

3.1、u8g2_FirstPage/u8g2_NextPage — 绘制命令

/*** 绘制图像*/
void u8g2_FirstPage(u8g2_t *u8g2)
uint8_t u8g2_NextPage(u8g2_t *u8g2)
  • u8g2_FirstPage方法会把当前页码位置变成0;
  • 修改内容处于u8g2_FirstPageu8g2_NextPage之间,每次都是重新渲染所有内容;
  • 该方法消耗的ram空间,比u8g2_SendBuffer消耗的RAM空间要少;

示例:(进度条)

u8g2_FirstPage(&u8g2);
do
{u8g2_DrawBox(&u8g2,0,32,i++,15);HAL_Delay(50);
}while (u8g2_NextPage(&u8g2));

四、绘制字体函数

4.1、u8g2_SetFont()——设置字库

写字之前肯定要自己决定写什么字体呀!

原作者制作了挺多的库的,里面其中甚至还有支持外国语言!这里我就举例我会用的和常用的库!

不同的库就代表着字体的大小或者样式不同,还有语言不同,这个库是非常强大的,还是有很多值得去探究的!

其他的库就需要自己去探究了!

4.2、u8g2_DrawStr()——绘制字符串

参数:
u8g2 : u8g2 结构体(C interface only). x,y: 左下角起点坐标
*s: 字符串文本
返回值: 字符串的长度函数:
u8g2_uint_t u8g2_DrawStr(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *s);
u8g2_uint_t u8g2_DrawStrX2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *s);

使用例子:

u8g2_SetFont(&u8g2,u8g2_font_ncenB14_tr);//设置字库
u8g2_DrawStr(&u8g2,0,15,"Hello World!");//绘制你好世界
u8g2_SendBuffer(&u8g2);//发送缓冲区的数据给OLED

效果:

 4.3、u8g2_DrawUTF8() —— 绘制UTF8编码的字符

/*** 绘制UTF8编码的字符串* @param x 字符串在屏幕上的左下角x坐标* @param y 字符串在屏幕上的左下角y坐标* @param s 需要绘制的UTF-8编码字符串* @return 返回字符串的长度*/
u8g2_uint_t u8g2_DrawUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)u8g2_uint_t u8g2_DrawUTF8X2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *s);//双倍显示

使用该方法,有两个前提。首先是你的编译器需要支持UTF-8编码,对于绝大部分Arduino板子已经支持;其次,显示的字符串需要存为“UTF-8”编码,Arduino IDE上默认支持;

该方法需要依赖于fontMode(setFont)以及drawing Color,也就是说如果你传进来的字符串编码必须在font定义里面;

Keil v5 mdk 编译UTF8字符串报错的解决办法–no-multibyte-chars

使用例子:

u8g2_SetFont(&u8g2,u8g2_font_unifont_t_symbols);
u8g2_DrawUTF8(&u8g2,5, 20, "Snowman: ☃");

4.4、绘制数字

还是使用u8g2_DrawStr函数

具体实现:(记得包括头文件stdio.h)

void PrintVarFormat(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const uint8_t *font, short var)
{char var_buff[100];             //用来存ASCII码u8g2_SetFont(u8g2, font);       //设定字体sprintf(var_buff, "%4d", var);  //传递变量(十进制(占四格))u8g2_DrawStr(u8g2, x, y, var_buff); //显示
}for(uint8_t i=0;i<100;i++)
{u8g2_ClearBuffer(&u8g2); PrintVarFormat(&u8g2,63,31,u8g2_font_ncenB14_tr,i);HAL_Delay(1000);  u8g2_SendBuffer(&u8g2);	
} 

效果:

4.5、u8g2_DrawGlyph()——绘制有趣的图标

函数:

函数:u8g2_uint_t u8g2_DrawGlyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding);
u8g2_uint_t u8g2_DrawGlyphX2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding);说明:画图形式字符,8g2_uint_t u8g2_DrawGlyphX2()图形放大显示
参数:
u8g2 : u8g2 结构体(C interface only). x,y: 左下角坐标
encoding: 字形索引

例子:

u8g2_SetFont(&u8g2,u8g2_font_unifont_t_symbols);//
u8g2_DrawGlyph(&u8g2,30, 20, 0x2603);
u8g2_DrawGlyphX2(&u8g2,70,45, 0x2603);
u8g2_SendBuffer(&u8g2);

效果:

上面的数字号码,是根据这个图:

五、使用U8g2库显示众多图形效果

这里的代码是一个CSDN大佬博主的,我这里直接拿来使用了,原博主我找不到了,如果原博主看到了可以告诉我一下!

U8g2库常用函数驱动OLED显示效果


http://www.ppmy.cn/devtools/144536.html

相关文章

bestphp‘s revenge

bestphp’s revenge 知识点 php session反序列化 解题 <?php highlight_file(__FILE__); $b implode; call_user_func($_GET[f], $_POST); //参数二的位置固定为 $_POST 数组&#xff0c;我们很容易便想到利用 extract 函数进行变量覆盖&#xff0c;以便配合后续利用…

远程连接的功能以及种类(sshd)

1.ssh简介 ssh通过创建安全隧道来实现ssh客户端与服务器之间的连接&#xff0c; 它的主要用途是连接远程服务器然后在上面执行指令。 远程连接服务器&#xff1a;分享主机的运算能力 种类&#xff1a;明文传输&#xff1a;Telent RSH等 目前非常少用 加密传输&#xff1a;S…

解决 Ubuntu 20.04 上编译 OpenCV 3.2 时的类型不匹配错误

解决 Ubuntu 20.04 上编译 OpenCV 3.2 时的类型不匹配错误 make[2]: *** [modules/python3/CMakeFiles/opencv_python3.dir/build.make:329&#xff1a;modules/python3/CMakeFiles/opencv_python3.dir/__/src2/cv2.cpp.o] 错误 1 make[1]: *** [CMakeFiles/Makefile2:11856&a…

在M系列芯片的Mac上使用Uniapp开发的依赖安装指南

在M系列芯片的Mac上使用Uniapp开发的依赖安装指南 在基于M系列芯片&#xff08;例如M3、M4&#xff09;的Mac上进行Uniapp开发时&#xff0c;使用esbuild和rollup等依赖包时需要注意处理不同架构的支持。具体问题出现在darwin-arm64&#xff08;ARM架构&#xff09;和darwin-x…

[react]suspend 组件搭配路由组件时fallback不生效

用key即可解决, 为什么,因为suspend只会在首次加载时执行一次fallback <Suspense> – React 中文文档

中阳科技:从量化交易到智能金融的创新实践

量化交易的出现改变了传统金融市场的游戏规则&#xff0c;它通过算法驱动和数据分析实现了自动化、智能化的交易流程。作为这一领域的佼佼者&#xff0c;中阳科技专注于探索量化模型的创新&#xff0c;助力投资者在复杂的市场中获取竞争优势。 量化交易的优势剖析 量化交易依赖…

深入浅出支持向量机(SVM)

1. 引言 支持向量机&#xff08;SVM, Support Vector Machine&#xff09;是一种常见的监督学习算法&#xff0c;广泛应用于分类、回归和异常检测等任务。自1990年代初期由Vapnik等人提出以来&#xff0c;SVM已成为机器学习领域的核心方法之一&#xff0c;尤其在模式识别、文本…

git 怎么删除一个远程分支

在Git中&#xff0c;删除远程分支是一个相对简单的操作。以下是删除远程分支的步骤&#xff1a; 打开命令行工具&#xff1a; 打开你的命令行工具&#xff08;如Terminal、Git Bash、Cmder等&#xff09;。 切换到你的仓库&#xff1a; 使用cd命令切换到你的Git仓库目录。 检…