用STM32玩OLED(顯示文字、圖片、動圖gif等)


用STM32玩OLED(顯示文字、圖片、動圖gif等)

一位伴隨我童年的演員也離開了人間,真的是感嘆人生無常,希望世上病痛少一點。

開發板:STM32F407ZGT6(正點原子探索者)
OLED:技小新0.96'OLED顯示器模塊(4PIN)
軟件:Keil MDK5.29

Gitee項目已發布,需要源碼請自助下載
地址(gitee)

OLED資料網頁:網頁地址

例程是STM32F103和STM8的,跟我用的不一樣,所以就改了例程

4pin的OLED用的是IIC通信,按着手冊改了oled的scl和sda的端口(PB8和PB9)

1. 顯示字符串

/*
	@brief			顯示字符串
	@param			x:起始列
					y:起始頁
					*chr:第一個字符首地址
	@retval			無
 */
void OLED_ShowString(unsigned char x,unsigned char y,unsigned char *chr)
{
	unsigned char j=0; //定義變量

	while (chr[j]!='\0') //如果不是最后一個字符
	{		
		OLED_ShowChar(x,y,chr[j]); //顯示字符
		x+=8; //列數加8 ,一個字符的列數占8
		if(x>=128){x=0;y+=2;} //如果x大於等於128,切換頁,從該頁的第一列顯示
		j++; //下一個字符
	}
} 

測試代碼如下

#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "oledfont.h"
#include "bmp.h"

int main(void)
{
	delay_init(168);		//延時初始化
	OLED_Init();  //OLED初始化
	OLED_Clear();
	
	OLED_ShowString(36,2,"Giao!!!");
    while(1)
    {
        
    }
}

顯示效果如下
image

2. 顯示中文

取模軟件用的是PCtoLCD2002完美版,取模方式如下
image

下載地址:地址(侵刪)

程序方面修改了例程,讓程序功能變得更直接

/*
	@brief			顯示中文
	@param			x:起始列;一個字體占16列
					y:起始頁;一個字體占兩頁
					no:字體的序號
					m:單個字體大小
					Chn[][m]:中文數組
	@retval			無
 */
void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no,unsigned char m,unsigned char Chn[][m])
{      			    
	unsigned char t,adder=0; //定義變量

	OLED_Set_Pos(x,y);	//從 x y 開始畫點,先畫第一頁
    for(t=0;t<16;t++) //循環16次,畫第一頁的16列
		{
			OLED_WR_Byte(Chn[2*no][t],OLED_DATA);//畫no在數組位置的第一頁16列的點
			adder+=1; //數組地址加1
     	}	
		OLED_Set_Pos(x,y+1); //畫第二頁
    for(t=0;t<16;t++)//循環16次,畫第二頁的16列
		{	
			OLED_WR_Byte(Chn[2*no+1][t],OLED_DATA);//畫no在數組位置的第二頁16列的點
			adder+=1;//數組地址加1
        }					
}

測試程序如下

#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "oledfont.h"
#include "bmp.h"

int main(void)
{
	delay_init(168);		//延時初始化
	OLED_Init();  //OLED初始化
	OLED_Clear();
	
	OLED_ShowCHinese(16,1,0,32,Welcome);
	OLED_ShowCHinese(32,1,1,32,Welcome);
	OLED_ShowCHinese(48,1,2,32,Welcome);
	OLED_ShowCHinese(64,1,3,32,Welcome);
	OLED_ShowCHinese(80,1,4,32,Welcome);
	OLED_ShowCHinese(96,1,5,32,Welcome);

    while(1)
    {
        
    }
}

顯示效果如下
image

3. 顯示圖片

取模方式與顯示中文一樣,但是要轉換成數組形式,就要變成單色(黑與白),而且大小應該在128*64內,我用的軟件是Img2Lcd

下載地址:地址(侵刪)

設置效果如下
image
測試圖片是一本書,網上找的,大小是48*48
image

unsigned char BMP1[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0xC0,0xC0,0xC0,0xC0,
0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,
0x1C,0x0E,0x07,0x73,0x79,0x58,0xC8,0xD8,0xD8,0xD8,0x98,0x90,0xB0,0xB0,0x30,0x30,
0x60,0xE1,0xE1,0xE1,0x01,0x03,0x03,0x03,0x83,0xC6,0xE6,0x7E,0x1C,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x0C,0x07,0x03,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x03,
0x03,0x83,0xC1,0xE0,0x70,0x38,0x9E,0xE7,0x7F,0x0F,0x03,0xFF,0xFF,0x00,0x00,0x00,
0x00,0x00,0x00,0xFE,0xFF,0x03,0xF8,0xF8,0x0C,0x0C,0x0C,0x18,0x18,0x18,0x18,0x30,
0x30,0x30,0x60,0x60,0x60,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0xC0,0xE0,0x70,0x1C,0x8E,
0xC7,0xE3,0x71,0x3C,0x8E,0xC7,0xE3,0x79,0x1C,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x07,0x0E,0x1C,0x3B,0x33,0x36,0x66,0x66,0x6C,0xCC,0xCC,0xD8,
0xD8,0x98,0xB0,0xB0,0x30,0x30,0x60,0x60,0x60,0xC0,0xE1,0x70,0x38,0x9C,0xCE,0xE7,
0x71,0x38,0x1E,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x01,0x01,0x03,0x03,0x03,0x03,0x06,0x06,0x06,0x06,0x07,0x03,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\long\Desktop\#′y′|àí\Pic\book1.bmp",0*/
};

這個就是例程里的,沒什么要改的
程序如下:

/*
	@brief			顯示圖片
	@param			x0:起始列地址
					y0:起始頁地址
					x1:終止列地址
					y1:終止頁地址
					BMP[]:存放圖片代碼的數組
	@retval			無
 */
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{ 	
 	unsigned int j=0; //定義變量
 	unsigned char x,y; //定義變量
  
 	if(y1%8==0) y=y1/8;   //判斷終止頁是否為8的整數倍
 	 else y=y1/8+1;

		for(y=y0;y<y1;y++) //從起始頁開始,畫到終止頁
		{
			OLED_Set_Pos(x0,y); //在頁的起始列開始畫
   			for(x=x0;x<x1;x++) //畫x1 - x0 列
	    		{
	    			OLED_WR_Byte(BMP[j++],OLED_DATA);	//畫圖片的點    	
	    		}
		}
} 

值得注意的是函數的第一個和第三個參數,起始列地址和終止列地址,如果和圖片的分辨率對不上,那就會顯示出來一坨散沙,看不出樣子

測試程序如下:

#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "oledfont.h"
#include "bmp.h"

int main(void)
{
	delay_init(168);		//延時初始化
	OLED_Init();  //OLED初始化
	OLED_Clear();
	
	OLED_DrawBMP(40,2,88,8,BMP1);

    while(1)
    {
        
    }
}

顯示效果如下
image

4. 顯示動圖

在網上找了一些512*512的GIF圖,這樣是沒辦法用的,需要降低分辨率和調成單色,而且還要提取幀

512*512動圖下載地址:地址(侵刪)

在這里用到的軟件有很多,我用的是一個叫IrfanView的軟件,這個軟件可以快速的查看圖片,也可以提取幀,批量操作圖片,真滴好好用。

IrfanView下載地址:官網
地址(侵刪)

使用教程:教程(bilibili)

取模之后的數組比較大,就不發上來了

顯示動圖程序如下

/*
	@brief			顯示動圖
	@param			x0:起始列地址
				y0:起始頁地址
				x1:終止列地址
				y1:終止頁地址
				k: 幀個數
				m: 單幀數組大小
				BMP[][m]:存放動圖代碼的數組
	@retval			無
 */
void OLED_DrawGIF(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1, unsigned char k, int m, unsigned char GIF[][m])
{
	unsigned int j=0; //定義變量
 	unsigned char x,y,i; //定義變量
  
 	if(y1%8==0) y=y1/8;   //判斷終止頁是否為8的整數倍
 	 else y=y1/8+1;
	for (i=0;i<k;i++) //從第一幀開始畫
	{
		j = 0;
		for(y=y0;y<y1;y++) //從起始頁開始,畫到終止頁
		{
			OLED_Set_Pos(x0,y); //在頁的起始列開始畫
   			
			for(x=x0;x<x1;x++) //畫x1 - x0 列
	    		{
						
	    			OLED_WR_Byte(GIF[i][j++],OLED_DATA);	//畫圖片的點    	
	    		}
		}
		//delay_ms(80);//人為制造卡頓???

	}
}

測試程序如下

#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "oledfont.h"
#include "bmp.h"

int main(void)
{
	delay_init(168);		//延時初始化
	OLED_Init();  //OLED初始化
	OLED_Clear();
	

    while(1)
    {
        OLED_DrawGIF(32,0,96,8,31,512,Pencil);
    }
}

顯示效果如下:
image

5. 總結測試

測試代碼:

#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "oledfont.h"
#include "bmp.h"

int main(void)
{
	delay_init(168);		//延時初始化
	OLED_Init();  //OLED初始化
	OLED_Clear();
	
		
	OLED_ShowCHinese(16,1,0,32,Welcome);
	OLED_ShowCHinese(32,1,1,32,Welcome);
	OLED_ShowCHinese(48,1,2,32,Welcome);
	OLED_ShowCHinese(64,1,3,32,Welcome);
	OLED_ShowCHinese(80,1,4,32,Welcome);
	OLED_ShowCHinese(96,1,5,32,Welcome);
	delay_ms(500);
	OLED_Clear();
	
	OLED_ShowCHinese(16,1,0,32,Introduced);
	OLED_ShowCHinese(32,1,1,32,Introduced);
	OLED_ShowCHinese(48,1,2,32,Introduced);
	OLED_ShowCHinese(64,1,3,32,Introduced);
	
	OLED_ShowCHinese(16,3,4,32,Introduced);
	OLED_ShowCHinese(32,3,5,32,Introduced);
	OLED_ShowCHinese(48,3,6,32,Introduced);
	OLED_ShowCHinese(64,3,7,32,Introduced);
	OLED_ShowCHinese(80,3,8,32,Introduced);
	OLED_ShowCHinese(96,3,9,32,Introduced);
	delay_ms(1000);
	OLED_Clear();
		
	while(1)
	{
		OLED_DrawGIF(32,0,96,8,31,512,Pencil);
		OLED_DrawGIF(32,0,96,8,31,512,Pencil);
		delay_ms(200);
		OLED_DrawGIF(32,0,96,8,18,512,Rocket);
		OLED_DrawGIF(32,0,96,8,18,512,Rocket);
		delay_ms(200);
		OLED_DrawGIF(32,0,96,8,28,512,Bell);
		OLED_DrawGIF(32,0,96,8,28,512,Bell);
		delay_ms(200);
		
	}
}

效果如下
玩耍OLED(動圖)

挺好玩的對不對?來制作你的動圖吧!


祝大家新的一年里健健康康!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM