目录一、小球在 OLED 屏幕平面内运动并碰撞反弹的效果二、 简单的波形生成和显示程序:三、三维三角形旋转展示四、正方形平面内顺时针旋转五、带有旋转点的空心圆圈应用六、字幕滚动效果七、下雪动画效果八、进度条动画效果自己移植的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); } } /*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/六、字幕滚动效果void OLED_WUStartTask04(void *argument) { const char* message 祝大家新年快乐,恭喜发财!; // 祝福语 int messageWidth WU_OLED_U8G2_GetUTF8Width(message); // 获取祝福语的宽度 int x WU_OLED_U8G2_GetDisplayWidth(); // 获取屏幕宽度初始x坐标为屏幕最右侧 while (1) { // 清空显示缓冲区 WU_OLED_U8G2_ClearBuffer(); // 绘制祝福语x坐标逐渐减小实现从右往左滚动效果 WU_OLED_U8G2_SetFont(u8g2_font_wqy13_t_gb2312a); // 设置字体支持中文 WU_OLED_U8G2_DrawUTF8(x, 32, message); // 在指定位置绘制祝福语 // 刷新显示 WU_OLED_U8G2_SendBuffer(); // 更新x坐标实现滚动效果 x--; // 如果祝福语完全滚出屏幕重置x坐标 if (x -messageWidth) { x WU_OLED_U8G2_GetDisplayWidth(); } // 控制滚动速度避免过快或过慢 //osDelay(20); // 20ms的延时可以根据实际效果调整 } }七、下雪动画效果/*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ // 定义屏幕的宽度和高度你可根据实际OLED屏幕尺寸修改 #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 // 雪花结构体用于表示每个雪花的属性 typedef struct Snowflake { int x; // x坐标 int y; // y坐标 int speed; // 下落速度 } Snowflake; // 最大雪花数量可以根据想要的下雪密度调整 #define MAX_SNOWFLAKES 50 Snowflake snowflakes[MAX_SNOWFLAKES]; // 初始化雪花的位置和速度 void initSnowflakes() { for (int i 0; i MAX_SNOWFLAKES; i) { snowflakes[i].x rand() % SCREEN_WIDTH; snowflakes[i].y rand() % SCREEN_HEIGHT; snowflakes[i].speed rand() % 3 1; // 速度在1到3之间随机 } } // 更新雪花的位置实现下落效果超出屏幕底部则重新回到顶部 void updateSnowflakes() { for (int i 0; i MAX_SNOWFLAKES; i) { snowflakes[i].y snowflakes[i].speed; if (snowflakes[i].y SCREEN_HEIGHT) { snowflakes[i].y 0; snowflakes[i].x rand() % SCREEN_WIDTH; } } } // 在OLED屏幕上绘制雪花白色像素点 void drawSnowflakes() { WU_OLED_U8G2_SetDrawColor(1); // 设置为白色用于绘制雪花 for (int i 0; i MAX_SNOWFLAKES; i) { WU_OLED_U8G2_DrawPoint(snowflakes[i].x, snowflakes[i].y); } } /*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ OLED_WUStartTask04(void *argument) { initSnowflakes(); while(1) { //Wu_oled_Proc(); WU_OLED_U8G2_ClearBuffer(); // 清空缓冲区 updateSnowflakes(); drawSnowflakes(); WU_OLED_U8G2_SendBuffer(); // 刷新缓冲区将绘制内容显示到屏幕上 // 可以添加适当延时控制动画速度这里简单示意实际可根据需求调整延时时间 //osDelay(50); } } /*------------------------------------------------------------------------------------------------------------------------------------------------------------------*/八、进度条动画效果OLED_WUStartTask04(void *argument) { int dat; while(1) { //Wu_oled_Proc(); while(dat101) { WU_OLED_U8G2_ClearBuffer(); WU_OLED_U8G2_SetFont(u8g2_font_wqy13_t_gb2312a);//选择字库 WU_OLED_U8G2_Printf(25,18,CHINA,WU-有点东); WU_OLED_U8G2_DrawButtonUTF8(65, 35, U8G2_BTN_SHADOW1|U8G2_BTN_HCENTER|U8G2_BTN_BW2, 0, 2, 2, 请等待初始化完成 ); WU_OLED_U8G2_Printf(101,60,CHINA,%d%%,dat); WU_OLED_U8G2_DrawRFrame(0, 50, 100,10,4); WU_OLED_U8G2_DrawRBox(0, 50, dat,10,4); WU_OLED_U8G2_SendBuffer(); dat2; } WU_OLED_U8G2_DrawButtonUTF8(65, 35, U8G2_BTN_SHADOW1|U8G2_BTN_HCENTER|U8G2_BTN_BW2|U8G2_BTN_INV, 0, 2, 2, 请等待初始化完成 ); WU_OLED_U8G2_SendBuffer(); dat0; //osDelay(50); } }