今日尝试做一款有动图的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(); //初始化定时器2
i2c_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(); //初始化定时器2
i2c_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