stm32教程:OLED屏显示字母、汉字、图片工程讲解

早上好啊,大佬们,今天带来的是我们 stm32系列的第一个外设——OLED,相信大家对于OLED都不陌生了吧,这个可以说每一个项目里的必需品了,单片机离不开OLED就像西方离不开耶路撒冷。

在生活中,我们见到的OLED的显示屏数不胜数,现在手机的显示屏也逐渐更换成了OLED的屏幕,电视啊,电脑显示屏啊,广场大屏啊,很多很多产品的显示屏都已经开始使用OLED屏了,它被人们称誉为“梦幻显示器”。

像是这些就是现在最好的显示屏了。

所以,我们今天就来接触一下现在的高端产品。

就算不谈那么长远的厉害的事情,我们但从学习stm32的历程中也绕不开OLED屏,不论是制作毕业设计也好,制作一个自己想要的小创意也罢,对于图像显示总是必须的。

那么我们就从头开始了解OLED吧。

什么是OLED?

Organic Light Emitting Display,即有机发光显示器,在手机LCD上属于新崛起的种类,被誉为“梦幻显示器”。

OLED也被称之为第三代显示技术。OLED不仅更轻薄、能耗低、亮度高、发光率好、可以显示纯黑色,并且还可以做到弯曲,如当今的曲屏电视和手机等。当今国际各大厂商都争相恐后的加强了对OLED技术的研发投入,使得OLED技术在当今电视、电脑(显示器)、手机、平板等领域里应用愈加广泛。

2022年7月,苹果将在未来几年将OLED屏幕引入其iPad系列中。苹果即将推出的2024款iPad设计新型OLED显示面板。这一过程使OLED显示面板更薄更轻。

(来源于百度百科)

相较于LCD屏的优势

经常对于一个新技术,我们会将它和上一代技术进行比对,通过两者的优劣势来选择更优的产品。

相比传统的LCD技术,OLED显示技术具有明显的优势,OLED屏幕厚度可以控制在1mm以内,而LCD屏幕厚度通常在3mm左右,并且重量更加轻盈。OLED屏幕的液态结构可以保证屏幕的抗衰性能,并且具有LCD不具备的广视角,可以实现超大范围内观看同一块屏幕,画面不会失真。响应时间是LCD屏幕的千分之一。并且OLED屏幕耐低温,可以在-40℃环境下正常显示内容,发光效率更高、能耗低、生态环保,可以制作成曲面屏,从而给人们带来不同的视觉冲击。 

(来源于百度百科)


想必上面的那些内容,大家都不想看吧。

下面我们就来点干货吧,先给大家提供代码历程,然后会教大家怎么用。

在这里,我就不得不提一个大大了, 就是江协科技,相信大家学习stm32和51单片机的时候或多或少都看过这位大大的视频,不得不说,这个大大真的很厉害,如果大家想要更好地学习stm32的内容,可以看看这位大大的视频,当然不要抛弃小白兔喔。

工程介绍

我们选用0.96寸的OLED显示屏为例(该代码适用于SSD1306,SSD1315, SH1106这几种芯片的oled屏),出于它有两个版本的型号,一种是基于I2C协议的四针版本,另一种是基于SPI协议的七针版本。这里提供两种版本的代码。

在最后小白兔会提供代码的链接,里面有两个内容,一个是江协科技的大大的示例工程,另一个是本期里面的所有示例。

由于大大现在更新的代码的最新版本是V2,所以小白兔下面的代码都是以这个版本为例,当然前面的版本大差不差,而且大大的注释写的很好,封装的简直完美,所以相信大佬们也都能灵活使用的。

OLED引脚接线

四针I2C OLED

七针SPI OLED

选择代码的时候选择对应的即可

代码导入方法

就比如说,我们要将这个代码加入到我们的工程模板中。

0.96寸OLED显示屏\01-程序源码\01-程序源码\OLED-V2.0\GB2312\01-OLED功能函数测试-4针脚I2C接口\Hardware

 将这四个文件复制粘贴到我们的工程模板的Hardware文件夹下。

软件里面添加进来就可以了。

编码格式选择

对于常用的 GB2312 和 UTF-8 两种格式的编码格式,我们需要进行一些操作。

首先选择你喜欢的编码格式

UTF-8

--no-multibyte-chars

GB2312

 代码使用方法

我们以四针 I2C协议的 UTF-8编码格式的工程为例。

首先无论你的代码是什么样子的,只要你需要使用OLED,就需要加上这些代码:

#include "stm32f10x.h"                  // Device header
#include "OLED.h"        //导入OLED.h

int main()
{
	OLED_Init();        //初始化OLED
	
	while(1)
	{
		
	}
	
}

然后下面我们就来尝试一下大大的这些函数。

/*初始化函数*/
void OLED_Init(void);

/*更新函数*/
void OLED_Update(void);
void OLED_UpdateArea(int16_t X, int16_t Y, uint8_t Width, uint8_t Height);

/*显存控制函数*/
void OLED_Clear(void);
void OLED_ClearArea(int16_t X, int16_t Y, uint8_t Width, uint8_t Height);
void OLED_Reverse(void);
void OLED_ReverseArea(int16_t X, int16_t Y, uint8_t Width, uint8_t Height);

/*显示函数*/
void OLED_ShowChar(int16_t X, int16_t Y, char Char, uint8_t FontSize);
void OLED_ShowString(int16_t X, int16_t Y, char *String, uint8_t FontSize);
void OLED_ShowNum(int16_t X, int16_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowSignedNum(int16_t X, int16_t Y, int32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowHexNum(int16_t X, int16_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowBinNum(int16_t X, int16_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowFloatNum(int16_t X, int16_t Y, double Number, uint8_t IntLength, uint8_t FraLength, uint8_t FontSize);
void OLED_ShowImage(int16_t X, int16_t Y, uint8_t Width, uint8_t Height, const uint8_t *Image);
void OLED_Printf(int16_t X, int16_t Y, uint8_t FontSize, char *format, ...);

/*绘图函数*/
void OLED_DrawPoint(int16_t X, int16_t Y);
uint8_t OLED_GetPoint(int16_t X, int16_t Y);
void OLED_DrawLine(int16_t X0, int16_t Y0, int16_t X1, int16_t Y1);
void OLED_DrawRectangle(int16_t X, int16_t Y, uint8_t Width, uint8_t Height, uint8_t IsFilled);
void OLED_DrawTriangle(int16_t X0, int16_t Y0, int16_t X1, int16_t Y1, int16_t X2, int16_t Y2, uint8_t IsFilled);
void OLED_DrawCircle(int16_t X, int16_t Y, uint8_t Radius, uint8_t IsFilled);
void OLED_DrawEllipse(int16_t X, int16_t Y, uint8_t A, uint8_t B, uint8_t IsFilled);
void OLED_DrawArc(int16_t X, int16_t Y, uint8_t Radius, int16_t StartAngle, int16_t EndAngle, uint8_t IsFilled);

字体显示大小 

首先我们先讲一个字体大小,也就是OLED_6X8 和 OLED_8X16。

    //基本所有的函数的前两个参数都是定位在显示屏的哪个位置。
    //然后大大这边给了两个大小的字
    //也就是OLED_8X16    和 OLED_6X8
    //简单而言就是 长 * 宽,所以如果相隔的显示字符之间要相隔
    //横向为 8 | 6; 纵向为 16 | 8

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

int main()
{
	OLED_Init();
	//基本所有的函数的前两个参数都是定位在显示屏的哪个位置。
	//然后大大这边给了两个大小的字
	//也就是OLED_8X16	和 OLED_6X8
	//简单而言就是 长 * 宽,所以如果相隔的显示字符之间要相隔
	//横向为 8 | 6; 纵向为 16 | 8
	OLED_ShowChar(0, 0, 'A', OLED_6X8);
	OLED_ShowChar(6, 8, 'A', OLED_8X16);
	
	OLED_Update(); //每次修改显示内容的后面都需要这一句,否则就不会变。
	while(1)
	{
		
	}
	
}

显示字符(英文字符及半角符号)

字符的显示使用到的是这两个函数:

void OLED_ShowChar(int16_t X, int16_t Y, char Char, uint8_t FontSize);
void OLED_ShowString(int16_t X, int16_t Y, char *String, uint8_t FontSize);

在V2.0的版本里的函数,字符和汉字能够同时使用了,但是在前面的版本里是不行,所以,我在这里还是分开进行讲解。

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

int main()
{
	OLED_Init();//函数定义初始化
	
	OLED_ShowChar(0, 0, 'S', OLED_8X16); //这个函数只能显示一个字符
	
	OLED_ShowString(0, 16, "bunny girl", OLED_8X16); //这是是显示一个字符串。
	
	OLED_Update(); //及时更新显示
	while(1)
	{
		
	}
	
}

 

显示数字

这里的数字分为了五种显示:
无符号整型; 有符号整型; 16进制整型; 2进制整型; 浮点型

void OLED_ShowNum(int16_t X, int16_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowSignedNum(int16_t X, int16_t Y, int32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowHexNum(int16_t X, int16_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowBinNum(int16_t X, int16_t Y, uint32_t Number, uint8_t Length, uint8_t FontSize);
void OLED_ShowFloatNum(int16_t X, int16_t Y, double Number, uint8_t IntLength, uint8_t FraLength, uint8_t FontSize);
#include "stm32f10x.h"                  // Device header
#include "OLED.h"

int main()
{
	OLED_Init();//函数定义初始化
	
	//无符号整型
	//参数为 y轴,x轴,数字,显示数字的长度,字体大小
	OLED_ShowNum(0,0, 15, 2, OLED_6X8);
	
	//有符号整型
	//y轴,x轴,数字,显示数字的长度(不包括符号),字体大小
	OLED_ShowSignedNum(0, 8, -25, 2, OLED_6X8);
	OLED_ShowSignedNum(0, 8, 35, 2, OLED_6X8);
	
	//16进制整型
	//y轴,x轴,数字(显示时会转换为16进制显示),显示数字的长度,字体大小
	OLED_ShowHexNum(0, 16, 46, 2, OLED_6X8);
	
	//2进制整型
	//y轴,x轴,数字(显示时会转换成2进制显示),显示数字的长度,字体大小
	OLED_ShowBinNum(0, 24, 15, 8, OLED_6X8);
	
	//浮点型
	//浮点型参数为 y轴,x轴,数字,整数部分的长度,小数部分长度,字体大小
	OLED_ShowFloatNum(0, 32, 3.1415926, 1, 7, OLED_6X8);
	
	
	//如果显示数字长度 与 真实数字长度不符
	//如果显示数字长度 > 真实数字长度, 会在数字前用0补足长度
	OLED_ShowHexNum(0, 48, 46, 5, OLED_6X8);
	
	//如果显示数字长度 < 真实数字长度, 会省略前面的数字
	OLED_ShowSignedNum(0, 56, 35, 1, OLED_6X8);
	
	OLED_Update(); //及时更新显示
	while(1)
	{
		
	}
	
}

显示汉字(包括全角字符)

在V1.x的版本里汉字和英文字符是不能同时显示的,但是在V2的版本里,大大将两种显示合在一起了。

V1.x里显示汉字使用的是:

void OLED_ShowChinese(uint8_t X, uint8_t Y, char *Chinese);

V2里显示汉字使用的是:

void OLED_ShowString(int16_t X, int16_t Y, char *String, uint8_t FontSize);

并且在V2里面,字符和汉字能够同时进行显示了。

在两个版本里显示方法基本是一样的, 这里我们就只展示V2的显示。

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

int main()
{
	OLED_Init();//函数定义初始化
	
	
	OLED_ShowString(0, 0, "你好,世界。", OLED_8X16);
	//如果是V1.x的话,这句话换成——
	//OLED_ShowChinese(0, 48, "你好,世界。");
	//就可以了
	
	//下面的写法在V1中不能使用
	OLED_ShowString(0, 16, "123,ni hao, 世界。", OLED_8X16);
	
	
	//然后汉字的显示只有8X16的,不能修改成6X8,否则汉字部分会变成?
	OLED_ShowString(0, 32, "123,ni hao, 世界。", OLED_6X8);
	
	OLED_Update(); //及时更新显示
	while(1)
	{
		
	}
	
}

然后,在起初,我们想要显示汉字只能显示大大预存的汉字,也就是下面这些。

const ChineseCell_t OLED_CF16x16[] = {
	
	",",
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x58,0x38,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,0x00,
	0x00,0x00,0x18,0x24,0x24,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	
	"你",
	0x00,0x80,0x60,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,
	0x01,0x00,0x00,0xFF,0x00,0x10,0x0C,0x03,0x40,0x80,0x7F,0x00,0x01,0x06,0x18,0x00,
	
	"好",
	0x10,0x10,0xF0,0x1F,0x10,0xF0,0x00,0x80,0x82,0x82,0xE2,0x92,0x8A,0x86,0x80,0x00,
	0x40,0x22,0x15,0x08,0x16,0x61,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,
	
	"世",
	0x20,0x20,0x20,0xFE,0x20,0x20,0xFF,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0x00,
	0x00,0x00,0x00,0x7F,0x40,0x40,0x47,0x44,0x44,0x44,0x47,0x40,0x40,0x40,0x00,0x00,
	
	"界",
	0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0xFE,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,0x00,
	0x08,0x08,0x04,0x84,0x62,0x1E,0x01,0x00,0x01,0xFE,0x02,0x04,0x04,0x08,0x08,0x00,
	
	/*按照上面的格式,在这个位置加入新的汉字数据*/
	//...
	
	
	/*未找到指定汉字时显示的默认图形(一个方框,内部一个问号),请确保其位于数组最末尾*/
	"",		
	0xFF,0x01,0x01,0x01,0x31,0x09,0x09,0x09,0x09,0x89,0x71,0x01,0x01,0x01,0x01,0xFF,
	0xFF,0x80,0x80,0x80,0x80,0x80,0x80,0x96,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0xFF,

};

 如果我们想要显示其他的汉字,就需要我们自己对汉字进行取模。

那么我们怎么取模呢,嘿嘿,大大也给我们提供了取模的软件。

汉字取模

0.96寸OLED显示屏\03-取模软件\PCtoLCD2002

 

软件也就是这样的一个东西。

1、在模式处选择字符模式

内容配置要和下图一样:

点阵格式:阴码

取模方式:列行式

每行显示数据:16

                         16

取模走向:逆向

输出数制:十六进制

输出选项 和 液晶面板仿真随意

自定义格式选择C51格式

在行前缀和行后缀处,将花括号 { } 去掉

然后保存就好了

然后生成字模即可。

生成出来的东西就是这样的:

 黑(0) 不(1) 拉(2) 几(3) 的(4) 小(5) 白(6) 兔(7)

0x00,0x00,0x3E,0x22,0x2A,0x32,0x22,0xFE,0x22,0x32,0x2A,0x22,0x3E,0x00,0x00,0x00,
0x88,0x68,0x09,0x09,0x29,0xC9,0x09,0x0F,0x29,0xC9,0x09,0x09,0x29,0xC8,0x08,0x00,/*"黑",0*/

0x00,0x02,0x02,0x02,0x02,0x82,0x42,0xF2,0x0E,0x42,0x82,0x02,0x02,0x02,0x00,0x00,
0x10,0x08,0x04,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0x01,0x02,0x0C,0x00,0x00,/*"不",1*/

0x10,0x10,0x10,0xFF,0x90,0x40,0x10,0x90,0x10,0x11,0x16,0x10,0x10,0xD0,0x10,0x00,
0x02,0x42,0x81,0x7F,0x00,0x40,0x40,0x41,0x5E,0x40,0x40,0x70,0x4E,0x41,0x40,0x00,/*"拉",2*/

0x00,0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x00,
0x80,0x40,0x30,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x78,0x00,/*"几",3*/

0x00,0xF8,0x0C,0x0B,0x08,0x08,0xF8,0x40,0x30,0x8F,0x08,0x08,0x08,0xF8,0x00,0x00,
0x00,0x7F,0x21,0x21,0x21,0x21,0x7F,0x00,0x00,0x00,0x43,0x80,0x40,0x3F,0x00,0x00,/*"的",4*/

0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00,
0x08,0x04,0x03,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00,/*"小",5*/

0x00,0x00,0xF8,0x08,0x08,0x0C,0x0A,0x09,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,
0x00,0x00,0xFF,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0xFF,0x00,0x00,0x00,/*"白",6*/

0x40,0x20,0xF0,0x28,0x27,0x24,0x24,0xE4,0x24,0x34,0x2C,0x20,0xE0,0x00,0x00,0x00,
0x80,0x80,0x47,0x22,0x12,0x0A,0x06,0x03,0x7E,0x82,0x8A,0xB2,0x87,0x80,0xE0,0x00,/*"兔",7*/

然后对它进行一些调整

    "黑",
	0x00,0x00,0x3E,0x22,0x2A,0x32,0x22,0xFE,0x22,0x32,0x2A,0x22,0x3E,0x00,0x00,0x00,
	0x88,0x68,0x09,0x09,0x29,0xC9,0x09,0x0F,0x29,0xC9,0x09,0x09,0x29,0xC8,0x08,0x00,

	"不",
	0x00,0x02,0x02,0x02,0x02,0x82,0x42,0xF2,0x0E,0x42,0x82,0x02,0x02,0x02,0x00,0x00,
	0x10,0x08,0x04,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0x01,0x02,0x0C,0x00,0x00,

	"拉",
	0x10,0x10,0x10,0xFF,0x90,0x40,0x10,0x90,0x10,0x11,0x16,0x10,0x10,0xD0,0x10,0x00,
	0x02,0x42,0x81,0x7F,0x00,0x40,0x40,0x41,0x5E,0x40,0x40,0x70,0x4E,0x41,0x40,0x00,

	"几",
	0x00,0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x00,
	0x80,0x40,0x30,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x78,0x00,

	"的",
	0x00,0xF8,0x0C,0x0B,0x08,0x08,0xF8,0x40,0x30,0x8F,0x08,0x08,0x08,0xF8,0x00,0x00,
	0x00,0x7F,0x21,0x21,0x21,0x21,0x7F,0x00,0x00,0x00,0x43,0x80,0x40,0x3F,0x00,0x00,

	"小",
	0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00,
	0x08,0x04,0x03,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00,

	"白",
	0x00,0x00,0xF8,0x08,0x08,0x0C,0x0A,0x09,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,
	0x00,0x00,0xFF,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0xFF,0x00,0x00,0x00,

	"兔",
	0x40,0x20,0xF0,0x28,0x27,0x24,0x24,0xE4,0x24,0x34,0x2C,0x20,0xE0,0x00,0x00,0x00,
	0x80,0x80,0x47,0x22,0x12,0x0A,0x06,0x03,0x7E,0x82,0x8A,0xB2,0x87,0x80,0xE0,0x00,

添加到这个数组中,也就是变成:

然后就可以进行输出了。

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

int main()
{
	OLED_Init();//函数定义初始化
	
	
	OLED_ShowString(0, 0, "你好,世界。", OLED_8X16);
	//如果是V1.x的话,这句话换成——
	//OLED_ShowChinese(0, 48, "你好,世界。");
	//就可以了
	
	//下面的写法在V1中不能使用
	OLED_ShowString(0, 16, "123,ni hao, 世界。", OLED_8X16);
	
	
	//然后汉字的显示只有8X16的,不能修改成6X8,否则汉字部分会变成?
	OLED_ShowString(0, 32, "123,ni hao, 世界。", OLED_6X8);
	
	OLED_ShowString(0, 48, "你好,小白兔", OLED_8X16);
	
	OLED_Update(); //及时更新显示
	while(1)
	{
		
	}
	
}

显示图片

void OLED_ShowImage(int16_t X, int16_t Y, uint8_t Width, uint8_t Height, const uint8_t *Image);

显示图片的操作和汉字很像。

因为我们使用的屏是黑白色的,所以在显示之前要先二值化去色,然后调整图像大小,取出图片后再取模,然后就可以了。

OK,不多废话,直接展示一下吧就~

小白兔这边使用的是PS。

按照如下选择阈值。

然后选择阈值范围,大于阈值的会呈现白色,小于阈值的会呈现黑色。

然后是调整图像大小

 这是原倍率下的图片,乐了,好小啊……

这里的参数选择默认的就行了

 

在取模软件里选中这个bmp文件,然后生成字模就可以了。

0x00,0x00,0x00,0x00,0x80,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xE0,0x60,0xE0,0xF0,0xF8,
0xF8,0xFC,0xFC,0xFE,0x06,0x06,0x06,0x06,0x06,0x06,0xF6,0xFE,0xFC,0xFC,0xFC,0xFC,
0xFC,0xFC,0x3C,0x36,0x26,0x06,0x06,0x06,0xF7,0xFF,0x1E,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1F,0x3B,
0xF1,0xC1,0x81,0xE1,0x72,0x9B,0xFD,0xFE,0x0E,0x07,0x07,0xE7,0xE3,0xF3,0xF1,0xF1,
0xFE,0xFE,0x7E,0x7E,0x7E,0xFC,0xF0,0xF1,0xF1,0xF3,0xE3,0x03,0x03,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0x3F,0xFC,0xC0,0x7C,0x7C,0xF0,0xE8,0x60,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xF8,0xFF,0x0F,0x03,0x07,
0x0F,0x0D,0x0D,0x0F,0x9F,0x9E,0xCE,0xFD,0xFF,0xFF,0xBF,0xFF,0xFF,0x3F,0x06,0x06,
0x06,0xC7,0xFF,0xFF,0xFF,0xFB,0x78,0x78,0xF0,0xF0,0xE0,0x60,0xC0,0xC0,0x80,0x80,
0x00,0x00,0x01,0x1F,0xFE,0xE1,0x0F,0xEE,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x38,0x7F,0xEF,0xC0,0x80,0x80,0xC0,0xF8,0xF8,0xEE,0x7B,
0xFF,0xF9,0x3E,0xEF,0xFE,0x3E,0x3F,0xFF,0xEF,0x70,0x38,0x1C,0x0F,0x0F,0x06,0x0F,
0x6F,0xFF,0xBF,0xBF,0xBF,0x9F,0xFF,0xFD,0x00,0x00,0xFD,0xFB,0xFF,0xBC,0x38,0xB0,
0xDF,0xFF,0x7C,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x03,0x0F,0x1C,0x38,0xFF,0xDF,0xF0,0xFF,0xFF,0xFE,0xF9,
0xDB,0xCB,0x8B,0x83,0x80,0x00,0x00,0x30,0x30,0x30,0x00,0x80,0x80,0xC0,0xC5,0xE7,
0xFD,0xFF,0xFF,0xEF,0xF0,0xBE,0xCF,0xFF,0xFF,0xFD,0xFE,0xFF,0xFF,0xFE,0xFE,0xFE,
0xFE,0xFE,0xFE,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x03,0x77,0xFF,0xFD,0xFB,0x1F,
0x1F,0xDB,0xFB,0x7F,0xFF,0xFB,0x3F,0xFF,0xED,0x86,0x06,0xE6,0xDF,0xFF,0x7F,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xBF,0xFF,0xDF,0xFF,
0xEF,0x1F,0xBF,0xFF,0xDF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xE0,0xF0,0x30,0xFF,0xFF,0xFF,0xBC,0xBC,0xA6,0xB6,0xB7,
0xA7,0xFD,0xEC,0xEC,0xFD,0x9F,0xE6,0xFF,0xFF,0xFF,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,
0xF0,0xF0,0xF0,0xF2,0xFF,0xF7,0xF9,0xFB,0xFF,0x7C,0x7E,0x7E,0x3F,0x3F,0x1F,0x1F,
0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x03,0x06,0x06,0x07,0x03,0x03,0x03,0x03,0x03,0x03,0x07,0x0F,0x0C,0x0D,
0x0D,0x0D,0x07,0x07,0x03,0x03,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

将它添加到OLED_Data.c文件里。

 在OLED_Data.h文件下添加数组名。

然后代码显示很容易:

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

int main()
{
	OLED_Init();//函数定义初始化
	
	OLED_ShowImage(0, 0, 60, 60, creeper);
	
	OLED_Update(); //及时更新显示
	while(1)
	{
		
	}
	
}

 OK,图像的显示就这么多。

后面说一下printf 形式的显示。

printf形式

这个模式的输出,除了汉字和图像不能输出之外都能输出,形式也很简单,就和C语言的printf是一样的。

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

int main()
{
	OLED_Init();//函数定义初始化
	
	OLED_Printf(0, 0, OLED_8X16, "%d   %c", 10, 'A');
	OLED_Printf(0, 16, OLED_8X16, "%x  %.2f", 0x12, 1.23);
	OLED_Update(); //及时更新显示
	while(1)
	{
		
	}
	
}

总结

OK,那么这一期就到这里,内容很多,但是对于OLED的内容还没有结束,OLED上还能自行绘制图像,这个我们下一期再说,期待一下吧~

那么最后,小白兔提供一下这一期里的代码工程文件,以及江协科技大大的OLED文件,大家可以下载一下。
链接:https://pan.quark.cn/s/205eec7346b8
提取码:PWwz

Bye,Bye~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/917034.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣 LeetCode 28. 找出字符串中第一个匹配项的下标(Day4:字符串)

解题思路&#xff1a; KMP算法 需要先求得最长相等前后缀&#xff0c;并记录在next数组中&#xff0c;也就是前缀表&#xff0c;前缀表是用来回退的&#xff0c;它记录了模式串与主串(文本串)不匹配的时候&#xff0c;模式串应该从哪里开始重新匹配。 next[ j - 1 ] 记录了 …

我与Linux的爱恋:进程间通信 匿名管道

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;Linux的学习 文章目录 匿名管道pipe 匿名管道 匿名管道&#xff08;Anonymous Pipes&#xff09;是Unix和类Unix操作系统中的一种通信机制&#xff0c;用于在两个进程之间传递数据。匿名…

Java之JDBC,Maven,MYBatis

前言 就是用来操作数据库的 1.JDBC快速入门 注意在使用前一定要导入jar包 在模块那里新建目录&#xff0c;新建lib&#xff0c;粘贴复制jar包&#xff0c;我这个jar设置的是模块有效 package test1017;import java.sql.Connection; import java.sql.DriverManager; import…

基于Matlab的碎纸片的自动拼接复原技术

碎纸片的自动拼接复原技术 摘要&#xff1a;破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。目前发现对碎纸片的拼接大部分由人工完成&#xff0c;准确率较高&#xff0c;但耗费大量人力财力及时间&#xff0c;效率很低。随着计算机技术的…

STM32 设计的较为复杂的物联网项目,包括智能家居控制系统,涵盖了硬件和软件的详细设计。

使用 STM32 设计的较为复杂的物联网项目&#xff0c;包括智能家居控制系统&#xff0c;涵盖了硬件和软件的详细设计。 一、硬件设计 微控制器&#xff1a;选择 STM32F4 系列微控制器&#xff0c;如 STM32F407ZGT6&#xff0c;具有高性能和丰富的外设资源。 传感器模块&#x…

1.7 JS性能优化

从输入url到页面加载完成都做了些什么 输入 URL - 资源定位符 http://www.zhaowa.com - http 协议 域名解析 https://www.zhaowa.com > ip 1. 切HOST&#xff1f; > 浏览器缓存映射、系统、路由、运营商、根服务器 2. 实际的静态文件存放&#xff1f; 大流量 > 多个…

LPDDR4芯片学习(四)——DDR Training

一、ZQ Calibration DDR 学习时间 (Part B - 6)&#xff1a;DRAM ZQ 校正 - 知乎 (zhihu.com) 从原理上解释什么是DDR的ZQ校准&#xff1f; - 知乎 (zhihu.com) LPDDR4的训练(training)和校准(calibration)--ZQ校准(Calibration)_wonder_coole-腾讯云开发者社区 01 ZQ校准的…

pycharm分支提交操作

一、Pycharm拉取Git远程仓库代码 1、点击VCS > Get from Version Control 2、输入git的url&#xff0c;选择自己的项目路径 3、点击Clone&#xff0c;就拉取成功了 默认签出分支为main 选择develop签出即可进行开发工作 二、创建分支&#xff08;非必要可以不使用&#xf…

鸿蒙实战:页面跳转

文章目录 1. 实战概述2. 实现步骤2.1 创建项目2.2 准备图片素材2.3 编写首页代码2.4 创建第二个页面 3. 测试效果4. 实战总结 1. 实战概述 实战概述&#xff1a;本实战通过ArkUI框架&#xff0c;在鸿蒙系统上开发了一个简单的两页面应用。首页显示问候语和“下一页”按钮&…

IDEA部署AI代写插件

前言 Hello大家好&#xff0c;当下是AI盛行的时代&#xff0c;好多好多东西在AI大模型的趋势下都变得非常的简单。 比如之前想画一幅风景画得先去采风&#xff0c;然后写实什么的&#xff0c;现在你只需描述出你想要的效果AI就能够根据你的描述在几分钟之内画出一幅你想要的风景…

深入理解 Spark 中的 Shuffle

Spark 的介绍与搭建&#xff1a;从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交&#xff1a;本地与集群模式全解析-CSDN博客 Spark on YARN&#xff1a;Spark集群模式…

常用在汽车PKE无钥匙进入系统的高度集成SOC芯片:CSM2433

CSM2433是一款集成2.4GHz频段发射器、125KHz接收器和8位RISC&#xff08;精简指令集&#xff09;MCU的SOC芯片&#xff0c;用在汽车PKE无钥匙进入系统里。 什么是汽车PKE无钥匙进入系统&#xff1f; 无钥匙进入系统具有无钥匙进入并且启动的功能&#xff0c;英文名称是PKE&…

人力资源招聘系统-提升招聘效率与质量的关键工具

在当今这个竞争激烈的商业环境中&#xff0c;企业要想在市场中立于不败之地&#xff0c;关键在于拥有高素质的人才队伍。然而&#xff0c;传统的招聘方式往往效率低下&#xff0c;难以精准匹配企业需求与人才特质&#xff0c;这无疑给企业的发展带来了不小的挑战。 随着科技的飞…

R语言贝叶斯分析:INLA 、MCMC混合模型、生存分析肿瘤临床试验、间歇泉喷发时间数据应用|附数据代码...

全文链接&#xff1a;https://tecdat.cn/?p38273 多模态数据在统计学中并不罕见&#xff0c;常出现在观测数据来自两个或多个潜在群体或总体的情况。混合模型常用于分析这类数据&#xff0c;它利用不同的组件来对数据中的不同群体或总体进行建模。本质上&#xff0c;混合模型是…

算法--解决二叉树遍历问题

第一 实现树的结构 class Node(): # 构造函数&#xff0c;初始化节点对象&#xff0c;包含数据和左右子节点 def __init__(self, dataNone): self.data data # 节点存储的数据 self.left None # 左子节点&#xff0c;默认为None self.rig…

华为eNSP:MSTP

一、什么是MSTP&#xff1f; 1、MSTP是IEEE 802.1S中定义的生成树协议&#xff0c;MSTP兼容STP和RSTP&#xff0c;既可以快速收敛&#xff0c;也提供了数据转发的多个冗余路径&#xff0c;在数据转发过程中实现VLAN数据的负载均衡。 2、MSTP可以将一个或多个VLAN映射到一个Inst…

从零到一:利用 AI 开发 iOS App 《震感》的编程之旅

在网上看到一篇关于使用AI开发的编程经历&#xff0c;分享给大家 作者是如何在没有 iOS 开发经验的情况下&#xff0c;借助 AI&#xff08;如 Claude 3 模型&#xff09;成功开发并发布《震感》iOS 应用。 正文开始 2022 年 11 月&#xff0c;ChatGPT 诞生并迅速引发全球关注。…

C++__day1

1、思维导图 2、如果登录失败&#xff0c;提示用户登录失败信息&#xff0c;并且提示错误几次&#xff0c;且重新输入&#xff1b;如果输入错误三次&#xff0c;则退出系统 #include <iostream> using namespace std;int main() {string id , pswd;string user"admi…

MySQL45讲 第二十讲 幻读是什么,幻读有什么问题?

文章目录 MySQL45讲 第二十讲 幻读是什么&#xff0c;幻读有什么问题&#xff1f;一、幻读的定义二、幻读带来的问题&#xff08;一&#xff09;语义问题&#xff08;二&#xff09;数据一致性问题 三、InnoDB 解决幻读的方法四、总结 MySQL45讲 第二十讲 幻读是什么&#xff0…

web与网络编程

使用HTTP协议访问Web 通过发送请求获取服务器资源的Web浏览器等&#xff0c;被成为客户端(client)。 Web使用一种名为HTTP(超文本传输协议)的协议作为规范&#xff0c;完成从客户端到服务器端等一系列运作流程。 可以说&#xff0c;Web时建立在HTTP协议上通信的。 网络基础T…