用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)
{
}
}
显示效果如下

2. 显示中文
取模软件用的是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)
{
}
}
显示效果如下

3. 显示图片
取模方式与显示中文一样,但是要转换成数组形式,就要变成单色(黑与白),而且大小应该在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)
{
}
}
显示效果如下

4. 显示动图
在网上找了一些512*512的GIF图,这样是没办法用的,需要降低分辨率和调成单色,而且还要提取帧
512*512动图下载地址:传送门(蓝奏云)
在这里用到的软件有很多,我用的是一个叫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);
}
}
显示效果如下:

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(动图)
挺好玩的对不对?来制作你的动图吧!
祝大家新的一年里健健康康!
用STM32玩OLED(显示文字、图片、动图gif等)的更多相关文章
- php生成文字图片效果
php生成文字图片效果最近看到php的GD功能,试着做了一个基本生成文字图片效果的代码: 显示文字图片页面:demo.php<?php$str = $_REQUEST['str'] ? $_RE ...
- 用STM32玩SR04(测距、串口显示、OLED显示)
目录 用STM32玩SR04(测距.串口显示.OLED显示) 超声波模块使用 SR04初始化 SR04使用串口打印数据 SR04使用OLED来传输数据,并显示在OLED上 用STM32玩SR04(测距 ...
- 致敬学长!J20航模遥控器开源项目计划【开局篇】 | 先做一个开机界面 | MATLAB图像二值化 | Img2Lcd图片取模 | OLED显示图片
我们的开源宗旨:自由 协调 开放 合作 共享 拥抱开源,丰富国内开源生态,开展多人运动,欢迎加入我们哈~ 和一群志同道合的人,做自己所热爱的事! 项目开源地址:https://github.com/C ...
- Qt中在图片上叠加显示文字
Qt中在图片上叠加显示文字 QCustLabel::QCustLabel(QWidget *parent):QLabel(parent){ setPixmap(QPixmap(QString::f ...
- VS2003 下GridControl的列显示成图片+文字的形式实现
public RC_CustomerSolicitListUC() { // 该调用是 Windows.Forms 窗体设计器所必需的. InitializeComponent(); // TODO: ...
- C#跑马灯,图片滚动,后台获取图片地址。动态绑定图片,imag显示文字
下面附下载地址. http://download.csdn.net/download/njxiaogui/10002058 1.跑马灯效果,图片连续循环滚动,图片下面并可附文字描述,图片是从数据库中获 ...
- 玩转X-CTR100 l STM32F4 l OLED显示-SSD1306无字库
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] OLED显示屏具有自发光特性,不需要背光, ...
- CSS实现文字半透明显示在图片上方法
CSS实现文字半透明显示在图片上方法 在css中文字半透明我们会需要使用滤镜效果也就是css中的filter:alpha来实现了,下面来看两个文字显示在图片上并且半透明的例子. CSS让一行文字显示在 ...
- iOS View自定义窍门——UIButton实现上显示图片,下显示文字
“UIButton实现上显示图片,下显示文字”这个需求相信大家在开发中都或多或少会遇见.比如自定义分享View的时候.当然,也可以封装一个item,上边imageView,下边一个label.但是既然 ...
随机推荐
- 各系统升级openssh
修订号: [V1.0] 修订人: [陈土锋] 修订日期: [2019.06.04] 前言 该文档只适用用于服务器Redhat,centos,Ubuntu和suse系统的openssh升级.需要注意必须 ...
- linux压缩打包、定时任务
压缩打包 gzip压缩 win中的压缩包:zip rar Linux常见的压缩包有哪些? gzip bzip2 1.gzip压缩 压缩命令:gzip [压缩文件] 解压命令:gzip -d [压缩包] ...
- 基于 Apache Hudi 构建增量和无限回放事件流的 OLAP 平台
1. 摘要 在本博客中,我们将讨论在构建流数据平台时如何利用 Hudi 的两个最令人难以置信的能力. 增量消费--每 30 分钟处理一次数据,并在我们的组织内构建每小时级别的OLAP平台 事件流的无限 ...
- unity 编辑器扩展简单入门
unity 编辑器扩展简单入门 通过使用编辑器扩展,我们可以对一些机械的操作实现自动化,而不用使用额外的环境,将工具与开发环境融为一体:并且,编辑器扩展也提供GUI库,来实现可视化操作:编辑器扩展甚至 ...
- 2022.02.20 SA
2022.02.20 SA 如果我还能看见明天黎明,如果我还能再爬起来,我仍会走我的路,哪怕这条路已经荒废许久,也许我们无法拥有感情,我们甚至无法像个正常人一样接受太阳的洗礼,但是我依然会执行我的条约 ...
- 解决vue安装less报错Failed to compile with 1 errors的问题
1.创建vue项目后安装less,执行 npm install less less-loader --save-dev 下载版本为:less-loader@6.1.0 , less@3.11.3,重启 ...
- php错误异常及其排错
错误和异常 错误 php程序自身的问题,一般是由非法的语法,环境问题导致 异常 一般是业务逻辑上出现的不合预期.与正常流程不同的状况,不是语法错误 错误异常继承关系 小括号表示php版本 php7下的 ...
- ucore lab4 内核线程管理 学习笔记
越学越简单,真是越学越简单啊 看视频的时候着实被那复杂的函数调用图吓到了.看代码的时候发现条理还是很清晰的,远没有没想象的那么复杂. 这节创建了俩内核线程,然后运行第一个线程,再由第一个切换到第二个. ...
- ReadWriteLock 接口详解
ReadWriteLock 接口详解 这是本人阅读ReadWriteLock接口源码的注释后,写出的一篇知识分享博客 读写锁的成分是什么? 读锁 Lock readLock(); 只要没有写锁,读锁可 ...
- 一篇文章教你搞懂日志采集利器 Filebeat
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 本文使用的Filebeat是7.7.0的版本,文章将从如下几个方面说明: Filebeat是什 ...