用STM32玩OLED(显示文字、图片、动图gif等)
阅读原文时间:2023年07月09日阅读:1

目录

用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)

/*
    @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)
    {

    }
}

显示效果如下

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

下载地址:传送门(蓝奏云)

程序方面修改了例程,让程序功能变得更直接

/*
    @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)
    {

    }
}

显示效果如下

取模方式与显示中文一样,但是要转换成数组形式,就要变成单色(黑与白),而且大小应该在128*64内,我用的软件是Img2Lcd

下载地址:传送门(蓝奏云)

设置效果如下

测试图片是一本书,网上找的,大小是48*48

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)
    {

    }
}

显示效果如下

在网上找了一些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);
    }
}

显示效果如下:

测试代码:

#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(动图)

挺好玩的对不对?来制作你的动图吧!


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

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章