简介

本文将介绍两种不同尺寸的OLED显示屏:0.96寸和0.91寸。他们都是4引脚I2C接口的,如下图所示:

注:经过项目测试发现,本文介绍的驱动方式和代码也完全适用于 1.54寸SSD1309主控的1.54寸OLED和1.29寸CH1115主控的OLED屏。如果需要更大的屏幕可以选用这两款,但是他们的分辨率仍然是126*64,只是显示的字体和图案可以更大。

0.96英寸OLED基本参数

  • 工作电压:3.3~5V(内置3.3V LDO,I2C通信接口电平是3.3V的)
  • 像素点阵规模:128×64(128列,64行,共8192颗LED)
  • 驱动IC:SSD1306
  • 0.91英寸OLED基本参数

  • 工作电压:3.3~5V(内置3.3V LDO,I2C通信接口电平是3.3V的)
  • 像素点阵规模:128×32(128列,32行,共4096颗LED)
  • 驱动IC:SSD1306
  • 可以发现,0.91英寸的像素点规模只有0.96英寸的一半,除此之外其余参数基本相同。接下来将主要介绍0.96英寸显示屏的使用方法。

    接口定义

    引脚名称 引脚说明
    VCC 模块电源正,3.3~5V
    GND 模块电源地
    SCL 模块I2C总线时钟信号
    SDA 模块I2C总线数据信号

    I2C通信接口

    硬件设计

  • 模块内置了一个3.3V的LDO,型号为662K,所以支持3.3~5V供电。
  • 模块已经板载了SCL和SDA线的上拉电阻,且上拉到了3.3V。如果单片机是5V的,只要IO配置为开漏输出,则也是可以直接接入到模块的,因为开漏无法输出高电平。最主要的问题是3.3V能够被5V单片机识别为高电平,这个要看单片机数据手册。一般是没有问题的。
  • 其他I2C从机挂接到同一个I2C总线时,无需再外接I2C总线的上拉电阻了。
  • 模块的I2C从机地址为:0111 10 [SA0] [RW],SA0是硬件地址选择位,当SA0接高电平时,地址中的SA0就是1,当SA0接低电平时,地址中的SA0就是0。模块出厂的时候,一般SA0是接的低电平,用户可以自己动手修改模块后面的电阻来改变SA0为高电平。这也意味着,同一个I2C总线最多支持挂接2个OLED模块。
  • 软件设计

    在SSD1306的I2C协议中,用到了控制字节,控制位的格式为:[Co][D/C#][000000]。在发送指令字节或者数据字节前,需要先发送一个控制字节,通过控制字节中的D/C#位,来告诉SSD1306,接下来发送的一个字节是指令还是数据。这里我们先不考虑控制字节中Co位的作用,这样我们就可以编写出发送单个字节的指令和单个字节的数据的函数。

    发送单个字节指令:起始信号【从机地址,ACK】【控制字节,ACK】【单字节的指令,ACK】结束信号

    static void OLED_write_cmd(uint8_t cmd)
    {
    	IIC_start();
    	IIC_write_byte(0x78);   //从机地址,SA0=0,RW=0 
    	IIC_wait_ack();
    	
    	IIC_write_byte(0x00);   //控制字节,Co=0,D/C#=0
    	IIC_wait_ack();
    	
    	IIC_write_byte(cmd);   //命令码
    	IIC_wait_ack();
    	
    	IIC_stop();
    }

    发送单个字节显存数据:起始信号【从机地址,ACK】【控制字节,ACK】【单字节的数据,ACK】结束信号 

    static void OLED_write_data(uint8_t dat)
    {
    	IIC_start();
    	IIC_write_byte(0x78);   // 从机地址,SA0=0,RW=0
    	IIC_wait_ack();
    	
    	IIC_write_byte(0x40);   //控制字节,Co=0,D/C#=1
    	IIC_wait_ack();
    	
    	IIC_write_byte(dat);   //数据值
    	IIC_wait_ack();
    	
    	IIC_stop();
    }

    上面的代码我们可以发现,每次发送一个指令或者数据字节,都要开启一次完整的I2C通信时序流程,要有起始信号,从机地址,控制字节和结束信号。指令性数据在正常运行时,使用的比较少,用上面的函数发送没什么大问题,但是发送到显存中的数据字节,则往往需要一次性发送多个,特别是在快速刷屏的时候,如果也使用上面的函数发送,会有大量的通信时间浪费在发送起始新,从机地址,控制字节和结束信号上了,效率低下。那么有没有办法一次性无间隔的连续发送多个显存数据呢?可以,这个时候控制字节中的Co位就派上用场了。

    控制字节中的Co位作用:当控制字节中Co=0,且D/C#=1时,则接下来可以连续发送任意多个显存数据字节,直到产生停止信号。下面是代码实现。

    一次性发送N个显存数据:起始信号【从机地址,ACK】【控制字节,ACK】【N个字节的数据,N个ACK】结束信号 

    static void OLED_write_data_array(const uint8_t* dats,uint32_t len)
    {
    	IIC_start();
    	IIC_write_byte(0x78);   //从机地址,SA0=0,RW=0 
    	IIC_wait_ack();
    	
    	IIC_write_byte(0x40);   //控制字节,Co=0,D/C#=1
    	IIC_wait_ack();
    	
    	for(uint32_t i=0;i<len;i++)
    	{
    		IIC_write_byte(dats[i]);   //数据值
    		IIC_wait_ack();
    	}
    	IIC_stop();
    }

    通过在0.91英寸OLED屏幕上测试发现,使用150KHz I2C总线,刷完一帧屏幕,使用单个发送字节显存数据函数需要大约100ms,而使用一次性发送多个显存数据的函数则只需要大约33ms,速度提升非常明显。

    驱动芯片的指令集

    这里将介绍如何看懂SSD1306数据手册中的指令集。如下图所示,这是截取指令集中的3条指令。

    指令A用于设置页地址,它由连续的3个字节组成,第一个字节0x22代表指令码,用于标识指令功能本身,也就是当发送0x22指令时,驱动芯片SSD1306就知道现在要设置页地址了,而后面的两个字节A[2:0]和B[2:0]则是两个指令参数,指令参数是指令运行时所需的参数数据。为了方便理解,我们可以将指令码和指令参数与函数和函数的参数类比起来。表示为*的位意思是他们的值可以任意设置,一般置0即可。

    指令B比较特殊,他将指令码和指令参数融合为了一个字节,高位部分固定为[10110],低位部分[X2,X1,X0] 则用于编码指令参数。

    指令C也比较特殊,它只有一个固定的指令码,没有指令参数。类似于C语言中的无参数函数。

    表格的第一列D/C#,用于告诉我们,发送对应的字节时,需要将D/C#位设置为0还是1。D/C#=0 代表发送的是指令性相关的数据,这些字节数据被SSD1306接收并解析,主要用于改变屏幕的工作参数。D/C#=1代表发送的是显示数据字节,这些字节将被写入到SSD1306的显存GDDRAM中作为显示数据使用。由于上图中的数据都是指令数据,所以他们在发送时,都要设置D/C#为0。

    显存与页寻址模式

    驱动芯片SSD1306带有一个128×64 bit大小的GDDRAM,用于存放显示数据,也就是所谓的显存。显存中的数据与显示内容是息息相关的,具体来说,显存中的每一个bit对应一颗像素点,如果显存中的某个bit为1,则它对应的那颗像素LED被点亮,否则是熄灭的。

    寻址模式规定了GDDRAM存储单元的组织形式。GDDRAM支持3种内存寻址模式,可以通过指令选择为:①页寻址模式 ②水平寻址模式 ③垂直寻址模式。这里讲解一下最常用的页寻址模式。

    如上图所示,当使用页寻址模式时,GDDRAM被划分为8个页:PAGE0~PAGE7,每个页由128个字节组成。那么通过单片机向GDDRAM中写入数据时,就需要指定2个地址:页地址和列地址,这样才能定位到GDDRAM中的一个的字节存储单元。例如,如果设置页指针为0,列指针为2,并写入显示数据0xF0,则效果如上图中蓝色所示。

    在页寻址模式下,每次写入一个字节的显示数据,列地址自动增1。当列地址超过127时,会自动回归到0。但是页指针不会改变,除非使用指令重新设置指向其他的页。

    如何设置页地址和列地址呢?

    通过查看SSD1306的指令表,可以发现有对应的指令来设置页地址和列地址。如下图所示。

    其中列地址需要拆成2部分写入,用第一条指令发送列地址值的低4bit部分,用第二条指令发送列地址值的高4bit部分。

     如何配置寻址模式为页寻址模式?

    先发送指令码0x20,来告诉屏幕要现在要设置内存寻址模式,然后发送指令参数:0x00水平地址模式,0x01垂直模式,0x02页地址模式。芯片复位后默认就是页寻址模式。

    图片的显示

    我们需要使用Pctolcd2002这款取模软件。首先我们需要准备一张图片,如果你需要在OLED屏上显示一个W像素宽,H像素高的图像,那么需要准备一张尺寸同等比例的图片。

    例如我们要在0.96英寸OLED上显示一张128宽,64高的图片,则我准备了一张378×189的意法半导体logo图片。128/64 = 2,378/189 =2。然后用Windows自带的画图软件打开它,调整它的大小为想要的像素规模,然后保存为BMP格式。

    接着打开Pctolcd2002软件,菜单栏【模式】修改为图形模式,【文件】【打开】,选中上一步生成的BMP图像。然后点击工具栏的【齿轮】按钮,在弹出的界面中按照下图进行配置,配置完成后点击【确定】返回主界面。

    在主界面中,生成的点阵预览图可能细节上有瑕疵,这个时候可以使用鼠标进行修补,左键增加一个像素,右键取消一个像素。最后点击主界面右下角的【生成子模】按钮,即可输出子模字节数据。将这个子模数据以一维字节数组的形式定义在C程序中,就可以使用了。

    由于我们的【取模方式】用的是【列行式】,则取模软件会从图片左上角第一列开始,每竖向8个像素点得到一个字节,一直到最后一列时取到128字节。下一次则换到下一个8像素宽的行从开始取。所以可以看出,【取模方式】用的是【列行式】对于页寻址模式是很方便的。

    //128像素宽,64像素高,st意法半导体 logo
    const uint8_t image_data[64*16]=
    {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,0xF0,0xF8,0xFC,0xFE,0xFE,0xFE,0xFE,
    0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
    0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
    0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
    0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
    0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
    0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0x3E,0x0E,0x06,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,0xF0,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,
    0x3F,0x1F,0x1F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
    0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
    0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
    0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
    0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
    0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,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,0x80,
    0xE0,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x03,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
    0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
    0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
    0xE0,0xE0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,
    0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
    0x60,0x20,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,0x80,0xF0,0xFC,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0xC0,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0F,0x1F,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,
    0x7F,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xFE,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x0F,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,0xC0,0xF0,0xFE,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
    0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,
    0x03,0x07,0x0F,0x1F,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,0x3F,0x07,0x01,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x07,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,0xE0,0xF8,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,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x07,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x80,0xE0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,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,0x0C,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
    0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
    0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0E,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0xC0,0xF0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0x3F,0x0F,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,0x40,0x60,0x60,0x70,0x78,0x7C,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
    0x7F,0x7F,0x7F,0x3F,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x78,
    0x7E,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x3F,0x1F,0x1F,0x0F,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,0x00,0x00,0x00,};
    
    void OLED_showImage(void)
    {
    	uint32_t page;
    	uint32_t i=0;
    	
    	for(page=0;page<8;page++)
    	{
    		OLED_write_cmd(0xb0+page);   //设置页地址
    		OLED_write_cmd(0x00);OLED_write_cmd(0x10);  //设置列地址为0起始地址
    		
    		OLED_write_data_array(image_data+i,128);  //发送128个字节的显存数据
    		i+=128;
    	}
    }

    汉字的显示

    打开Pctolcd2002软件,菜单栏【模式】修改为字符模式,【选择字体】,设置【字宽和字高】。在下方输入需要取模的汉字,然后点击【生成字模】即可。设置里面的参数和上面图片取模的一样。

    实际使用过程中,为了达到比较好的显示效果,汉字最小一般使用16×16宽和高。Pctolcd2002软件把每一个汉字当做一个基本的图像来进行取模的,且按照输入的文字依次进行取模。所以得到的子模数据是:第一个汉字的上半部分字模,第一个汉字的下半部分字模;第二个汉字的上半部分字模,第二个汉字的下半部分字模。。。这样的的方式得到的字模数据。如下:

    0x00,0xFC,0x04,0x04,0xFC,0x20,0x50,0x48,0x44,0x43,0x44,0x48,0x50,0x20,0x20,0x00, //哈的上半部分
    0x00,0x0F,0x04,0x04,0x0F,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00, //哈的下半部分
    0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, //士的上半部分
    0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, //士的下半部分
    0x40,0x40,0x44,0x44,0x64,0x54,0x4C,0x47,0x4C,0x54,0x64,0xC4,0x44,0x40,0x40,0x00, //奇的上半部分
    0x00,0x00,0x00,0x1E,0x12,0x12,0x12,0x12,0x1E,0x40,0x80,0x7F,0x00,0x00,0x00,0x00, //奇的下半部分

    所以,在显示汉字的时候,要先按顺序显示每个字的上半部分,然后换到下一个page,再按顺序显示每个字的下半部分。

    static const uint8_t hanzi[] = {
    0x00,0xFC,0x04,0x04,0xFC,0x20,0x50,0x48,0x44,0x43,0x44,0x48,0x50,0x20,0x20,0x00,
    0x00,0x0F,0x04,0x04,0x0F,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,/*"哈",0*/
    0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
    0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,/*"士",1*/
    0x40,0x40,0x44,0x44,0x64,0x54,0x4C,0x47,0x4C,0x54,0x64,0xC4,0x44,0x40,0x40,0x00,
    0x00,0x00,0x00,0x1E,0x12,0x12,0x12,0x12,0x1E,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,/*"奇",2*/
    };
    
    //参数han为汉字字模数据
    //cnt为汉字个数
    void OLED_print_chinese(const uint8_t *han,uint8_t cnt,uint8_t page,uint8_t col)
    {
    	uint8_t i;
    	
    	OLED_set_pos(page,col);
    	for(i=0;i<cnt;i++)
    	{	
    		OLED_write_data_array(han+i*16*2,16);  //发送汉字字模数据的上半部分
    	}
    	
    	OLED_set_pos(page+1,col);  //切换到下一个page
    	for(i=0;i<cnt;i++)
    	{	
    		OLED_write_data_array(han+i*16*2+16,16);  //发送汉字字模数据的下半部分
    	}
    }

    初始化序列

    0.96寸IIC接口OLED初始化序列

    //0.96寸IIC接口OLED初始化
    void OLED_init(void)
    {
        OLED_I2C_init();     //初始化驱动I2C总线的引脚
    	//延时200ms等待OLED稳定
    
    	OLED_write_cmd(0xAE );//--display off
    	OLED_write_cmd(0x00 );//---set low column address
    	OLED_write_cmd(0x10 );//---set high column address
    	OLED_write_cmd(0x40 );//--set start line address  
    	OLED_write_cmd(0xB0 );//--set page address
    	OLED_write_cmd(0x81 ); // contract control
    	OLED_write_cmd(0xFF );//--128   
    	OLED_write_cmd(0xA1 );//set segment remap 
    	OLED_write_cmd(0xA6 );//--normal / reverse
    	OLED_write_cmd(0xA8 );//--set multiplex ratio(1 to 64)
    	OLED_write_cmd(0x3F );//--1/32 duty
    	OLED_write_cmd(0xC8 );//Com scan direction
    	OLED_write_cmd(0xD3 );//-set display offset
    	OLED_write_cmd(0x00 );//
    	OLED_write_cmd(0xD5 );//set osc division
    	OLED_write_cmd(0x80 );//
    	OLED_write_cmd(0xD8 );//set area color mode off
    	OLED_write_cmd(0x05 );//
    	OLED_write_cmd(0xD9 );//Set Pre-Charge Period
    	OLED_write_cmd(0xF1 );//
    	OLED_write_cmd(0xDA );//set com pin configuartion
    	OLED_write_cmd(0x12 );//
    	OLED_write_cmd(0xDB );//set Vcomh
    	OLED_write_cmd(0x30 );//
    	OLED_write_cmd(0x8D );//set charge pump enable
    	OLED_write_cmd(0x14 );//
    	OLED_write_cmd(0xAF );//--turn on oled panel
    
    	OLED_clear();         //清除屏幕显示
    }

    0.91寸IIC接口OLED初始化序列

    //0.91寸IIC接口OLED初始化
    void OLED_init(void)
    {
    	OLED_I2C_init();     //初始化驱动I2C总线的引脚
    	//延时200ms等待OLED稳定
    	
    	OLED_write_cmd(0xAE);
        OLED_write_cmd(0x40);//---set low column address
        OLED_write_cmd(0xB0);//---set high column address
        OLED_write_cmd(0xC8);//-not offset
        OLED_write_cmd(0x81);
        OLED_write_cmd(0xff);
        OLED_write_cmd(0xa1);
        OLED_write_cmd(0xa6);
        OLED_write_cmd(0xa8);
        OLED_write_cmd(0x1f);
        OLED_write_cmd(0xd3);
        OLED_write_cmd(0x00);
        OLED_write_cmd(0xd5);
        OLED_write_cmd(0xf0);
        OLED_write_cmd(0xd9);
        OLED_write_cmd(0x22);
        OLED_write_cmd(0xda);
        OLED_write_cmd(0x02);
        OLED_write_cmd(0xdb);
        OLED_write_cmd(0x49);
        OLED_write_cmd(0x8d);
        OLED_write_cmd(0x14);
    	OLED_write_cmd(0xaf); //打开显示
    
        OLED_clear();     //清除显示
    }

    物联沃分享整理
    物联沃-IOTWORD物联网 » OLED显示屏I2C接口

    发表评论