STM32配合CubeMX硬件SPI驱动0.96寸OLED

目录

一、简单介绍

1.1 OLED

1.2 SPI协议

接口

优点

缺点

数据传输

二、实战

2.1 工程配置

2.2 测试工程

2.3 波形分析

三、驱动OLED

3.1 初始化代码

3.2 清屏函数

3.3 设置坐标函数

3.4 显示字符函数

3.5 显示字符串函数

3.6 显示图片函数

附录 驱动代码文件

oled.c

oled.h

f6x8.h

一、简单介绍

1.1 OLED

有机发光二极管(英语:Organic Light-Emitting Diode,缩写:OLED)又称有机电激发光显示(英语:Organic Electroluminescence Display,缩写:OELD)、有机发光半导体,OLED技术最早于1950年代和1960年代由法国人和美国人研制,其后由美国柯达及英国剑桥大学加以演进,日本SONY及韩国三星LG等公司于21世纪开始量产,现在的市场都趋近于OLED但是在寿命上比LCD短。[来源请求]

OLED(有机发光二极管)与TFT-LCD(薄膜晶体管液晶显示器)为不同类型的产品,OLED具有自发光性、广视角、高对比、低耗电、高反应速率、全彩化及制程简单等优点,但相对的在大面板价格、技术选择性 、寿命、分辨率色彩还原方面便无法与TFT-LCD匹敌,有机发光二极管显示器可分单色、多彩及全彩等种类,而其中以全彩制作技术最为困难。

OLED显示器依驱动方式的不同又可分为被动式(Passive Matrix,PMOLED)与主动式(Active Matrix,AMOLED)。

笔者使用的oled如上图,七针脚SPI协议,主控为SSD1306

规格为0.96寸,分辨率为128*64

1.2 SPI协议

串行外设接口(Serial Peripheral Interface Bus,SPI),是一种用于芯片通信的同步串行通信接口规范,主要应用于单片机系统中。类似I²C。 这种接口首先由摩托罗拉公司于20世纪80年代中期开发,后发展成了行业规范。它的典型应用有闪存[1][2]EEPROMSD卡液晶显示器

SPI设备之间使用全双工模式通信,是一个主机和一个或多个从机的主从模式。主机负责初始化,这个数据传输帧可以用于读与写两种操作,片选线路可以从多个从机选择一个来响应主机的请求。

有时SPI接口被称作四线式接口,这是为了与其他不同线制的数据传输接口加以区分。SPI准确来讲应为“同步串行接口”,但是它又与同步串行接口协议(SSI)是完全不同的两种协议。虽然SSI也是一个四线式同步通信协议,但是它使用差分信号,而且仅提供一个单工通信信道。于此相对地,SPI是一个单主机多从机的通信接口。

SPI是一种事实标准,也就是说这种规范没有对应的技术标准。因此各个厂家生产的SPI器件配置不一样,不一定有互操作性

接口

SPI总线规定了4个保留逻辑信号接口:

  • SCLK(Serial Clock):串列时脉,由主机发出
  • MOSI(Master Output, Slave Input):主机输出从机输入信号(数据由主机发出)
  • MISO(Master Input, Slave Output):主机输入从机输出信号(数据由从机发出)
  • SS(Slave Select):片选信号,由主机发出,一般是低电位有效

尽管上面的引脚名称是最常用的,但在过去,有时会使用其他引脚命名方式,因此旧的集成电路产品的SPI端口引脚名称可能有所不同。

优点
  • SPI协议默认是全双工通信。
  • 漏极开路输出相反,SPI的推挽输出可提供良好的信号完整性和高速度
  • I²CSMBus更高的传输带宽 。 不限于任何最大时钟频率,可实现高速运行
  • 完整的传输位协议灵活性
    • 不限于8位字
    • 任意选择消息大小,内容和目的地
  • 简单的线路连接
    • 由于电路较少(包括上拉电阻),因此通常比I²C或SMBus的功耗要低,
    • 没有仲裁或相关的失败模式
    • 从站与主机使用同一主频来源,不需要各自配置精密振荡器
    • 从站不需要唯一的地址 - 不像I²CGPIBSCSI
    • 不需要收发器
  • IC封装只使用四个引脚,而电路板布局或连接器则少于并行接口
  • 每个器件至多有一个独特的总线信号(芯片选择);其他信号均可以共享
  • 信号是单向的,允许简单的电气隔离
  • 软件撰写简易
缺点
  • 即使是三线式SPI,也需要比I²C更多的IC线路
  • 没有带内寻址; 共享总线上需要带外片选信号
  • 从机不支持流控制 (但主机可以延迟下一个时钟边沿以降低传输速率)
  • 不支持动态添加节点(热插拔)。
    • 没有从机检测机制,主机无法检测是否与从机断开。
  • 通常只支持一个主设备(取决于设备的硬件实现)
  • 没有错误检测机制,不像I²C在每个字节后有回复信号
  • 无法进行数据检验,不定义额外的协议时(如CRC)无法保证数据正确性。
  • RS-232 , RS-485或CAN总线相比,它只能处理短距离内的数据传输。(距离可以通过使用收发器如RS-422进行扩展)
  • 有许多现有的变体,使得很难找到支持这些变体的主机适配器等开发工具。
  • 必须通过带外信号来实现中断,或者通过使用类似于USB 1.1和2.0的定期轮询来模拟中断
数据传输

为了开始通信,总线上的主设备需要使用从设备支持的频率来配置时钟,这个频率最高为几兆赫兹左右。然后主设备将某个从设备的SS线置为低电平,来选中这个从设备。如果等待时间是必要的话(例如进行模数转换),主设备必须在这段时间结束后,才可以发出时钟周期讯号。

在每个SPI时钟周期内,都会发生全双工数据传输。主设备在MOSI线上发送一个位,从设备读取它,同时从机在MISO线上发送一位数据,主机读取它。即使只有单向数据传输的目的,主从机之间的通信工作方式仍然是双工的。

两个连接成虚拟环形缓冲器的移位寄存器

传输通常会使用给定字长的两个移位寄存器,一个在主设备中,一个在从设备中,这两个寄存器连接成一个虚拟的环形缓冲器。数据通常先从最高位移出。在时钟讯号边沿,主机和从机均移出一位,然后在传输线上输出给对方。在下一个时钟沿,每个接收器都从传输线接受对方发出的数据位,并且从移位寄存器的最低位推入。每完成这样一个移出——推入的周期后,主机和从机就交换寄存器中的一位数据。当所有数据位都经过了这样的移出——推入过程后,主机和从机就完成了寄存器上的数据交换。如果需要交换的数据比寄存器的位数还要长的话,则需要重新加载移位寄存器并重复该过程。传输可能会持续任意数量的时钟周期。完成后,主设备会停止发送时钟讯号,并通常会取消选择从设备。

传输寄存器通常包含8位。但是其他字长也很常见,例如触摸屏控制器或音频编解码器通常采用16位字长(如德州仪器的TSC2101),许多数模转换或者模数转换的设备则会采用12位字长。

所有在总线上的没有被片选线激活的从设备必须忽略输入时钟和MOSI讯号,并且不得从MISO发送数据。

二、实战

2.1 工程配置

打开cubeMX进行配置

开启SPI1,我这里GPIO是根据板子上的接口来设定的,大家灵活配置即可。波特率我设置了3M的速率,实际上更高到12M也是没问题的,不过那样的话逻辑分析仪采集信号就会有损失,为了方便演示,笔者就16分频了。

2.2 测试工程

打开生成的工程,添加测试代码

函数具体说明如下

2.3 波形分析

使用逻辑分析仪查看波形如下

但是这仅仅有发送数据,没有设置CS,SC,RES引脚的电平

三、驱动OLED

知道HAL库对SPI的发送过程后,阅读ssd1306的datasheet,进行驱动的编写

使用器件需要对器件进行初始化,阅读手册进行配置即可

其间用到一条重要的函数即

void SSD1306_WriteByte(uint8_t dat,uint8_t cmd);

功能是通过SPI总线对ssd1306进行数据发送

OLED通信过程如下

当片选信号CS电平为低时器件被主机选中,由DC引脚控制发生的是命令还是数据

如果是数据则高电平,如果是指令则低电平.

void SSD1306_WriteByte(uint8_t dat,uint8_t cmd)
{
	uint8_t buffer[1];
	buffer[0]=dat;
	if(cmd==OLED_CMD)
	{
		HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_RESET);
		HAL_SPI_Transmit(&hspi1,buffer,1,0xffff);
	}
	else if(cmd==OLED_DATA)
	{
		HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_SET);
		HAL_SPI_Transmit(&hspi1,buffer,1,0xffff);
	}
}

HAL_SPI_Transmit()函数一次发一个字节过去,参数cmd告知是数据还是指令,选择DC引脚的电平

主要指令内容集中在这几章,整个datasheet约60页,开头为目录和介绍,末尾是封装信息。

指令表中有基本指令,滚动指令,地址设置指令,硬件配置指令,时序及驱动指令

用到的为除滚动指令外的四个

光看指令表会有些陌生,可以结合下面的描述来看

3.1 初始化代码

void OLED_Init()
{
	HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_RESET);
	HAL_Delay(100);
	HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_SET);
	SSD1306_WriteByte(0xAE,OLED_CMD); //display off
	
	SSD1306_WriteByte(0x20,OLED_CMD); //Set Memory Addressing Mode   
	SSD1306_WriteByte(0x10,OLED_CMD); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	
	SSD1306_WriteByte(0xB0,OLED_CMD); //Set Page Start Address for Page Addressing Mode,0-7
	
	SSD1306_WriteByte(0x00,OLED_CMD); //---set low column address
	SSD1306_WriteByte(0x10,OLED_CMD); //---set high column address
	
	SSD1306_WriteByte(0xC8,OLED_CMD); //Set COM Output Scan Direction

	SSD1306_WriteByte(0x40,OLED_CMD); //--set start line address
	
	SSD1306_WriteByte(0x81,OLED_CMD); //--set contrast control register
	SSD1306_WriteByte(0xff,OLED_CMD); //对比度设置
	
	SSD1306_WriteByte(0xA1,OLED_CMD); //--set segment re-map 0 to 127
	SSD1306_WriteByte(0xC8,OLED_CMD); //--set segment re-map 0 to 127
	
	SSD1306_WriteByte(0xA6,OLED_CMD); //--set normal display
	
	SSD1306_WriteByte(0xA8,OLED_CMD); //--set multiplex ratio(1 to 64)
	SSD1306_WriteByte(0x3F,OLED_CMD); //
	
	SSD1306_WriteByte(0xA4,OLED_CMD); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	
	SSD1306_WriteByte(0xD3,OLED_CMD); //-set display offset
	SSD1306_WriteByte(0x00,OLED_CMD); //-not offset
	
	SSD1306_WriteByte(0xD5,OLED_CMD); //--set display clock divide ratio/oscillator frequency
	SSD1306_WriteByte(0xF0,OLED_CMD); //--set divide ratio
	
	SSD1306_WriteByte(0xD9,OLED_CMD); //--set pre-charge period
	SSD1306_WriteByte(0x22,OLED_CMD); //
	
	SSD1306_WriteByte(0xDA,OLED_CMD); //--set com pins hardware configuration
	SSD1306_WriteByte(0x12,OLED_CMD);
	
	SSD1306_WriteByte(0xDB,OLED_CMD); //--set vcomh
	SSD1306_WriteByte(0x20,OLED_CMD); //0x20,0.77xVcc
	
	SSD1306_WriteByte(0x8D,OLED_CMD); //--set DC-DC enable
	SSD1306_WriteByte(0x14,OLED_CMD); //
	SSD1306_WriteByte(0xAF,OLED_CMD); //--turn on SSD1306 panel
}

 OLED_CMD使用宏定义,其值为0x00

根据描述,第一步先设置地址模式为页地址模式,注意这个指令是双字节的,意思是发送0x20后要继续发送一个指令联合起来进行设置。根据手册,第二个指令为 0x10

然后设置列地址起始位置,由于屏幕横向有128个像素点,就有128列,手册将地址设置分成高四位地址设置和低四位地址设置,用两个指令来完成,分别是0x00~0x0F控制低四位,0x10~0x1F控制高四位,手册中的例子为低地址指令0x03,高地址为0x10,则最终列起始地址为0x03即SEG3

重要的指令为页起始地址设置指令,就是上面的0x10~0x1f和0x00~0x0f,实际上前者不能为0x1f,因为只有128列,显然f*16=240>128

3.2 清屏函数

void OLED_Clear()
{
    uint8_t i,n;		    
	for(i=0;i<8;i++)  
	{  
		SSD1306_WriteByte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
		SSD1306_WriteByte (0x00,OLED_CMD);      //设置显示位置—列低地址
		SSD1306_WriteByte (0x10,OLED_CMD);      //设置显示位置—列高地址   
		for(n=0;n<128;n++)
			SSD1306_WriteByte(0,OLED_DATA); //write 0x00;
	} //更新显示
}

外层循环8次,对应8个page,每个page由纵向8个像素,横向128列构成。设置页地址起始列为最左边即SEG0,将这128列都填充数据0x00,显示出来就是一片黑色

3.3 设置坐标函数

void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 	
	SSD1306_WriteByte(0xb0+y,OLED_CMD);						//page y
	SSD1306_WriteByte(((x&0xf0)>>4)|0x10,OLED_CMD);			//high 4 address
	SSD1306_WriteByte((x&0x0f),OLED_CMD); 					//low 4 address
} 

形参y设置page,范围为0到7,对应的指令为0xb0~0xb7。形参x设置起始页列地址,范围为0~127对应SEG0~SEG127。需要对x进行分块,分成高半字节和低半字节

编写主函数代码如下

 OLED在左上角显示字符A,高度为8像素,宽为6像素,图中6行发送数据的函数将字符A的6列一一发送过去,且OLED的列指针会自动加一,因此不必反复设置列指针位置 

 当然,写成下面这样也是可以的

这里会有一个疑问,就是这些数据是怎么得到的,总不会一个个去画吧。实际这是对A进行字体大小为8*6的取模得到的。网上有许多取模软件,一般会将ASCII码全部取出,并存放在一个数组中,需要用到时只需要发送对应行的数据

3.4显示字符函数

void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{      	
	unsigned char c=0,i=0;	
	c=chr-' ';//得到偏移后的值			
	if(x>Max_Column-1){x=0;y=y+2;}
	if(Char_Size ==16)
	{
		OLED_Set_Pos(x,y);	
		for(i=0;i<8;i++)
		SSD1306_WriteByte(F8X16[c*16+i],OLED_DATA);
		OLED_Set_Pos(x,y+1);
		for(i=0;i<8;i++)
		SSD1306_WriteByte(F8X16[c*16+i+8],OLED_DATA);
	}
	else 
	{	
		OLED_Set_Pos(x,y);
		for(i=0;i<6;i++)
		SSD1306_WriteByte(F6x8[c][i],OLED_DATA);
	}
}

这个字符显示函数只有高8和高16两种大小的字符显示功能,其中显示高度为16像素的字符时,涉及到两页,需要将y+1。先将上半部分的8列写入再将下半部分8列写入。但是想写高为12,14,20等等的字体需要用另一种方法

3.5 显示字符串函数

void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t 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函数进行转换为字符串,然后显示对应的字符串即可。

3.6 显示图片函数

这里以经典的PCtoLCD2002为例

取模设置如下

 参考手册页地址模式

选择低位在前,且为列行式,使用一维数组储存,右边格式前缀后缀稍作修改。

由于图片包含取模信息和图片的长度宽度,使用结构体进行定义 

typedef struct
{
	uint8_t xSize;
	uint8_t ySize;
	const unsigned char *p;
}BMP;

将这个声明放到oled.h中,因为oled.c有显示图片函数需要用到

以这个苹果图片为例

 将取好的图片模和字模放到一个.h文件中

#include "oled.h"


extern BMP bmp;

const unsigned char bmp_data[]=
{
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,0x00,0x00,
0x00,0xC0,0xE0,0xE0,0xF0,0xF0,0xF8,0xF8,0xFC,0xFC,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFE,
0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x1F,0x1F,0x07,0x01,0x00,0x80,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,0xC0,0xE0,0xF8,0xF8,0xFC,0xFE,0xFE,0xFE,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFE,0xFE,0xFE,0xFC,0xFE,0xFC,0xFD,0xFD,
0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0xFC,0xFE,0xF8,0xF8,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xBF,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x04,0x1F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFC,0xF8,0xF8,0xE0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0F,0x3F,0x7F,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0x7F,0x1F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x0F,0x0F,
0x1F,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x1F,0x1F,0x1F,0x1F,0x0F,
0x0F,0x1F,0x1F,0x1F,0x1F,0x3F,0x3F,0x3F,0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x1F,0x1F,
0x0F,0x07,0x03,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,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,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\Tom\Desktop\1.bmp",0*/
};

BMP bmp=
{
	64,	//宽像素
	64,	//高像素
	bmp_data
};

并将bmp用extern修饰

extern BMP bmp;

显示函数如下

void OLED_ShowPic(uint8_t x,uint8_t y,BMP bmp)
{
	uint8_t xsize=bmp.xSize;
	uint8_t ysize=bmp.ySize;
	OLED_Set_Pos(x,y);
	//如果像素高度不是8的倍数,则整除后加1补上
	if(ysize%8!=0)
		ysize=ysize+8;
	uint8_t i,j;
	for(i=0;i<ysize/8;i++)
	{
		OLED_Set_Pos(x,y+i);
		for(j=0;j<xsize;j++)
		SSD1306_WriteByte(*(bmp.p+i*xsize+j),OLED_DATA);
	}
}

主函数编写

OLED_Init();
OLED_Clear();
OLED_ShowPic(32,0,bmp);

 显示效果如下

附录 驱动代码文件

oled.c

#include "oled.h"
#include "f6x8.h"

static  uint16_t AStrbuffer[STRING_LENTH];		//字库转16进制数存放数组
static  uint16_t Strbuffer[STRING_LENTH];		//待显示字符串转16进制数存放数组
static uint16_t Alen=0;		//字库字符串长度,值为字库包含汉字数*2
static uint16_t len=0;		//要显示的字符串的长度,值为字库包含汉字数*2
static HZ* hz;				//字库指针

static uint8_t xsize;		//汉字的宽度
static uint8_t ysize;		//汉字的高度

void SSD1306_WriteByte(uint8_t dat,uint8_t cmd)
{
	uint8_t buffer[1];
	buffer[0]=dat;
	if(cmd==OLED_CMD)
	{
		HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_RESET);
		HAL_SPI_Transmit(&hspi1,buffer,1,0xffff);
		//HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_SET);
	}
	else if(cmd==OLED_DATA)
	{
		HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_SET);
		HAL_SPI_Transmit(&hspi1,buffer,1,0xffff);
		//HAL_GPIO_WritePin(DC_GPIO_Port,DC_Pin,GPIO_PIN_SET);
	}
}

void OLED_Clear()
{
     uint8_t i,n;		    
	for(i=0;i<8;i++)  
	{  
		SSD1306_WriteByte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
		SSD1306_WriteByte (0x00,OLED_CMD);      //设置显示位置—列低地址
		SSD1306_WriteByte (0x10,OLED_CMD);      //设置显示位置—列高地址   
		for(n=0;n<128;n++)
			SSD1306_WriteByte(0,OLED_DATA); //write 0x00;
	} //更新显示
}
void OLED_Init()
{
	HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_RESET);
	HAL_Delay(100);
	HAL_GPIO_WritePin(RES_GPIO_Port,RES_Pin,GPIO_PIN_SET);
	SSD1306_WriteByte(0xAE,OLED_CMD); //display off
	
	SSD1306_WriteByte(0x20,OLED_CMD); //Set Memory Addressing Mode   
	SSD1306_WriteByte(0x10,OLED_CMD); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	
	SSD1306_WriteByte(0xB0,OLED_CMD); //Set Page Start Address for Page Addressing Mode,0-7
	
	SSD1306_WriteByte(0x00,OLED_CMD); //---set low column address
	SSD1306_WriteByte(0x10,OLED_CMD); //---set high column address
	
	SSD1306_WriteByte(0xC8,OLED_CMD); //Set COM Output Scan Direction

	SSD1306_WriteByte(0x40,OLED_CMD); //--set start line address
	
	SSD1306_WriteByte(0x81,OLED_CMD); //--set contrast control register
	SSD1306_WriteByte(0xff,OLED_CMD); //对比度设置
	
	SSD1306_WriteByte(0xA1,OLED_CMD); //--set segment re-map 0 to 127
	SSD1306_WriteByte(0xC8,OLED_CMD); //--set segment re-map 0 to 127
	
	SSD1306_WriteByte(0xA6,OLED_CMD); //--set normal display
	
	SSD1306_WriteByte(0xA8,OLED_CMD); //--set multiplex ratio(1 to 64)
	SSD1306_WriteByte(0x3F,OLED_CMD); //
	
	SSD1306_WriteByte(0xA4,OLED_CMD); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	
	SSD1306_WriteByte(0xD3,OLED_CMD); //-set display offset
	SSD1306_WriteByte(0x00,OLED_CMD); //-not offset
	
	SSD1306_WriteByte(0xD5,OLED_CMD); //--set display clock divide ratio/oscillator frequency
	SSD1306_WriteByte(0xF0,OLED_CMD); //--set divide ratio
	
	SSD1306_WriteByte(0xD9,OLED_CMD); //--set pre-charge period
	SSD1306_WriteByte(0x22,OLED_CMD); //
	
	SSD1306_WriteByte(0xDA,OLED_CMD); //--set com pins hardware configuration
	SSD1306_WriteByte(0x12,OLED_CMD);
	
	SSD1306_WriteByte(0xDB,OLED_CMD); //--set vcomh
	SSD1306_WriteByte(0x20,OLED_CMD); //0x20,0.77xVcc
	
	SSD1306_WriteByte(0x8D,OLED_CMD); //--set DC-DC enable
	SSD1306_WriteByte(0x14,OLED_CMD); //
	SSD1306_WriteByte(0xAF,OLED_CMD); //--turn on SSD1306 panel
}



void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 	
	SSD1306_WriteByte(0xb0+y,OLED_CMD);						//page y
	SSD1306_WriteByte(((x&0xf0)>>4)|0x10,OLED_CMD);			//high 4 address
	SSD1306_WriteByte((x&0x0f),OLED_CMD); 					//low 4 address
} 


void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{      	
	unsigned char c=0,i=0;	
	c=chr-' ';//得到偏移后的值			
	if(x>Max_Column-1){x=0;y=y+2;}
	if(Char_Size ==16)
	{
		OLED_Set_Pos(x,y);	
		for(i=0;i<8;i++)
				SSD1306_WriteByte(F8X16[c*16+i],OLED_DATA);
		OLED_Set_Pos(x,y+1);
		for(i=0;i<8;i++)
				SSD1306_WriteByte(F8X16[c*16+i+8],OLED_DATA);
	}
	else 
	{	
		OLED_Set_Pos(x,y);
		for(i=0;i<6;i++)
			SSD1306_WriteByte(F6x8[c][i],OLED_DATA);
	}
}
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t 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++;
	}
}
void OLED_ShowPic(uint8_t x,uint8_t y,BMP bmp)
{
	uint8_t xsizeb=bmp.xSize;
	uint8_t ysizeb=bmp.ySize;
	OLED_Set_Pos(x,y);
	//如果像素高度不是8的倍数,则整除后补上
	if(ysizeb%8!=0)
		ysizeb=ysizeb/8*8+8;
	uint8_t i,j;
	for(i=0;i<ysizeb/8;i++)
	{
		OLED_Set_Pos(x,y+i);
		for(j=0;j<xsizeb;j++)
		SSD1306_WriteByte(*(bmp.p+i*xsizeb+j),OLED_DATA);
	}
}

/**
将字库字符串转为16进制数并存入全局数组
*/
void AStrtoHex(char* c)
{
	uint16_t i;
	
	for(i=0;i<STRING_LENTH;i=i+1)		//清空数组内容
	{
		AStrbuffer[i]=0;
	}
	
	Alen=0;
	char*p=c;
	while(*(p++)!='\0')
		Alen++;

	
	uint16_t tmp=0;
	p=c;
	for(i=0;i<Alen;i=i+2)
	{
		tmp=((uint16_t)(*(p+i)))<<8;
		tmp=tmp|(uint16_t)*(p+i+1);
		AStrbuffer[i/2]=tmp;
	}
}
/**
将待显示字符串转为16进制数并存入全局数组
*/
void StrtoHex(char* c)
{
	uint16_t i;
	for(i=0;i<STRING_LENTH;i=i+1)		//清空数组内容
	{
		Strbuffer[i]=0;
	}
	char*p=c;
	len=0;
	while(*(p++)!='\0')
		len++;

	
	uint16_t tmp=0;
	p=c;
	for(i=0;i<len;i=i+2)
	{
		tmp=((uint16_t)(*(p+i)))<<8;
		tmp=tmp|(uint16_t)*(p+i+1);
		Strbuffer[i/2]=tmp;
	}
}
/**
设置字体
*/
void OLED_SetFont(HZ *hz1)
{
	hz=hz1;
	xsize=hz->xSize;
	ysize=hz->ySize;
	if(ysize%8!=0)		//如果像素高度不是8的倍数,则整除后补上
		ysize=ysize/8*8+8;
}
/**
显示字符串
*/
void OLED_ShowHZ(uint8_t x,uint8_t y, char* str)
{
	uint16_t i,j,k,index=0;

	
	AStrtoHex(hz->Astr);		//-->AStrbuffer[]  Alen值为字库包含汉字数*2
	StrtoHex(str);			//-->Strbuffer[]   len值为显示函数中字符串包含汉字数*2
	uint16_t a=0;
	//要显示的中文字符串有几个汉字就循环几次
	for(a=0;a<len/2;a++)
	{
		for(i=0;i<Alen/2;i++)
		{
			if(Strbuffer[a]==AStrbuffer[i])
			{
				index=i;		//分别找出每个汉字在字符串内的位置
				break;
			}

		}
			for(j=0;j<ysize/8;j++)
			{
				OLED_Set_Pos(x+a*xsize,y+j);		//显示完一个汉字后坐标移动
				for(k=0;k<xsize;k++)
				SSD1306_WriteByte(*(hz->p +  k +j*xsize+ index*xsize*ysize/8),OLED_DATA);//显示index指向的那个汉字
			}
	}
}




oled.h

#ifndef OLED_H
#define OLED_H
#include "main.h"                  // Device header
#include "spi.h"


#define OLED_CMD  0X00 //写命令
#define OLED_DATA 0X40 //写数据

#define SSD1306_I2C_ADDR         0x78
#define SSD1306_WIDTH            128
#define SSD1306_HEIGHT           6

#define SIZE 16
#define XLevelL		0x02
#define XLevelH		0x10
#define Max_Column	128
#define Max_Row		64
#define	Brightness	0xFF 
#define X_WIDTH 	128
#define Y_WIDTH 	64

#define STRING_LENTH 50
typedef struct
{
	uint8_t xSize;
	uint8_t ySize;
	const unsigned char *p;
}BMP;
typedef struct
{
	uint8_t xSize;			//字体宽度
	uint8_t ySize;			//字体高度
	const char *Astr;		//字库所包含字模按顺序的字符串
	const unsigned char *p;	//字模数组指针
}HZ;

void SSD1306_WriteByte(uint8_t dat,uint8_t cmd);
void OLED_Set_Pos(unsigned char x, unsigned char y) ;
void OLED_Init();
void OLED_Clear();
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size);
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size);
void OLED_ShowPic(uint8_t x,uint8_t y,BMP bmp);
void OLED_ShowHZ(uint8_t x,uint8_t y,char* str);
void OLED_SetFont(HZ *hz1);

#endif

f6x8.h

#ifndef __OLEDFONT_H__
#define __OLEDFONT_H__   
#include "oled.h"

//常用ASCII表
//偏移量32
//ASCII字符集
//偏移量32
//大小:12*6
/************************************6*8的点阵************************************/
const unsigned char  F6x8[][6] =		
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// 
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
}
/****************************************8*16的点阵************************************/
const unsigned char  F8X16[]=	  
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
  0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
  0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
  0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
  0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
  0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
  0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
  0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
  0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
  0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
  0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
  0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
  0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
  0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
  0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
  0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
  0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
  0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
  0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
  0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
  0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
  0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
  0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
  0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
  0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,// 27
  0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
  0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
  0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
  0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
  0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
  0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
  0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
  0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
  0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
  0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
  0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
  0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
  0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
  0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
  0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
  0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
  0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
  0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
  0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
  0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
  0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
  0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
  0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
  0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
  0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
  0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
  0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
  0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
  0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
  0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
  0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
  0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
  0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
  0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
  0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
  0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
  0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
  0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
  0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
  0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
  0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
  0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
  0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
  0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
  0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
  0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
  0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
  0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
  0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
  0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
  0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
  0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
  0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
  0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
  0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
  0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
  0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
  0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
  0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
  0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
  0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
  0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
  0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
  0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
}





#endif


使用时主函数只需要包含oled.h即可

  • 13
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值