U8G2库使用案例(stm32)

U8G2官网:

自己移植的U8g2库,OLED库超好用,自己封装了用户层不需要再去查资料使用,注释写的很多很详细,有示例上手就会,初始化也很简单

个人移植的U8g2库:

超简单的stm32 U8g2移植

  大家可以自己去官网移植,也可以用我的         U8G2官网

  很多大家都可以举一反三

一、小球在 OLED 屏幕平面内运动并碰撞反弹的效果

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

// 小球结构体,包含位置、速度等信息
typedef struct {
    int16_t x;
    int16_t y;
    int16_t vx;  // x方向速度
    int16_t vy;  // y方向速度
    uint8_t radius;  // 小球半径
} Ball;

// 初始化小球的位置和速度
void init_ball(Ball *ball) {
    ball->x = 10;
    ball->y = 10;
    ball->vx = 2;
    ball->vy = 2;
    ball->radius = 5;
}

// 更新小球的位置,处理边界碰撞
void update_ball_position(Ball *ball, u8g2_uint_t screen_width, u8g2_uint_t screen_height) {
    // 更新x坐标
    ball->x += ball->vx;
    // 检查是否碰到左右边界,碰到则反弹
    if (ball->x <= ball->radius || ball->x >= screen_width - ball->radius) {
        ball->vx = -ball->vx;
    }

    // 更新y坐标
    ball->y += ball->vy;
    // 检查是否碰到上下边界,碰到则反弹
    if (ball->y <= ball->radius || ball->y >= screen_height - ball->radius) {
        ball->vy = -ball->vy;
    }
}

// 在OLED屏幕上绘制小球
void draw_ball(Ball ball) {
    WU_OLED_U8G2_DrawDisc(ball.x, ball.y, ball.radius, U8G2_DRAW_ALL);
}

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/



OLED_WUStartTask04(void *argument)
{

	Ball my_ball;
	init_ball(&my_ball);
	while(1)
	{
		//Wu_oled_Proc();

		// 清空缓冲区
		WU_OLED_U8G2_ClearBuffer();

		// 获取屏幕宽度和高度
		u8g2_uint_t screen_width = WU_OLED_U8G2_GetDisplayWidth();
		u8g2_uint_t screen_height = WU_OLED_U8G2_GetDisplayHeight();

		// 更新小球位置
		update_ball_position(&my_ball, screen_width, screen_height);

		// 绘制小球
		draw_ball(my_ball);

		// 刷新缓冲区,显示内容到OLED屏幕
		WU_OLED_U8G2_SendBuffer();

		//osDelay(50);
	}
}

二、 简单的波形生成和显示程序:

#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include "../../WU/OLED_U8g2/U8g2/WU_U8g2_Init.h"
#include "USER_OLED.h"
#include "../../WU/OLED_U8g2/U8g2/u8g2.h"

// 定义屏幕的宽度和高度
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// 定义波形参数
#define WAVE_AMPLITUDE 20  // 波形的振幅
#define WAVE_FREQUENCY 0.2 // 波形的频率(加快频率)

// 初始化波形数据
void InitWave(void) {
    // 无需初始化,因为每次都会重新计算正弦波
}

// 更新波形数据(生成正弦波)
void UpdateWave(uint8_t *waveData, float time) {
    for (int i = 0; i < SCREEN_WIDTH; i++) {
        // 计算正弦波的值,并将其映射到屏幕范围内
        float value = WAVE_AMPLITUDE * sin(WAVE_FREQUENCY * (i + time));
        waveData[i] = SCREEN_HEIGHT / 2 + (uint8_t)value;
    }
}

// 绘制波形
void DrawWave(uint8_t *waveData) {
    // 清空屏幕
    WU_OLED_U8G2_ClearBuffer();

    // 绘制波形
    for (int i = 0; i < SCREEN_WIDTH; i++) {
        // 确保波形在屏幕范围内
        if (waveData[i] < SCREEN_HEIGHT) {
            WU_OLED_U8G2_DrawPixel(i, waveData[i]);
        }
    }

    // 刷新发送缓冲区
    WU_OLED_U8G2_SendBuffer();
}

// 主函数
int main(void) {
    uint8_t waveData[SCREEN_WIDTH];  // 存储每个像素点的Y坐标
    float time = 0;                  // 时间变量,用于生成动态波形

    // 初始化OLED
    WU_OLED_U8G2_Init();

    // 主循环
    while (1) {
        // 更新波形数据
        UpdateWave(waveData, time);

        // 绘制波形
        DrawWave(waveData);

        // 更新时间(加快波形移动速度)
        time += 1.0;

        // 延时一段时间,控制波形刷新速度(减少延时时间)
        // 这里假设有一个延时函数 delay_ms
        //delay_ms(20);  // 将延时时间从50ms减少到20ms
    }

    return 0;
}

三、三维三角形旋转展示

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

// 定义更大的三角形在三维空间中的三个顶点坐标
float triangleVertices[3][3] = {
		{-15, -15, 0},  // 第一个顶点,调整了坐标使三角形更大
		{15, -15, 0},   // 第二个顶点
		{0, 15, 0}      // 第三个顶点
};

// 用于记录绕X、Y、Z轴旋转的角度
float angleX = 0;
float angleY = 0;
float angleZ = 0;

// 旋转角度的增量,这里固定一个合适的速度,可按需调整
const float angleIncrement = 0.03;

// 投影平面距离视点(类似相机到投影平面的距离,影响投影效果,可调整)
const float projectionPlaneDistance = 8;

// 转换三维坐标到二维屏幕坐标(简单的正投影示例,实际可替换为更复杂的投影算法比如透视投影等)
void project3DTo2D(float point3D[3], float* x2D, float* y2D) {
	// 先绕X轴旋转
	float rotatedX = point3D[0];
	float rotatedY = point3D[1] * cos(angleX) - point3D[2] * sin(angleX);
	float rotatedZ = point3D[1] * sin(angleX) + point3D[2] * cos(angleX);

	// 再绕Y轴旋转
	rotatedX = rotatedX * cos(angleY) + rotatedZ * sin(angleY);
	rotatedZ = -rotatedX * sin(angleY) + rotatedZ * cos(angleY);

	// 接着绕Z轴旋转
	rotatedX = rotatedX * cos(angleZ) - rotatedY * sin(angleZ);
	rotatedY = rotatedX * sin(angleZ) + rotatedY * cos(angleZ);

	// 进行正投影,将三维坐标投影到二维平面(这里假设投影平面平行于XY平面,且在Z轴固定位置)
	*x2D = rotatedX * projectionPlaneDistance / (rotatedZ + projectionPlaneDistance);
	*y2D = rotatedY * projectionPlaneDistance / (rotatedZ + projectionPlaneDistance);

	// 转换坐标到屏幕坐标系(以屏幕中心为原点,根据屏幕尺寸进行偏移等调整)
	*x2D += 64;  // 这里假设屏幕宽度为128像素,取一半作为中心原点的X偏移量,可根据实际屏幕宽度调整
	*y2D += 32;  // 这里假设屏幕高度为64像素,取一半作为中心原点的Y偏移量,可根据实际屏幕高度调整
}

// 绘制旋转后的空心三角形
void drawRotatedTriangle() {
	float x1, y1, x2, y2, x3, y3;
	// 对三角形的三个顶点分别进行投影转换
	project3DTo2D(triangleVertices[0], &x1, &y1);
	project3DTo2D(triangleVertices[1], &x2, &y2);
	project3DTo2D(triangleVertices[2], &x3, &y3);

	// 绘制空心三角形(使用绘制线的函数来连接三个顶点形成三角形)
	WU_OLED_U8G2_DrawLine(x1, y1, x2, y2);
	WU_OLED_U8G2_DrawLine(x2, y2, x3, y3);
	WU_OLED_U8G2_DrawLine(x3, y3, x1, y1);
}


/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/



OLED_WUStartTask04(void *argument)
{


	while(1)
	{
		//Wu_oled_Proc();

		// 清空发送缓冲区
		WU_OLED_U8G2_ClearBuffer();

		// 绘制旋转后的空心三角形
		drawRotatedTriangle();

		// 更新旋转角度(分别绕X、Y、Z轴增加一定角度,实现旋转效果)
		angleX += angleIncrement;
		angleY += angleIncrement;
		angleZ += angleIncrement;
		if (angleX >= 2 * M_PI) angleX -= 2 * M_PI;
		if (angleY >= 2 * M_PI) angleY -= 2 * M_PI;
		if (angleZ >= 2 * M_PI) angleZ -= 2 * M_PI;

		// 刷新发送缓冲区,将绘制内容显示到屏幕上
		WU_OLED_U8G2_SendBuffer();


		// 可以添加适当延时,控制动画速度,这里简单示意,实际可根据需求调整延时时间
		//osDelay(50);
	}
}

四、正方形平面内顺时针旋转

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

// 定义正方形在三维空间中的四个顶点坐标,调整大小使其适配屏幕
float squareVertices[4][3] = {
    {-20, -20, 0},  // 左下角顶点
    {20, -20, 0},   // 右下角顶点
    {20, 20, 0},    // 右上角顶点
    {-20, 20, 0}    // 左上角顶点
};

// 用于记录绕 Z 轴旋转的角度(仅绕 Z 轴旋转可实现平面内顺时针旋转)
float angleZ = 0;

// 旋转角度的增量,用于控制旋转速度,可根据实际需求调整
const float angleIncrement = 0.05;

// 投影平面距离视点(类似相机到投影平面的距离,影响投影效果,可调整)
const float projectionPlaneDistance = 5;

// 转换三维坐标到二维屏幕坐标(简单的正投影示例,实际可替换为更复杂的投影算法比如透视投影等)
void project3DTo2D(float point3D[3], float* x2D, float* y2D) {
	// 先绕 Z 轴旋转
	float rotatedX = point3D[0] * cos(angleZ) - point3D[1] * sin(angleZ);
	float rotatedY = point3D[0] * sin(angleZ) + point3D[1] * cos(angleZ);
	float rotatedZ = point3D[2];

	// 进行正投影,将三维坐标投影到二维平面(这里假设投影平面平行于XY平面,且在Z轴固定位置)
	*x2D = rotatedX * projectionPlaneDistance / (rotatedZ + projectionPlaneDistance);
	*y2D = rotatedY * projectionPlaneDistance / (rotatedZ + projectionPlaneDistance);

	// 转换坐标到屏幕坐标系(以屏幕中心为原点,根据屏幕尺寸进行偏移等调整)
	*x2D += 64;  // 这里假设屏幕宽度为128像素,取一半作为中心原点的X偏移量,可根据实际屏幕宽度调整
	*y2D += 32;  // 这里假设屏幕高度为64像素,取一半作为中心原点的Y偏移量,可根据实际屏幕高度调整
}

// 绘制旋转后的正方形
void drawRotatedSquare() {
	float x1, y1, x2, y2, x3, y3, x4, y4;
	// 对正方形的四个顶点分别进行投影转换
	project3DTo2D(squareVertices[0], &x1, &y1);
	project3DTo2D(squareVertices[1], &x2, &y2);
	project3DTo2D(squareVertices[2], &x3, &y3);
	project3DTo2D(squareVertices[3], &x4, &y4);

	// 绘制正方形的四条边
	WU_OLED_U8G2_DrawLine(x1, y1, x2, y2);
	WU_OLED_U8G2_DrawLine(x2, y2, x3, y3);
	WU_OLED_U8G2_DrawLine(x3, y3, x4, y4);
	WU_OLED_U8G2_DrawLine(x4, y4, x1, y1);
}

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/



OLED_WUStartTask04(void *argument)
{


	while(1)
	{
		//Wu_oled_Proc();

		// 清空发送缓冲区
		WU_OLED_U8G2_ClearBuffer();

		// 绘制旋转后的正方形
		drawRotatedSquare();

		// 更新旋转角度(绕 Z 轴增加一定角度,实现顺时针旋转效果)
		angleZ += angleIncrement;
		if (angleZ >= 2 * M_PI) angleZ -= 2 * M_PI;

		// 刷新发送缓冲区,将绘制内容显示到屏幕上
		WU_OLED_U8G2_SendBuffer();


		// 可以添加适当延时,控制动画速度,这里简单示意,实际可根据需求调整延时时间
		//osDelay(50);
	}
}

五、带有旋转点的空心圆圈应用

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

// 定义大空心圆圈的圆心坐标及半径
float bigCircleCenter[2] = {0, 0};
float bigCircleRadius = 25;

// 定义实心小圆圈的初始坐标
float smallSolidCircle[3];

// 用于记录实心小圆圈绕大空心圆圈旋转的角度
float circleAngle = 0;
const float circleAngleIncrement = 0.03;

// 投影平面距离视点(类似相机到投影平面的距离,影响投影效果,可调整)
const float projectionPlaneDistance = 5;

// 转换三维坐标到二维屏幕坐标(简单的正投影示例,实际可替换为更复杂的投影算法比如透视投影等)
void project3DTo2D(float point3D[3], float* x2D, float* y2D) {
	// 先绕 Z 轴旋转(针对实心小圆圈所在平面内旋转)
	float rotatedX = point3D[0];
	float rotatedY = point3D[1];
	float rotatedZ = point3D[2];

	// 进行正投影,将三维坐标投影到二维平面(这里假设投影平面平行于XY平面,且在Z轴固定位置)
	*x2D = rotatedX * projectionPlaneDistance / (rotatedZ + projectionPlaneDistance);
	*y2D = rotatedY * projectionPlaneDistance / (rotatedZ + projectionPlaneDistance);

	// 转换坐标到屏幕坐标系(以屏幕中心为原点,根据屏幕尺寸进行偏移等调整)
	*x2D += WU_OLED_U8G2_GetDisplayWidth() / 2;
	*y2D += WU_OLED_U8G2_GetDisplayHeight() / 2;
}

// 绘制大空心圆圈
void drawBigHollowCircle() {
	float centerX, centerY;
	project3DTo2D(bigCircleCenter, &centerX, &centerY);
	WU_OLED_U8G2_DrawCircle(centerX, centerY, bigCircleRadius, U8G2_DRAW_ALL);
}

// 绘制实心小圆圈并更新其位置(绕大空心圆圈旋转)
void drawRotatingSmallSolidCircle() {
	float x, y;
	// 根据旋转角度更新实心小圆圈的坐标
	smallSolidCircle[0] = bigCircleRadius * cos(circleAngle);
	smallSolidCircle[1] = bigCircleRadius * sin(circleAngle);

	project3DTo2D(smallSolidCircle, &x, &y);
	WU_OLED_U8G2_DrawDisc(x, y, 5, U8G2_DRAW_ALL);
}

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/



OLED_WUStartTask04(void *argument)
{

	// 初始化实心小圆圈的坐标
	smallSolidCircle[0] = bigCircleRadius;
	smallSolidCircle[1] = 0;
	smallSolidCircle[2] = 0;
	while(1)
	{
		//Wu_oled_Proc();

		// 清空发送缓冲区
		WU_OLED_U8G2_ClearBuffer();

		// 绘制大空心圆圈
		drawBigHollowCircle();

		// 绘制绕大空心圆圈旋转的实心小圆圈
		drawRotatingSmallSolidCircle();

		// 更新实心小圆圈绕大空心圆圈的旋转角度
		circleAngle += circleAngleIncrement;
		if (circleAngle >= 2 * M_PI) circleAngle -= 2 * M_PI;

		// 刷新发送缓冲区,将绘制内容显示到屏幕上
		WU_OLED_U8G2_SendBuffer();


		// 可以添加适当延时,控制动画速度,这里简单示意,实际可根据需求调整延时时间
		//osDelay(50);
	}
}

/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux 上安装 PostgreSQL

文章目录 前言一、安装PostgreSQL二、修改数据库默认数据存储目录 1.自定义数据存放目录2.修改自定义服务3.初始化数据库4.运行数据库 三、配置数据库信息 四、权限 异常处理 前言 提示&#xff1a;本次博客是centos7.9安装PostgreSQL12版本 名称 版本 Centos 7.9 postg…

HTML——56.表单发送

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表单发送</title></head><body><!--注意&#xff1a;1.表单接收程序&#xff0c;放在服务器环境中(也就是这里的www文件目录中)2.表单发送地址&#x…

logback之pattern详解以及源码分析

目录 &#xff08;一&#xff09;pattern关键字介绍 &#xff08;二&#xff09;源码分析 &#xff08;一&#xff09;pattern关键字介绍 %d或%date&#xff1a;表示日期&#xff0c;可配置格式化%d{yyyy-MM-dd HH:mm:ss} %r或%relative&#xff1a;也是日期&#xff0c;不过…

vLLM结构化输出(Guided Decoding)

简介 vLLM 的结构化输出特性是通过“引导式解码”&#xff08;Guided Decoding&#xff09;实现的&#xff0c;这一功能允许模型在生成文本时遵循特定的格式约束&#xff0c;例如 JSON 模式或正则表达式&#xff0c;从而确保生成的内容符合预期的结构化要求。 后端引擎 启动…

CM3/CM4时钟系统

CM3/4时钟系统 1. CM3时钟系统1.1 输入时钟源------------------A1.2 锁相环PLL------------------B1.3 系统时钟SYSCLK--------C/D/E/F/G 2. CM4时钟系统2.1 输入时钟源------------------A2.2 锁相环PLL------------------B2.3 系统时钟SYSCLK--------C/D/E2.4 时钟信号输出M…

RabbitMQ实现生产者消费者

一.启动MQ 注意管理员身份进入cmd才行,我这里是在本地安装的MQ,推荐使用虚拟机安装 二.思路 官方解释RabbitMQ结构: 自我理解RabbitMQ结构: 其实RabbitMQ的服务器就像邮局一样,我们的生产者和消费者对于这个服务器来说都是消费者,因为服务器都可以向两者发送消息 环境准备 …

MySQL--》如何在SQL中巧妙运用函数与约束,优化数据处理与验证?

目录 函数使用 字符串函数 数值函数 日期函数 流程函数 约束 外键约束 约束规则 函数使用 函数是指一段可以直接被另一段程序调用的程序或代码&#xff0c;在mysql当中有许多常见的内置函数&#xff0c;接下来开始对这些内置函数及其作用进行简单的讲解和使用&#xf…

OpenLinkSaas使用手册-待办事项和通知中心

在OpenLinkSaas工作台上&#xff0c;你可以查看待办事项和未读通知。 待办事项 目前待办事项支持: 个人待办项目待办:在项目中指派给你的任务/缺陷Git待办:在Git仓库中指标给你的Issue,目前只有在AtomGit和Gitee账号登录时才支持。 通知中心 通知中心支持Git通知和邮件通知两种…

【Unity】 HTFramework框架(五十八)【进阶篇】资源及代码热更新实战演示(Deployment + HybridCLR)

更新日期&#xff1a;2025年1月2日。 Github源码&#xff1a;[点我获取源码] 索引 资源及代码热更新实战演示运行演示Demo1.克隆项目工程2.更新子模块3.打开项目4.打开入口场景5.设置远端资源服务器地址6.导入HybridCLR7.初始化HybridCLR8.发布项目9.部署资源版本10.运行Exe11.…

路由基本配置实验

路由器用于实现不同类型网络之间的互联。 路由器转发ip分组的基础是路由表。 路由表中的路由项分为直连路由项、静态路由项和动态路由项。 通过配置路由器接口的ip地址和子网掩码自动生成直连路由项。 通过手工配置创建静态路由项。 热备份路由器协议允许将由多个路由器组…

CTFshow—远程命令执行

29-35 Web29 代码利用正则匹配过滤了flag&#xff0c;后面加了/i所以不区分大小写。 可以利用通配符绕过 匹配任何字符串&#xff0f;文本&#xff0c;包括空字符串&#xff1b;*代表任意字符&#xff08;0个或多个&#xff09; ls file * ? 匹配任何一个字符&#xff08;不…

idea 的 springboot项目spring-boot-devtools 自动编译 配置热部署

1&#xff0c;设置一 2&#xff0c;设置二 设置二&#xff08;旧版本&#xff09; CtrlShiftAlt/ 点击弹出框中Registry... 引入&#xff08;如果报错&#xff0c;换不同的版本&#xff09; <dependency><groupId>org.springframework.boot</groupId><a…

Github拉取项目报错解决

前言 昨天在拉取github上面的项目报错了&#xff0c;有好几个月没用github了&#xff0c;命令如下&#xff1a; git clone gitgithub.com:zhszstudy/git-test.git报错信息&#xff1a; ssh: connect to host github.com port 22: Connection timed out fatal: Could not rea…

TypeScript 常用类型

文章目录 1. 类型注解2. 原始类型3. 数组类型4. 联合类型5. 类型别名6. 函数类型7. 对象类型8. 接口类型8.1 接口声明8.2 接口继承 9. 元组类型10. 类型断言11. 字面量类型12. 枚举类型12.1 数字枚举12.2 字符串枚举 13. any 类型14. typeof 运算符 1. 类型注解 前言&#xff1…

ARM200~500部署

前提&#xff1a;数据库已经安装好&#xff0c;并且正常运行 1.修改hostname,将里面的AR-A 改为hzx vi /etc/hostname 2.重启网络服务 sudo systemctl restart NetworkManager 3.修改community-admin.service 文件&#xff0c;更改小区名称和IP&#xff0c;并将文件上传到/…

Linux buildroot和ubuntu的异同点

Buildroot 和 Ubuntu 都是 Linux 系统的操作环境,但它们的设计理念和使用场景有很大的不同。 一、定义与目标 Buildroot Buildroot 是一个用于生成嵌入式 Linux 系统的工具集,专注于交叉编译和构建嵌入式设备的最小 Linux 环境。它的目标是为嵌入式系统提供定制化和优化的…

从0开始的opencv之旅(1)cv::Mat的使用

目录 Mat 存储方法 创建一个指定像素方式的图像。 尽管我们完全可以把cv::Mat当作一个黑盒&#xff0c;但是笔者的建议是仍然要深入理解和学习cv::Mat自身的构造逻辑和存储原理&#xff0c;这样在查找问题&#xff0c;或者是遇到一些奇奇怪怪的图像显示问题的时候能够快速的想…

免登录游客卡密发放系统PHP网站源码

源码介绍&#xff1a; 这是一个简单易用的卡密验证系统&#xff0c;主要功能包括&#xff1a; 卡密管理和验证&#xff0c;多模板支持&#xff0c;响应式设计&#xff0c;验证码保护&#xff0c;防刷机制&#xff0c;简洁的用户界面&#xff0c; 支持自定义模板&#xff0c;移…

LeetCode - 初级算法 数组(旋转数组)

旋转数组 这篇文章讨论如何通过编程实现数组元素的旋转操作。 免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 描述 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例: 输入: nums = [1,2,3,

BOC调制信号matlab性能仿真分析,对比功率谱,自相关性以及抗干扰性

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff08;完整版代码包含详细中文注释和操作步骤视频&#xff09…