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]; 引用数组元素可以用下标法,也可以用指针法…...
基于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ÿ…...

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>主页:我的代码爱吃辣📃<2>知识讲解:数据结构——二叉搜索树☂️<3>开发环境 :Visual Studio 2022💬<4>前言:在之前的我们已经学过了普通二叉树,了解了基本的二叉树…...

【先进PID控制算法(ADRC,TD,ESO)加入永磁同步电机发电控制仿真模型研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

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

serve : 无法将“serve”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
1、在学习webpack打包的时候,需要 serve用来启动开发服务器来部署代码查看效果的。安装完之后运行出现以下错误: 2、使用命令查看安装目录: npm list -g我们已经安装过了 3、解决: 我们看到上图路径在:C:\Users\qiy…...

【LVS】2、部署LVS-DR群集
LVS-DR数据包的流向分析 1.客户端发送请求到负载均衡器,请求的数据报文到达内核空间; 2.负载均衡服务器和正式服务器在同一个网络中,数据通过二层数据链路层来传输; 3.内核空间判断数据包的目标IP是本机VIP,此时IP虚…...
设计模式 -- 单例模式(传统面向对象与JavaScript 的对比实现)
单例模式 – 传统面向对象与JavaScript 的对比实现 文章目录 单例模式 -- 传统面向对象与JavaScript 的对比实现传统的面向对象的实现定义实现思路初级实现缺点 透明的单例模式实现目的(实现效果)实现缺点 用代理实现单例模式优点 JavaScript 中的单例模…...

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

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...