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();						//初始化定时器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

  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NULL指向我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值