23. SPI——OLED屏幕显示

RA芯片的SPI分为简单SPI和普通SPI,简单SPI就是SCI模块(Serial Communications Interface)中的SPI模式,它是使用串行总线来模拟SPI,而我们本章我们所要学习的是普通的SPI,是全功能的SPI,它在RA芯片内部实际存在的一个硬件SPI控制器模块。

23.1. SPI协议

SPI协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在ADC、LCD等设备与MCU间,要求通讯速率较高的场合。

在瑞萨RA6M5芯片中,SPI外设可用作通讯的主机及从机,数据传输可达到最大的50Mbps速率,信号允许通过SPI操作(4线方法)或时钟同步操作(3-线方法),支持事件链接功能,并具有数据校验功能。

下面我们分别对SPI协议的物理层及协议层进行讲解。

23.1.1. SPI物理层

SPI通讯设备之间的常用连接方式见下图。

常见的SPI通讯系统

SPI通讯使用3条总线及片选线,3条总线分别为SCK、MOSI、MISO,片选线,它们的作用介绍如下:

  1. 从设备选择信号线 ( Slave Select):常称为片选信号线,也称为NSS、CS,以下用 NSS表示。当有多个SPI从设备与SPI主机相连时,设备的其它信号线SCK、MOSI及MIS O同时并联到相同的SPI总线上,当主机要选择从设备时,把该从设备的NSS信号线设置为低电平,该从设备即被选中, 即片选有效,接着主机开始与被选中的从设备进行SPI通讯。 所以SPI通讯以NSS线置低电平为开始信号,以NSS线被拉高作为结束信号。

  2. SCK (Serial Clock)时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了 通讯的速率,不同的设备支持的最高时钟频率不一样,如RA6M5的SPI时钟 频率最大为fpclkA/2,两个设备之间通讯时,通讯速率受限于低速设备。

  3. MOSI (Master Output, Slave Input):主设备输出/从设备输入引脚。主机的数据从这条 信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机

  4. MISO(Master Input,,Slave Output):主设备输入/从设备输出引脚。主机从这条信 线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机

23.1.2. 协议层

23.1.2.1. SPI基本通讯过程

SPI通讯的通讯时序,见下图:

SPI通讯时序

这是一个主机的通讯时序。NSS、SCK、MOSI信号都由主机控制产生,而MISO的信号由从机产生,主机通过该信号线读取从机的数据。 MOSI与MISO的信号只在NSS为低电平的时候才有效,在SCK的每个时钟周期MOSI和MISO传输一位数据。

以上通讯流程中包含的各个信号分解如下:

23.1.2.2. 通讯的起始和停止信号

在上图 SPI通讯时序 中的标号 1 处,NSS信号线由高变低,是SPI通讯的起始信号。 NSS是每个从机各自独占的信号线,当从机在自己的NSS线检测到起始信号后,就知道自己被主机选中了,开始准备与主机通讯。 在标号 6 处,NSS信号由低变高,是SPI通讯的停止信号,表示本次通讯结束,从机的选中状态被取消。

23.1.2.3. 数据有效性

SPI使用MOSI及MISO信号线来传输数据,使用SCK信号线进行数据同步。MOSI及MISO数据线在SCK的每个时钟周期传输一位数据, 且数据输入输出是同时进行的。数据传输时,MSB先行或LSB先行并没有作硬性规定,但要保证两个SPI通讯设备之间使用同样的协定, 一般都会采用图 SPI通讯时序 中的MSB先行模式。

观察图中的标号处,MOSI及MISO的数据在SCK的上升沿期间变化输出,在SCK的下降沿时被采样。即在SCK的下降沿时刻, MOSI及MISO的数据有效,高电平时表示数据“1”,为低电平时表示数据“0”。在其它时刻,数据无效,MOSI及MISO为下一次表示数据做准备。

SPI每次数据传输可以8位或16位为单位,每次传输的单位数不受限制

23.1.2.4. CPOL/CPHA及通讯模式

SPI一共有四种通讯模式,它们的主要区别是总线空闲时SCK的时钟状态以及数据采样时刻,它们由CPOL与CPHA来决定。

时钟极性CPOL是指SPI通讯设备处于空闲状态时,SCK信号线的电平信号(即SPI通讯开始前、 NSS线为高电平时SCK的状态)。CPOL=0时, SCK在空闲状态时为低电平,CPOL=1时,则相反。

时钟相位CPHA是指数据的采样的时刻,当CPHA=0时,MOSI或 MISO数据线上的信号将会在SCK时钟线的“奇数边沿”被采样。 当CPHA=1时,数据线在SCK的“偶数边沿”采样。

见下图 CPHA=0时的SPI通讯模式:

CPHA=0时的SPI通讯模式

我们来分析这个CPHA=0的时序图。首先,根据SCK在空闲状态时的电平,分为两种情况。SCK信号线在空闲状态为低电平时,CPOL=0;空闲状态为高电平时,CPOL=1。

无论CPOL=0还是=1,因为我们配置的时钟相位CPHA=0,在图中可以看到,采样时刻都是在SCK的奇数边沿。注意当CPOL=0的时候,时钟的奇数边沿是上升沿,而CPOL=1的时候,时钟的奇数边沿是下降沿。所以SPI的采样时刻不是由上升/下降沿决定的。MOSI和MISO数据线的有效信号在SCK的奇数边沿保持不变,数据信号将在SCK奇数边沿时被采样,在非采样时刻,MOSI和MISO的有效信号才发生切换。

类似地,当CPHA=1时,不受CPOL的影响,数据信号在SCK的偶数边沿被采样,

见下图 CPHA=1时的SPI通讯模式:

CPHA=1时的SPI通讯模式

由CPOL及CPHA的不同状态,SPI分成了四种模式,见下表:

SPI的四种模式

SPI模式

CPOL

CPHA

空闲时SCK时钟

采样时刻

数据发送

0

0

0

低电平

上升沿

下降沿

1

0

1

低电平

下降沿

上升沿

2

1

0

高电平

下降沿

上升沿

3

1

1

高电平

上升沿

下降沿

主机与从机需要工作在相同的模式下才可以正常通讯,上图 SPI通讯时序 就是采用的模式1,而我们本次OLED的SPI通讯实验就是采用的是模式3。

23.2. 瑞萨SPI功能框图

以 RA6M5 为例,SPI的功能结构框图如下图所示。接下来我们大致地研究一下它的结构和功能。

SPI功能框图

见图注1,瑞萨RA6M5有两个SPI外设,分别是SPI0,SPI1,每个SPI都有2~3组,下面是关于SPI各引脚的说明,以SPI0_A为例,见下表,其中值得一提的是, 当MCU作为主机时,有多个从机时,从机可通过SSLA0~SSLA3作为片选信号线来连接主机,而当MCU作为从机时, 则通过SSLA0作为片选线连接主机。

SPI_0的IO引脚描述

引脚名称

I/O

Description

RSPCKA

I/O

时钟输入输出引脚

MOSIA

I/O

主机发送数据输入输出

MISOA

I/O

从机发送数据输入输出

SSLA0

I/O

从机选择输入输出

SSLA1~SSLA3

Output

从机选择输出

注解

SPI0的引脚名称表示为“…A”或“…An”,SPI1的引脚名称表示为“…B”或“…Bn”(n=0、1、2或3)。

见图注2,其中:

  • Master:主机通讯模式

  • Slave:从机通讯模式

  • Normal:正常通讯模式

  • Loopback:环回模式1(接受数据=反转发送数据)

  • Loopback:环回模式2(接受数据=发送数据)

见图注3,其中:

  • SPTX:发送缓冲器

  • SPRX:接受缓冲器

见图注4,对于瑞萨RA6M5的SPI外设的寄存器介绍,见下表:

SPI的寄存器

SPCR

SPI控制寄存器

SSLP

SPI从机选择极性寄存器

SPPCR

SPI引脚控制寄存器

SPSR

SPI状态寄存器

SPDR/SPDR_HA/SPDR_BY

SPI数据寄存器

SPSCR

SPI序列控制寄存器

SPSSR

SPI序列状态寄存器

SPBR

SPI比特率寄存器

SPDCR

SPI数据控制寄存器

SPCKD

SPI时钟延迟寄存器

SSLND

SPI从机选择否定延迟寄存器

SPND

SPI下一次访问延迟寄存器

SPCR2

SPI控制寄存器2

SPCMDm

SPI命令寄存器m(m=0到7)

SPDCR2

SPI数据控制寄存器2

SPCR3

SPI控制寄存器3

注解

我们这里主要介绍的是瑞萨的fsp库的使用,所以在这里寄存器我们在这里做一些简单的介绍

见图注5,SPI波特率设置由寄存器SPBR与SPMDm.BRDV[1:0]设置的组合在主模式下设置。 当SPI处于从机模式时,比特率取决于输入时钟PCLKA的比特率,与SPBR和SPMDm.BRDV[1:0]位(比特率分频设置)的 设置无关。

见图注6,其中:

  • SPIi_SPRI:接收缓冲区满事件输出。

  • SPIi_SPTI:发送缓冲区空事件输出。

  • SPIi_SPEI:模式故障、欠载、溢出或奇偶校验错误事件输出。

  • SPIi_SPII:SPI空闲事件输出。

  • SPIi_SPCEND:传输完成事件输出。

23.3. OLED相关

OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display,OELD)。OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。 OLED 显示技术具有自发光的特性,采用非常薄的有机材料涂层和玻璃基板,当有电流通过时,这些有机材料就会发光,而且 OLED 显示屏幕可视角度大,并且能够节省电能。

本文使用是0.96 寸的 OLED 显示模块(蓝色)作为实验模块,详细资料可以在野火电子官网找到。实物如下所示:

OLED屏_SPI_0.96寸
  • 分辨率为 128*64

  • 驱动IC芯片为SSD1306

  • 4线SPI总线通信方式

原理图如下:

OLED_SSD1306模块原理图

23.3.1. 接口协议

对于4线制SPI接口协议,其通信过程对于片选信号和数据/命令切换信号的要求如下图所示

SSD1306 SPI接口协议要求

通过设置CS引脚为低电平,我们可以确定器件为选中状态, 设置其DC引脚不同的电平状态,来控制输出的指令为地址指令还是数据指令。

SSD1306的4线制SPI通信的时序如下图所示:

OLED-SPI通讯时序图

我们可以看到,CS信号线由高变低,是SPI通讯的起始信号,MOSI信号线负责传输数据, MOSI的数据在SCLK的下升沿或低电平期间变化输出,在SCLK上降沿的时候,SDIN(MOSI)的数据有效,SDIN(MOSI)将数据锁存, 高电平时表示数据“1”,为低电平时表示数据“0”。在其它时刻,数据无效。 SSD1306芯片则根据DC信号线的电平状态,来区分接受到的指令是地址指令还是数据指令, 最后,当数据/命令传输完毕后,CS信号线由低变高,解除对当前设备的选中状态,至此,一次数据传输完成。

23.3.2. 显存写入方式

SSD1306的显存写入方式有三种,分别是页地址模式,横向地址模式和纵向地址模式。 不同的地址模式下,把数据写入显存后,显存的地址变化方式是不一样的。 我们这里选择的是页地址模式,在页地址模式下,在发送完显示数据后,列地址指针将增加。 如果列地址指针到达列结束地址,则列地址指针为重置为列开始地址,而页地址指针不更改,需要用户设置新页面,并且 列地址为访问下一页显存。 页地址与列地址的移动顺序如下图所示:

SSD1306页地址模式

23.3.3. 命令字

关于SSD1306的基本命令字及说明如下表:

SSD1306的基本命令字

属性

命令字

说明

设置对比度

0x81

包含两个字节,第一个0X81为命令,随后发送的一个字节为要设置的对比度的值。

这个值设置得越大屏幕就越亮。

设置显示开关

0x8D

0XAE为关闭显示命令;0XAF为开启显示命令

电荷泵设置

0x81

包含2个字节,第一个为命令字,第二个为设置值,其中低位第三位为1,则开启电荷泵,为0则关闭。

在模块初始化的时候,这个必须要开启,否则是看不到屏幕显示的。

设置页地址

0xB0~0xB7

用于设置页地址,其低三位的值对应着页地址。

设置列地址低4位

0X00~0X0F

用于设置显示时的起始列地址低四位。

设置列地址高4位

0X10~0X1F

用于设置显示时的起始列地址高四位。

更多关于SSD1306的命令字的描述,见 SSD1306(OLED驱动芯片)指令详解

23.4. SPI-OLED显示实验

野火启明6M5开发板的扩展 SPI 接口电路图如图所示:

启明6M5开发板:SPI_PMOD接口

因为野火启明4M2开发板的扩展 SPI 接口被下载调试引脚占用,故采用GPIO-软件SPI的方式来测试实验。

野火启明4M2开发板的扩展 OLED 6线接口电路图如图所示:

启明4M2开发板:OLED接口

野火启明2L1开发板的扩展 SPI 接口电路图如图所示:

启明2L1开发板:SPI_PMOD接口

因为对于OLED模块,主机只需要发送显示数据,它也只需要接受显示数据,所以我们只需要连接MOSI这条线即可。

OLED模块连接引脚分配

开发板

OLED模块引脚

启明6M5

  • P203—-MOSI

  • P204—-CLK

  • P301—-CS

  • P302—-D/C

启明4M2

  • P602—-MOSI

  • P601—-CLK

  • P007—-CS

  • P008—-D/C

启明2L1

  • P203—-MOSI

  • P204—-CLK

  • P206—-CS

  • P007—-D/C

使用瑞萨官方提供的FPS库进行编程,瑞萨官方提供的FPS库具有方便、快捷、简洁的特性。

23.4.1. 新建工程

对于 e2 studio 开发环境:

拷贝一份我们之前的 e2s 工程模板 05_Template, 然后将工程文件夹重命名为 “SPI_OLED”,最后再将它导入到我们的 e2 studio 工作空间中。

对于 Keil 开发环境:

拷贝一份我们之前的 Keil 工程模板 05_Template, 然后将工程文件夹重命名为 “SPI_OLED”,并进入该文件夹里面双击 Keil 工程文件,打开该工程。

工程新建好之后,在工程根目录的 “src” 文件夹下面新建 “spi_oled” 文件夹, 再进入 “spi_oled” 文件夹里面新建源文件和头文件:“bsp_spi_oled.c” 和 “bsp_spi_oled.h”,并添加好字库文件 “codetab.h”,具体代码见下。

整个工程文件结构如下:

文件结构
SPI_OLED
├─ ......
└─ src
   ├─ spi_oled
   │  ├─ bsp_spi_oled.c
   │  ├─ bsp_spi_oled.h
   |  └─ codetab.h
   └─ hal_entry.c
codetab.h
 /************************************************************************************
 * Description:
 * 1. 128*64点整OLED模块功能演示程序的字表;
 * 2. 字表由打包资料中的“取字软件”计算得出;
 * 3. 取字方式 -- 共阴、列行式、逆向输出
 *
 *
 *************************************************************************************/

 /***************************16*16的点阵字体取模方式:共阴——列行式——逆向输出*********/
 #ifndef __CODETAB_H__
 #define __CODRTAB_H__

 const unsigned char F16x16[] =
 {
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/

 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/

 0x00,0xFE,0x92,0x92,0xFE,0x92,0x92,0xFE,0x00,0x42,0x4A,0xD2,0x6A,0x46,0xC0,0x00,
 0x40,0xC4,0x44,0x44,0x3F,0x24,0x24,0x24,0x00,0x40,0x80,0x7F,0x00,0x01,0x00,0x00,/*"野",0*/
 0x00,0x00,0xC0,0x38,0x00,0x00,0x00,0xFF,0x00,0x00,0x40,0x20,0x18,0x00,0x00,0x00,
 0x80,0x81,0x40,0x20,0x10,0x0C,0x03,0x00,0x03,0x0C,0x10,0x20,0x40,0x80,0x80,0x00,/*"火",1*/
 0x24,0x24,0xA4,0xFE,0xA3,0x22,0x00,0x22,0xCC,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,
 0x08,0x06,0x01,0xFF,0x00,0x01,0x04,0x04,0x04,0x04,0x04,0xFF,0x02,0x02,0x02,0x00,/*"科",2*/
 0x10,0x10,0x10,0xFF,0x10,0x90,0x08,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x08,0x00,
 0x04,0x44,0x82,0x7F,0x01,0x80,0x80,0x40,0x43,0x2C,0x10,0x28,0x46,0x81,0x80,0x00,/*"技",3*/



 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",6*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",6*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",7*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",7*/

 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/

 0x84,0x84,0xFC,0x84,0x84,0x40,0x5E,0x50,0x50,0x50,0xDF,0x50,0x50,0x50,0x5E,0x00,
 0x10,0x30,0x1F,0x08,0x08,0x00,0xFE,0x02,0x02,0x7F,0x02,0x7E,0x02,0x82,0xFE,0x00,/*"瑞",0*/
 0x04,0xE4,0x24,0x24,0xA4,0x6F,0x04,0x24,0x64,0xAF,0x34,0xA4,0x64,0x24,0x04,0x00,
 0x00,0xFF,0x00,0x11,0x22,0x9C,0x40,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,/*"萨",1*/

 0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00,
 0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00,/*"电",2*/
 0x80,0x82,0x82,0x82,0x82,0x82,0x82,0xE2,0xA2,0x92,0x8A,0x86,0x82,0x80,0x80,0x00,
 0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"子",3*/

 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",6*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",6*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",7*/
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",7*/
 };

 /************************************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
 };

 const unsigned char BMP1[] = {
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,
 0xC0,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,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,0x70,0x70,0x70,0xE0,0xC0,0x80,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0xF8,0x78,0x78,0x78,0xF8,
 0xF8,0xF8,0xF8,0x78,0x78,0x78,0xF8,0xF8,0xF8,0xF8,0x00,0xF8,0xF8,0x78,0x78,0x78,
 0x78,0x78,0x78,0x78,0x78,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,
 0xFE,0xFE,0xFE,0xFE,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xE0,0x80,
 0x00,0x00,0x00,0x00,0x3E,0xFF,0xC1,0xFF,0x7F,0x1F,0x7F,0xE6,0xE3,0xFF,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xFE,
 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xF0,0xE0,0xE0,0xFF,
 0xFF,0xFF,0xFF,0xE0,0xE0,0xE0,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x60,0xF8,0xF8,0xF8,
 0xF8,0xE0,0xF8,0xFE,0xFF,0x7F,0x1F,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0x18,0x00,0x00,0x00,0x00,0xFF,
 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xFC,0xFF,0xFF,
 0x00,0x00,0x00,0x80,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x01,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xFF,0xFF,0xFF,0xFF,
 0xFF,0xFF,0x7F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xC0,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xC1,0xC1,0xFF,
 0xFF,0xFF,0xFF,0xC1,0xC1,0xC1,0xFF,0xFF,0xFF,0xFF,0xF8,0xF8,0xF8,0xF8,0xF9,0xF1,
 0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xF0,0xF0,0xF0,0xF8,0xF8,0x38,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xF0,0x00,0x00,0x00,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
 0xE0,0xC0,0xE0,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x80,0xF0,0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x8F,
 0xE7,0xF3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFE,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC7,0xC7,0xC7,0xC7,0x87,0x83,0x87,
 0xFF,0xFF,0xFF,0x83,0x83,0x87,0x87,0xC7,0xC7,0xC7,0x05,0x01,0x01,0x01,0x00,0x00,
 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x78,0x7F,0x7F,0x7F,0x3F,0x01,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x0E,0x0F,0x0F,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0xC0,0xFC,0xFF,
 0xFF,0xFF,0x3F,0xFF,0xFF,0xFE,0xE0,0x80,0x00,0x00,0x01,0x07,0x07,0x0F,0x0F,0x1F,
 0x1F,0x1F,0x0F,0x0F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0xF8,0xFF,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC1,0x7C,0xFF,
 0xFF,0xFF,0xF8,0xF0,0xE0,0xF0,0xF0,0xFC,0xFE,0xFF,0xFF,0xFF,0x7F,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
 0xFF,0xFF,0xFF,0x07,0x07,0x87,0x87,0x87,0xC7,0xC7,0xC0,0x00,0x00,0x00,0x00,0x00,
 0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF8,0xFE,0xFF,0xFF,0x3F,
 0x0F,0x01,0x00,0x03,0x1F,0x7F,0xFF,0xFF,0xFC,0xF8,0xE0,0xC0,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,0x01,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0xFF,0xFE,0xFF,
 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x3F,0x0F,0x03,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x7E,0x7E,0x7E,0x3E,0x3E,0x3E,0x3E,0x1E,
 0x1F,0x1F,0x1F,0x1F,0x1F,0x0F,0x0F,0x0F,0x0F,0x0F,0x03,0x30,0xF0,0xF0,0xE0,0xE0,
 0xF0,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,
 0xC0,0xE0,0xF0,0xF0,0xF8,0xFC,0xFE,0xFE,0xFF,0x7F,0x1F,0x0F,0x07,0x03,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x1F,0x3F,0x7F,0x7F,0xFF,0xFE,0xFC,
 0xFC,0xF8,0xF8,0xF0,0x70,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,0x01,0x01,0x01,0x01,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
 0x03,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x01,0x03,0x07,0x07,0x07,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,
 0x03,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 };

 #endif

23.4.2. FSP配置

因为启明6M5/2L1开发板采用硬件SPI的方式,而启明4M2开发板采用GPIO模拟SPI的方式进行实验,所以FPS的配置也是不同的。

注解

关于硬件SPI与软件SPI的区别:

  1. 软件SPI:软件SPI需要用IO口模拟时序,这个模拟过程全部由CPU完成,为了能稳定的存入数据,可能插入软件延时,这个时间在读取数据量小的情况下不明显, 但是基本上你在读取过程中其他非中断、非异常程序是无法得到执行的。

  2. 硬件SPI:硬件SPI数据存储过程是不需要CPU参与的,程序中配置好SPI的访问时序,开启中断,CPU就可以在中断函数中搬移数据,省下了软件模拟IO的存取时间。

下面以启明6M5开发板为例,进行FSP配置。

首先打开 “41_SPI_OLED” 项目的 FSP 配置界面进行配置。

先配置CS,D/C引脚,在 FSP 配置界面里面点开 “Pins”-> “Poets”-> “P3”-> “P301” ,然后配置CS对应的IO引脚的 “Mode” 属性配置为 “Output mode (Initial High)”, 表示该引脚默认输出高电平,其他的属性默认即可。 D/C引脚也是按照这样进行配置。 启明2L1开发板与其类似,只是需要配置的引脚号不一样。 配置步骤如下图所示:

配置Ports

配置SPI,在 FSP 配置界面里面点开 “Pins”-> “Peripherals”-> “Connectivity:SPI”-> “SPI0”,选择A组并使能, 启明2L1开发板与其类似,只是选择的SPI模块为SPI1,A组。 配置步骤如下图所示:

配置SPI引脚

接着在 FSP 配置界面里面依次点击 “Stacks” -> “New Stack” -> “Connectivity” -> “SPI” 来添加SPI模块, 配置步骤如下图所示:

添加SPI模块

按照如下图所示对 SPI 模块属性进行配置

配置SPI模块

SPI 模块的属性介绍如下:

SPI 属性介绍

SPI属性

描述

Name

模块实例名。设置为g_spi0_flash

Channel

通道。这里选择spi0

Receive Interrupt Priority

接收中断优先级

Transmit Buffer Empty Interrupt Priority

发送缓存区空中断优先级

Transfer Complete Interrupt Priority

发送完成中断优先级

Error Interrupt Priority

错误中断优先级

Operating Mode

操作模式。可选SPI主机或从机

Clock Phase

SPI时钟相位(设置CPHA)

Clock Polarity

SPI时钟极性(设置CPOL)

Mode Fault Error

模式错误检测。检测主从模式冲突

Bit Order

位时序。MSB或LSB

Callback

中断回调函数。设置为spi_flash_callback

SPI Mode

SPI 模式。设置为SPI Operation

Full or Transmit Only Mode

全双工或仅发送模式选择

Slave Select Polarity

从机选择引脚极性。一般是低电平有效

Select SSL(Slave Select)

从机选择信号

MOSI Idle State

总线空闲时 MOSI 电平

Parity Mode

极性模式

Byte Swapping

字节交换模式

Bitrate

比特率

Clock Delay

时钟延迟

SSL Negation Delay

SSL失效延迟

Next Access Delay

下一次访问延迟

在 FSP 配置界面里面点开 “Pins”-> “Poets”-> “P0”-> “P007” ,然后配置IO引脚的 “Mode” 属性配置为 “Output mode (Initial High)”, 表示该引脚默认输出高电平,其他的属性默认即可。其他三个引脚也是按照这样进行配置。 配置步骤如下图所示:

配置GPIO

配置完成之后可以按下快捷键“Ctrl + S”保存, 最后点右上角的 “Generate Project Content” 按钮,让软件自动生成配置代码即可。

23.4.3. 对于启明6M5/2L1开发板的 “41_SPI_OLED” 工程:

当使用SPI接口时,我们通过 R_SPI_Write 这个函数,可以直接给我们的OLED模块发送指令,进行相应的操作。 R_SPI_Write 的函数原型如下:

fsp_err_t R_SPI_Write (spi_ctrl_t * const    p_api_ctrl,
                    void const          * p_src,
                    uint32_t const        length,
                    spi_bit_width_t const bit_width)

发送一个数组的数据,p_src 是指需要发送的数据,length 是指发送数据的个数,bit_width 是指每个要发送的数据的位宽。

中断回调函数的原型已经在hal_data.h中进行了声明,我们只需要对其进行定义即可。

/** Callback used by SPI Instance. */
#ifndef spi0_callback
void spi0_callback(spi_callback_args_t * p_args);
#endif

在本次实验中,在中断回调函数中,我们可以通过检测发送完成事件来判断SPI传输是否完成,并且还封装了一个发送超时等待函数。

中断回调函数
/**
* @brief  中断回调函数
* @param  SPI中断回调参数指针
* @retval 无
*/
void spi0_callback(spi_callback_args_t *p_args)
{
  if(p_args->event == SPI_EVENT_TRANSFER_COMPLETE)
  {
    g_transfer_complete = true;
  }
}
/**
* @brief  发送超时等待函数
* @param  无
* @retval 无
*/
static bool SPIWaitgtc(void)
{
  unsigned short wTimeout = 100;
  while(!g_transfer_complete && wTimeout)
  {
      R_BSP_SoftwareDelay(1u, BSP_DELAY_UNITS_MICROSECONDS);
      wTimeout--;
  }
  g_transfer_complete = false;
  if(g_transfer_complete==false && wTimeout==0)
      return false;
  return true;
}

当我们需要对OLED发送命令/数据时,通过将D/C引脚配置成低电平来确定发送的为命令指令,而需要发送数据时,将D/C引脚配置成高电平。

OLED发送命令/数据函数
void OLED_WrCmd(unsigned char cmd)
{
  OLED_DC_Clr();
  R_SPI_Write(&g_spi0_ctrl,&cmd,1,SPI_BIT_WIDTH_8_BITS);
  SPIWaitgtc();
}
void OLED_WrDat(unsigned char dat)
{
  OLED_DC_Set();
  R_SPI_Write(&g_spi0_ctrl,&dat,1,SPI_BIT_WIDTH_8_BITS);
  SPIWaitgtc();
}

对于CS与D/C引脚的操作我们也是封装了宏

#define OLED_CS_Pin       BSP_IO_PORT_03_PIN_01
#define OLED_CS_Clr()     R_IOPORT_PinWrite(&g_ioport_ctrl, OLED_CS_Pin, BSP_IO_LEVEL_LOW)
#define OLED_CS_Set()     R_IOPORT_PinWrite(&g_ioport_ctrl, OLED_CS_Pin, BSP_IO_LEVEL_HIGH)

#define OLED_DC_Pin       BSP_IO_PORT_03_PIN_02
#define OLED_DC_Clr()     R_IOPORT_PinWrite(&g_ioport_ctrl, OLED_DC_Pin, BSP_IO_LEVEL_LOW)
#define OLED_DC_Set()     R_IOPORT_PinWrite(&g_ioport_ctrl, OLED_DC_Pin, BSP_IO_LEVEL_HIGH)

最后我们来看一下OLED的初始化,开头是通过 R_SPI_Open 函数来启动SPI0,接着是对OLED的寄存器进行操作,这些参数不需要去了解,默认也不需要修改。

OLED初始化
void OLED_Init(void)
{
  fsp_err_t err = FSP_SUCCESS;
  err = R_SPI_Open(&g_spi0_ctrl,&g_spi0_cfg);//打开SPI模块
  assert(FSP_SUCCESS == err);

  R_BSP_SoftwareDelay(500u, BSP_DELAY_UNITS_MILLISECONDS);//延时500ms

  OLED_CS_Clr();

  OLED_WrCmd(0xae);
  OLED_WrCmd(0xae);//--turn off oled panel
  OLED_WrCmd(0x00);//---set low column address
  OLED_WrCmd(0x10);//---set high column address
  OLED_WrCmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
  OLED_WrCmd(0x81);//--set contrast control register
  OLED_WrCmd(0xcf); // Set SEG Output Current Brightness
  OLED_WrCmd(0xa1);//--Set SEG/Column Mapping     0xa0,0xa1
  OLED_WrCmd(0xc8);//Set COM/Row Scan Direction   0xc0,0xc8
  OLED_WrCmd(0xa6);//--set normal display
  OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
  OLED_WrCmd(0x3f);//--1/64 duty
  OLED_WrCmd(0xd3);//-set display offset      Shift Mapping RAM Counter (0x00~0x3F)
  OLED_WrCmd(0x00);//-not offset
  OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
  OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
  OLED_WrCmd(0xd9);//--set pre-charge period
  OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  OLED_WrCmd(0xda);//--set com pins hardware configuration
  OLED_WrCmd(0x12);
  OLED_WrCmd(0xdb);//--set vcomh
  OLED_WrCmd(0x40);//Set VCOM Deselect Level
  OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
  OLED_WrCmd(0x02);//
  OLED_WrCmd(0x8d);//--set Charge Pump enable/disable
  OLED_WrCmd(0x14);//--set(0x10) disable
  OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
  OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
  OLED_WrCmd(0xaf);//--turn on oled panel

  OLED_Fill(0x00);//清屏
  OLED_SetPos(0,0);
}

23.4.4. 对于启明4M2开发板的 “41_SPI_OLED” 工程:

对于四个要用来模拟SPI的引脚,我们也是封装了宏

#define SPI_SCK_Pin       BSP_IO_PORT_06_PIN_01
#define SPI_SCK_LOW()     R_IOPORT_PinWrite(&g_ioport_ctrl, SPI_SCK_Pin, BSP_IO_LEVEL_LOW)
#define SPI_SCK_HIGH()    R_IOPORT_PinWrite(&g_ioport_ctrl, SPI_SCK_Pin, BSP_IO_LEVEL_HIGH)

#define SPI_MOSI_Pin       BSP_IO_PORT_06_PIN_02
#define SPI_MOSI_LOW()     R_IOPORT_PinWrite(&g_ioport_ctrl, SPI_MOSI_Pin, BSP_IO_LEVEL_LOW)
#define SPI_MOSI_HIGH()    R_IOPORT_PinWrite(&g_ioport_ctrl, SPI_MOSI_Pin, BSP_IO_LEVEL_HIGH)

#define SPI_CS_Pin       BSP_IO_PORT_00_PIN_07
#define SPI_CS_LOW()      R_IOPORT_PinWrite(&g_ioport_ctrl, SPI_CS_Pin, BSP_IO_LEVEL_LOW)
#define SPI_CS_HIGH()     R_IOPORT_PinWrite(&g_ioport_ctrl, SPI_CS_Pin, BSP_IO_LEVEL_HIGH)

#define SPI_DC_Pin       BSP_IO_PORT_00_PIN_08
#define SPI_DC_LOW()      R_IOPORT_PinWrite(&g_ioport_ctrl, SPI_DC_Pin, BSP_IO_LEVEL_LOW)
#define SPI_DC_HIGH()     R_IOPORT_PinWrite(&g_ioport_ctrl, SPI_DC_Pin, BSP_IO_LEVEL_HIGH)

根据SSD1306的时序图,在SCLK信号为地电平的时候,改变MOSI的电平状态,输出完数据后将其拉高,延时一段时间后进行拉低SCLK,如此循环8次便可将一字节的数据传输出去。

OLED模拟SPI发送函数
/**
* @brief  模拟SPI发送数据函数
* @param  data:待发送数据
* @retval 无
*/
void SPI_WriteByte(unsigned char data)
{
  unsigned char i = 0;
  unsigned char temp = 0;
  for(i=0; i<8; i++)
  {
    temp = ((data&0x80)==0x80)? 1:0;
    data = data<<1;
    SPI_SCK_LOW();
    if(temp)
    {
      SPI_MOSI_HIGH();
    }
    else
    {
      SPI_MOSI_LOW();
    }
    R_BSP_SoftwareDelay(1u, BSP_DELAY_UNITS_MICROSECONDS);
    SPI_SCK_HIGH();
    R_BSP_SoftwareDelay(1u, BSP_DELAY_UNITS_MICROSECONDS);
  }
  SPI_SCK_HIGH();
}

同样的,模拟的OLED发送指令/数据函数与 OLED发送指令数据函数 类似,如下

OLED发送命令/数据函数
void OLED_WrCmd(unsigned char cmd)//写命令
{
  SPI_DC_LOW();
  SPI_WriteByte(cmd);
}
void OLED_WrDat(unsigned char dat)//写数据
{
  SPI_DC_HIGH();
  SPI_WriteByte(dat);
}

OLED的初始化,启明4M2开发板与启明6M5/2L1类似。

OLED初始化
void OLED_Init(void)
{
  SPI_CS_HIGH();
  SPI_SCK_HIGH();
  R_BSP_SoftwareDelay(100u, BSP_DELAY_UNITS_MICROSECONDS);

  SPI_CS_LOW();//拉高CS后拉低CS,选中OLED

  OLED_WrCmd(0xae);
  OLED_WrCmd(0xae);//--turn off oled panel
  OLED_WrCmd(0x00);//---set low column address
  OLED_WrCmd(0x10);//---set high column address
  OLED_WrCmd(0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
  OLED_WrCmd(0x81);//--set contrast control register
  OLED_WrCmd(0xcf); // Set SEG Output Current Brightness
  OLED_WrCmd(0xa1);//--Set SEG/Column Mapping     0xa0,0xa1
  OLED_WrCmd(0xc8);//Set COM/Row Scan Direction   0xc0,0xc8
  OLED_WrCmd(0xa6);//--set normal display
  OLED_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
  OLED_WrCmd(0x3f);//--1/64 duty
  OLED_WrCmd(0xd3);//-set display offset      Shift Mapping RAM Counter (0x00~0x3F)
  OLED_WrCmd(0x00);//-not offset
  OLED_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
  OLED_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
  OLED_WrCmd(0xd9);//--set pre-charge period
  OLED_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  OLED_WrCmd(0xda);//--set com pins hardware configuration
  OLED_WrCmd(0x12);
  OLED_WrCmd(0xdb);//--set vcomh
  OLED_WrCmd(0x40);//Set VCOM Deselect Level
  OLED_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
  OLED_WrCmd(0x02);//
  OLED_WrCmd(0x8d);//--set Charge Pump enable/disable
  OLED_WrCmd(0x14);//--set(0x10) disable
  OLED_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
  OLED_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
  OLED_WrCmd(0xaf);//--turn on oled panel

  OLED_Fill(0x00);
  OLED_SetPos(0,0);
}

23.4.5. hal_entry函数

在hal_entry函数中,初始化OLED。

hal_entry.c
void hal_entry(void)
{
    /* TODO: add your own code here */
  unsigned char i;
  extern const unsigned char BMP1[];
  OLED_Init();//初始化
  while(1)
  {
    OLED_Fill(0xff);//填充屏幕
    R_BSP_SoftwareDelay(2u, BSP_DELAY_UNITS_SECONDS);
    OLED_CLS();//清屏
    for(i=0; i<8; i++)//通过点阵显示汉字 -- i表示子表中汉字的位置
    {
      OLED_16x16CN(i*16,0,i);
      OLED_16x16CN(i*16,4,i+8);
    }
    R_BSP_SoftwareDelay(2u, BSP_DELAY_UNITS_SECONDS);
    OLED_CLS();
    //显示不同字体大小的英文
    OLED_6x8Str(0,1,(unsigned char *)"www.embedfire.com");
    OLED_8x16Str(0,2,(unsigned char *)"Wildfire Tech");
    OLED_8x16Str(10,4,(unsigned char *)"SPI-OLED");
    R_BSP_SoftwareDelay(4u, BSP_DELAY_UNITS_SECONDS);
    OLED_CLS();
    //显示图片
    OLED_BMP(0,0,128,8,(unsigned char *)BMP1);
    R_BSP_SoftwareDelay(4u, BSP_DELAY_UNITS_SECONDS);
  }
#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

在循环中点亮屏幕,2秒后熄灭屏幕,然后使用 OLED_16x16CN 函数显示中文,使用 OLED_6x8Str 函数测试6*8字符,使用 OLED_8x16Str函数测试8*16字符,最后只用 OLED_BMP 函数测试BMP位图显示。

把代码下载后,可以看到OLED屏幕上由 清屏-> 显示中文 -> 显示英文 -> 显示图片 的顺序循环显示。

启明6M5/2L1开发板 SPI_OLED 实验现象:

启明6M5/2L1开发板 SPI_OLED 实验现象

启明4M2开发板 SPI_OLED 实验现象:

启明4M2开发板 SPI_OLED 实验现象