当前位置: 首页 > news >正文

STM32 F103C8T6学习笔记10:OLED显示屏GIF动图取模—简易时钟—动图手表的制作~

今日尝试做一款有动图的OLED实时时钟,本文需要现学一个OLED的GIF动图取模

其余需要的知识点有不会的可以去我  STM32 F103C8T6学习笔记  系列专栏自己查阅把,闲话不多,直接开肝~~~

文章提供源码,测试工程下载,测试效果图。

做个简易的时钟,就不把RTC实时时钟放进来学了,用定时器简单代替了~~

目录

原图GIF:

程序显示时间的问题:

简单版定时器2时间计数:

字符串给OLED打印函数:

 十进制数字转字符串:

下载程序测试:

 GIF取模问题:

程序贴出:

测试效果图:

工程下载:


原图GIF:

这里先提示一下,工程会提供原图GIF(原图像素64*64):

程序显示时间的问题:

首先解决一下程序显示时间的问题:

简单版定时器2时间计数:

这里初始化定时器2 是10ms周期,然后定义变量在定时器2中断服务函数刷新1s使得SECOND秒加一:

uint16_t YEAR,HOUR,MINUTE,SECOND;
uint16_t TimeDisplay_cnt,TimeDisplay;//定时器2中断服务函数
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){		if(++TimeDisplay_cnt==100){TimeDisplay_cnt=0;SECOND++;}TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清出中断寄存器标志位,用于退出中断}
}

别忘了时分秒之间的逻辑:

		if(SECOND==60){SECOND=0;MINUTE++;}if(MINUTE==60){MINUTE=0;HOUR++;}if(HOUR==12)  {HOUR=0;}

字符串给OLED打印函数:

 然后就是转化数字字符串给OLED打印的函数:

//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{unsigned char j=0;while (chr[j]!='\0'){		OLED_ShowChar(x,y,chr[j],Char_Size);x+=8;if(x>120){x=0;y+=2;}j++;}
}

 十进制数字转字符串:

 主函数使用    sprintf(  );  函数   把十进制数字处理转化到字符串数组中

#include "main.h"uint16_t YEAR,HOUR,MINUTE,SECOND;
uint16_t TimeDisplay_cnt,TimeDisplay;
uint16_t BMP_cnt,BMP_FLAG;
char  buf[10];   //用于存储oled数据int main(void)
{	init_ALL();     //初始化所有函数while(1){if(SECOND==60){SECOND=0;MINUTE++;}if(MINUTE==60){MINUTE=0;HOUR++;}if(HOUR==12)  {HOUR=0;}sprintf(buf,"%d",YEAR);OLED_ShowString(80,0,(u8 *)buf,16);sprintf(buf,"%d-",HOUR);OLED_ShowString(70,3,(u8 *)buf,12);sprintf(buf,"%d-",MINUTE);OLED_ShowString(70+15,3,(u8 *)buf,12);sprintf(buf,"%d",SECOND);OLED_ShowString(70+38,3,(u8 *)buf,12);}
}//初始化所有函数:
void init_ALL(void)
{SysTick_Init(72);         //初始化滴答计时器Timer2_Init();						//初始化定时器2i2c_GPIO_Config();	      //IIC初始化OLED_Init();              //初始化OLED屏幕OLED_Clear();             //清空屏幕数据YEAR=2023;HOUR=8;MINUTE=22;
}//定时器2中断服务函数
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){		if(++TimeDisplay_cnt==100){TimeDisplay_cnt=0;SECOND++;}if(++BMP_cnt==10)										 //定时器   刷新太空人图片{BMP_cnt=0;BMP_FLAG++;if(BMP_FLAG==8){BMP_FLAG=0;}}TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清出中断寄存器标志位,用于退出中断}
}

下载程序测试:

 

 

 GIF取模问题:

 动图本质是一帧一帧的图片,因此我们先要将动图分解,在逐个取模....这是个庞大的工程~~

 然后就是每个图片调整大小,像素,取模:

 

程序贴出:

#include "main.h"uint16_t YEAR,HOUR,MINUTE,SECOND;
uint16_t TimeDisplay_cnt,TimeDisplay;
uint16_t BMP_cnt,BMP_FLAG;
char  buf[10];   //用于存储oled数据int main(void)
{	init_ALL();     //初始化所有函数while(1){if(SECOND==60){SECOND=0;MINUTE++;}if(MINUTE==60){MINUTE=0;HOUR++;}if(HOUR==12)  {HOUR=0;}sprintf(buf,"%d",YEAR);OLED_ShowString(80,0,(u8 *)buf,16);sprintf(buf,"%02d-",HOUR);OLED_ShowString(65,3,(u8 *)buf,12);sprintf(buf,"%02d-",MINUTE);OLED_ShowString(65+24,3,(u8 *)buf,12);sprintf(buf,"%02d",SECOND);OLED_ShowString(65+45,3,(u8 *)buf,12);OLED_ShowChar(70,5,'N',12);OLED_ShowChar(70+8,5,'U',12);		OLED_ShowChar(70+16,5,'L',12);		OLED_ShowChar(70+24,5,'L',12);		OLED_ShowCHinese(70,6,0);OLED_ShowCHinese(70+16,6,1);		OLED_ShowCHinese(70+32,6,2);switch(BMP_FLAG){case 1:OLED_DrawBMP(0,0,64,8,BMP1);  break;case 2:OLED_DrawBMP(0,0,64,8,BMP2);  break;case 3:OLED_DrawBMP(0,0,64,8,BMP3);  break;case 4:OLED_DrawBMP(0,0,64,8,BMP4);  break;case 5:OLED_DrawBMP(0,0,64,8,BMP5);  break;case 6:OLED_DrawBMP(0,0,64,8,BMP6);  break;case 7:OLED_DrawBMP(0,0,64,8,BMP7);  break;case 8:OLED_DrawBMP(0,0,64,8,BMP8);  break;case 9:OLED_DrawBMP(0,0,64,8,BMP9);  break;case 10:OLED_DrawBMP(0,0,64,8,BMP10);  break;case 11:OLED_DrawBMP(0,0,64,8,BMP11);  break;case 12:OLED_DrawBMP(0,0,64,8,BMP12);  break;case 13:OLED_DrawBMP(0,0,64,8,BMP13);  break;case 14:OLED_DrawBMP(0,0,64,8,BMP14);  break;case 15:OLED_DrawBMP(0,0,64,8,BMP15);  break;case 16:OLED_DrawBMP(0,0,64,8,BMP16);  break;case 17:OLED_DrawBMP(0,0,64,8,BMP17);  break;case 18:OLED_DrawBMP(0,0,64,8,BMP18);  break;case 19:OLED_DrawBMP(0,0,64,8,BMP19);  break;case 20:OLED_DrawBMP(0,0,64,8,BMP20);  break;		case 21:OLED_DrawBMP(0,0,64,8,BMP21);  break;case 22:OLED_DrawBMP(0,0,64,8,BMP22);  break;case 23:OLED_DrawBMP(0,0,64,8,BMP23);  break;case 24:OLED_DrawBMP(0,0,64,8,BMP24);  break;case 25:OLED_DrawBMP(0,0,64,8,BMP25);  break;case 26:OLED_DrawBMP(0,0,64,8,BMP26);  break;case 27:OLED_DrawBMP(0,0,64,8,BMP27);  break;case 28:OLED_DrawBMP(0,0,64,8,BMP28);  break;}}
}//初始化所有函数:
void init_ALL(void)
{SysTick_Init(72);         //初始化滴答计时器Timer2_Init();						//初始化定时器2i2c_GPIO_Config();	      //IIC初始化OLED_Init();              //初始化OLED屏幕OLED_Clear();             //清空屏幕数据YEAR=2023;HOUR=8;MINUTE=22;SECOND=55;
}//定时器2中断服务函数
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){		if(++TimeDisplay_cnt==100){TimeDisplay_cnt=0;SECOND++;		if(SECOND==60){SECOND=0;MINUTE++;}}if(++BMP_cnt==10)										 //定时器   刷新太空人图片{BMP_cnt=0;BMP_FLAG++;if(BMP_FLAG==29){BMP_FLAG=1;}}TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清出中断寄存器标志位,用于退出中断}
}

测试效果图:

 

工程下载:

https://download.csdn.net/download/qq_64257614/88232446?spm=1001.2014.3001.5503

相关文章:

STM32 F103C8T6学习笔记10:OLED显示屏GIF动图取模—简易时钟—动图手表的制作~

今日尝试做一款有动图的OLED实时时钟,本文需要现学一个OLED的GIF动图取模 其余需要的知识点有不会的可以去我 STM32 F103C8T6学习笔记 系列专栏自己查阅把,闲话不多,直接开肝~~~ 文章提供源码,测试工程下载,测试效…...

大数据课程K3——Spark的常用案例

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的常用案例——WordCount; ⚪ 掌握Spark的常用案例——求平均值; ⚪ 掌握Spark的常用案例——求最大值和最小值; ⚪ 掌握Spark的常用案例——TopK; ⚪ 掌握Spark的常用案例…...

85-最大矩阵

题目 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。 示例 1: 输入:matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,…...

8.3 【C语言】通过指针引用数组

8.3.1 数组元素的指针 所谓数组元素的指针就是数组元素的地址。 可以用一个指针变量指向一个数组元素。例如: int a[10]{1,3,5,7,9,11,13,15,17,19}; int *p; p&a[0]; 引用数组元素可以用下标法,也可以用指针法&#xf…...

基于Flink CDC实时同步PostgreSQL与Tidb【Flink SQL Client模式下亲测可行,详细教程】

文章目录 一、PostgreSQL作为数据来源(source),由flink读取1.postgre安装与配置2.flink安装与配置3.flink cdc postgre配置3.1 postgre配置(for flink cdc)3.2 flink cdc postgres的jar包下载 4.flink cdc postgre测试…...

Vue-5.编译器Idea

Vue专栏(帮助你搭建一个优秀的Vue架子) Vue-1.零基础学习Vue Vue-2.Nodejs的介绍和安装 Vue-3.Vue简介 Vue-4.编译器VsCode Vue-5.编译器Idea Vue-6.编译器webstorm Vue-7.命令创建Vue项目 Vue-8.Vue项目配置详解 Vue-9.集成(.editorconfig、…...

qiuzhiji3

本篇想介绍一下慧与,这里的工作氛围和企业文化令人难忘,希望更多人了解它 也想探讨一下不同的文化铸就的不同企业,究竟有哪些差别。 本篇将从我个人角度出发描述慧与。 2022/3/16至2023/7/31 本篇初次写于2023年8月20日 说起来在毕业之前那段…...

JVM——垃圾回收(垃圾回收算法+分代垃圾回收+垃圾回收器)

1.如何判断对象可以回收 1.1引用计数法 只要一个对象被其他对象所引用,就要让该对象的技术加1,某个对象不再引用其,则让它计数减1。当计数变为0时就可以作为垃圾被回收。 有一个弊端叫做循环引用,两个的引用计数都是1&#xff…...

QT TLS initialization failed问题(已解决) QT基础入门【网络编程】openssl

问题: qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed 这个问题的出现主要是使用了https请求:HTTPS ≈ HTTP + SSL,即有了加密层的HTTP 所以Qt 组件库需要OpenSSL dll 文件支持HTTPS 解决: 1.加入以下两行代码获取QT是否支持opensll以…...

SpringMVC之获取请求参数

文章目录 前言一、通过ServletAPI获取二、通过控制器方法的形参获取请求参数三、注解1.RequestParam2.RequestHeader3.CookieValue前面的代码总和:4.通过POJO获取请求参数 三、解决获取请求参数的乱码问题总结 前言 下面用到了thymeleaf,不知道的可以看…...

【无标题】QT应用编程: QtCreator配置Git版本控制(码云)

QT应用编程: QtCreator配置Git版本控制(码云) 感谢:DS小龙哥的文章,这篇主要参考小龙哥的内容。 https://cloud.tencent.com/developer/article/1930531?areaSource102001.15&traceIdW2mKALltGu5f8-HOI8fsN Qt Creater 自带了git支持。但是一直没…...

JVM面试题-2

1、有哪几种垃圾回收器,各自的优缺点是什么? 垃圾回收器主要分为以下几种:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1; Serial:单线程的收集器,收集垃圾时,必须stop the worl…...

kafka安装说明以及在项目中使用

一、window 安装 1.1、下载安装包 下载kafka 地址,其中官方版内置zk, kafka_2.12-3.4.0.tgz其中这个名称的意思是 kafka3.4.0 版本 ,所用语言 scala 版本为 2.12 1.2、安装配置 1、解压刚刚下载的配置文件,解压后如下&#x…...

二叉树搜索

✅<1>主页&#xff1a;我的代码爱吃辣&#x1f4c3;<2>知识讲解&#xff1a;数据结构——二叉搜索树☂️<3>开发环境 &#xff1a;Visual Studio 2022&#x1f4ac;<4>前言&#xff1a;在之前的我们已经学过了普通二叉树&#xff0c;了解了基本的二叉树…...

【先进PID控制算法(ADRC,TD,ESO)加入永磁同步电机发电控制仿真模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

k8s集群生产环境的问题处理

2 k8s上的服务均无法访问 执行命令kubectl get pods -ALL,k8s集群中的服务均是running状态 1 kuboard 网页无法访问 kuboard无法通过浏览器访问&#xff0c;但是查看端口是被占用的...

serve : 无法将“serve”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

1、在学习webpack打包的时候&#xff0c;需要 serve用来启动开发服务器来部署代码查看效果的。安装完之后运行出现以下错误&#xff1a; 2、使用命令查看安装目录&#xff1a; npm list -g我们已经安装过了 3、解决&#xff1a; 我们看到上图路径在&#xff1a;C:\Users\qiy…...

【LVS】2、部署LVS-DR群集

LVS-DR数据包的流向分析 1.客户端发送请求到负载均衡器&#xff0c;请求的数据报文到达内核空间&#xff1b; 2.负载均衡服务器和正式服务器在同一个网络中&#xff0c;数据通过二层数据链路层来传输&#xff1b; 3.内核空间判断数据包的目标IP是本机VIP&#xff0c;此时IP虚…...

设计模式 -- 单例模式(传统面向对象与JavaScript 的对比实现)

单例模式 – 传统面向对象与JavaScript 的对比实现 文章目录 单例模式 -- 传统面向对象与JavaScript 的对比实现传统的面向对象的实现定义实现思路初级实现缺点 透明的单例模式实现目的&#xff08;实现效果&#xff09;实现缺点 用代理实现单例模式优点 JavaScript 中的单例模…...

YOLOX算法调试记录

YOLOX是在YOLOv3基础上改进而来&#xff0c;具有与YOLOv5相媲美的性能&#xff0c;其模型结构如下&#xff1a; 由于博主只是要用YOLOX做对比试验&#xff0c;因此并不需要对模型的结构太过了解。 先前博主调试过YOLOv5,YOLOv7&#xff0c;YOLOv8,相比而言&#xff0c;YOLOX的环…...

告别‘缺少DLL’:用EnigmaVB给Qt5.14程序封包的保姆级避坑指南

告别“缺少DLL”困境&#xff1a;EnigmaVBQt5.14封包全流程实战手册 当你用Qt Creator完成开发&#xff0c;满怀期待地将程序打包发给用户&#xff0c;却收到“缺少xxx.dll”的报错反馈时&#xff0c;这种挫败感开发者都深有体会。本文将以Qt5.14为例&#xff0c;结合EnigmaVB封…...

5分钟快速上手!用VeriStand为你的Simulink模型搭建一个简易监控仪表盘

5分钟快速上手&#xff01;用VeriStand为Simulink模型搭建实时监控仪表盘 在工程仿真领域&#xff0c;能够直观观察模型运行状态并实时调整参数&#xff0c;是提升开发效率的关键。想象一下这样的场景&#xff1a;你刚完成一个BUCK电路的Simulink建模&#xff0c;通过仿真验证了…...

闽北哥-做个无用之人,方成大用

做个无用之人 ——方成大用 “太有用的人&#xff0c;一定走不远。” &#x1f33f; 人生是一场‘无心生大用’的修行。 白木香树越能结香&#xff0c;越被千疮百孔&#xff1b; 无用之树&#xff0c;反得自然生长。 &#x1f4a1; 真正的价值&#xff0c;不在“有”&#xff…...

零基础掌握SeleniumBasic:革新性浏览器自动化框架全攻略

零基础掌握SeleniumBasic&#xff1a;革新性浏览器自动化框架全攻略 【免费下载链接】SeleniumBasic A Selenium based browser automation framework for VB.Net, VBA and VBScript 项目地址: https://gitcode.com/gh_mirrors/se/SeleniumBasic 每天重复机械的网页操作…...

LFM2.5-1.2B-Thinking-GGUF实操手册:自定义system prompt提升领域适配性

LFM2.5-1.2B-Thinking-GGUF实操手册&#xff1a;自定义system prompt提升领域适配性 1. 模型简介与核心优势 LFM2.5-1.2B-Thinking-GGUF是Liquid AI推出的轻量级文本生成模型&#xff0c;专为低资源环境优化设计。该模型采用GGUF格式和llama.cpp运行时&#xff0c;在保持高性…...

告别枯燥刷怪!用Python+大漠插件实现《功夫》游戏后台自动挂机(附完整源码)

用Python与大漠插件打造《功夫》游戏智能挂机系统 在角色扮演类游戏中&#xff0c;重复性的任务往往成为玩家体验的瓶颈。以经典游戏《功夫》为例&#xff0c;"考古"任务需要不断接取、放弃任务直至找到特定地点&#xff0c;再完成打怪流程。这种机械操作不仅耗时耗力…...

Flutter 实现点击任意位置收起键盘的最佳实践

痛点 在 Flutter 开发中&#xff0c;TextField 聚焦后会弹出键盘&#xff0c;关闭键盘通常需要&#xff1a; 点击系统返回键点击输入框外的空白区域&#xff08;但很多情况下点击空白区域也没反应&#xff09;点击其他输入框&#xff08;键盘会切换到另一个输入框&#xff0c;不…...

Vue 3 Fragments:打破枷锁的组件化革命

Vue 3 Fragments&#xff1a;打破枷锁的组件化革命 在前端框架的演进史上&#xff0c;每一次对底层限制的突破&#xff0c;往往都伴随着开发体验的质的飞跃。Vue 3 中引入的 Fragments&#xff08;片段&#xff09; 特性&#xff0c;正是这样一场迟来的“解绑”革命。它彻底粉碎…...

当心“Pin-to-Pin兼容“陷阱:ICM-42688国产替代芯片深度拆解与避坑指南

两句话总结&#xff1a;近期TDK ICM-42688-P价格暴涨至百元且一芯难求&#xff0c;立创商城上出现了华轩阳、Tokmas等"国产替代"。本文通过详细对比三家datasheet数据手册&#xff0c;揭示所谓"兼容"背后的软件陷阱与性能差异。结论可能出乎你意料&#xf…...

OpenClaw备份策略:GLM-4.7-Flash模型与技能容灾方案

OpenClaw备份策略&#xff1a;GLM-4.7-Flash模型与技能容灾方案 1. 为什么需要备份OpenClaw环境 去年冬天的一个深夜&#xff0c;我的MacBook突然遭遇硬盘故障。当时OpenClaw正在执行一个长达3小时的自动化数据处理任务&#xff0c;所有中间状态和配置瞬间消失。这次事故让我…...