STM32F4_软件模拟SPI

目录

1. 硬件连接

2. SPI通讯协议

3. W25Q64 简介

4. 程序详解

4.1 main.c

4.2 SPI.c

4.3 SPI.h

4.4 W25Q128.c

4.5 W25Q128.h

4.6 OLED.c

4.7 OLED.h

4.8 OLED_Font.h

5. 实验结果


        我们都知道,SPI 和 IIC 一样,都可以通过硬件方式和软件方式来驱动,在上一节,我们学习如何通过STM32F4的硬件去驱动SPI,本节我们学习如何通过软件模拟SPI,软件模拟SPI的最大好处就是引脚的灵活性,只要可以控制引脚输出高低电平,形成SPI通讯时序,那么任何四个引脚都可以充当 MOSI、MISO、SCL、CS;

        对硬件驱动SPI(以及SPI时序、SPI相关基础知识)有疑问的,请移至:

        STM32F4_SPI协议详解_light_2025的博客-CSDN博客

1. 硬件连接

        本次使用的是STM32F407开发板,既然是使用软件去模拟SPI,那么就不再使用开发板的外设资源,也就是不再使用开发板上的PB3、PB4、PB5、PB14引脚了;

        首先,使用软件模拟SPI首先需要知道SPI的通讯时序,需要控制相应的引脚输出高低电平来形成SPI的通讯时序;本节使用的Flash芯片是下述的这款(江科大的面包板套件中的这款),通过STM32F4外接杜邦线接到这个引脚来读写该芯片,通过外接OLED来显示现象;

VCC --- 3.3V

GND --- GND

CS --- PB6

DO(MISO) --- PB7

CLK --- PB8

DI(MOSI) --- PB9

GND --- GND

VCC --- 3.3V

SCL --- PE5

SDA --- PE6

2. SPI通讯协议

        下图是 SPI 主从机的 MOSI 和 MISO 进行数据交换的示意图:

        SPI 主机内部有一个波特率发生器,用来产生时钟SCK,波特率发生器产生时钟驱动主机的移位寄存器进行移位,同时产生时钟驱动从机的移位寄存器。SPI 通讯是高位在前,当 SCK 上升沿时,主机移位寄存器的最高位移至 MOSI 数据线上,从机的最低位移至 MISO 数据线上;SCK 低电平期间,MOSI 数据线上的数据移至 SPI 从机,MISO 数据线上的数据移至 SPI 主机;以此完成一位的交换;(更通俗易懂点就是:第一次交换时,SCK高电平期间,主机的最高位1放到MOSI数据线上,从机的最低位1放到MISO数据线上,SCK低电平期间,MOSI数据线上的数据移至从机的最低位,MISO数据线上的数据移至主机的最低位,这样经过8次循环,就可以完成一个字节的交换,并且每次循环都会将最低位的值逐步移到移位寄存器的最高位,保证了SPI高位在前的原则)

SPI 时序基本单元:

        起始条件:SS从高电平切换到低电平

        终止条件:SS从低电平切换到高电平

        根据CPOL和CPHA的变化(CPOL和CPHA在STM32F4硬件驱动SPI有介绍),交换一个字节,可以产生4种模式:分别是模式0、模式1、模式2、模式3;

交换一个字节(模式0)

        CPOL=0:空闲状态下,SCK为低电平

        CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据(在硬件驱动SPI时,将这一过程称作奇数边沿采样或者偶数边沿采样)

交换一个字节(模式1)

        CPOL=0:空闲状态下,SCK为低电平

        CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据(本节写程序时用的就是模式1,通过下图可以发现,SS低电平时,从机被选中,SCK处于低电平,当SCK高电平时,MOSI和MISO进行数据交换,SCK低电平期间,最高位的数据交换完成)

交换一个字节(模式2)

        CPOL=1:空闲状态下,SCK为高电平

        CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

交换一个字节(模式3)

        CPOL=1:空闲状态下,SCK为高电平

        CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据

//交换一个字节,SPI是全双工通讯,MOSI和MISO同时进行工作,也就是发送和接收是同时开始的,所以SPI的通讯速率比IIC要快
unsigned char MySPI_SwapByte(unsigned char ByteSend)
{
    //交换的原则就是根据SCK高低电平的变换,将MOSI和MISO数据线上数据进行移入和移出
    unsigned char i,ByteReceive = 0x00;
    for(i=0;i<8;i++)
    {
        GPIO_WriteBit(GPIOB,GPIO_Pin_9,(ByteSend&(0x80>>i))); //初始化SCK低电平,所以SCK低电平期间,主机取出要发送数据的最高位放在MOSI数据线上
        GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_SET); //SCK置高电平
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1) //因为SPI发送和接收是同步进行的,所以主机将数据放至MOSI数据线的同时,从机也将数据放至MISO数据线上了
            //此时读取MISO数据线的电平,因为PA7设置上拉输入,所以若PA7引脚为高电平,则表示有数据交换
        {
            ByteReceive = ByteReceive | (0x80>>i);//将接收的这一位放至变量ByteReceive的最高位,依次移位,获取完成的一个字节
        }
        GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_RESET); //SCK置低电平,完成一位的发送接收
    }
    return ByteReceive;
    //这里解释一下,为什么只判断了主机的电平变换,因为SPI可以设置主发送主接收、主发送从接收、主接收从发送;
    //所谓设置模式,简单来说就是,你可以发送,但是我不看你发送的内容就是了;
}

3. W25Q64 简介

        W25QXX 系列是一种低成本、小型化、使用简单的非易失性存储器,常应用于数据存储、子库存储、固件程序存储等场景。

        存储介质:Nor Flash(闪存)

        时钟频率:80MHz/160MHz(Dual SPI)/320MHz(Quad SPI)

        存储容量(24位地址):

  •                 W25Q40:    4Mbit / 512KByte
    •                 W25Q80:    8Mbit / 1MByte
      •                 W25Q16:    16Mbit / 2MByte
        •                 W25Q32:    32Mbit / 4MByte
          •                 W25Q64:    64Mbit / 8MByte
            •                 W25Q128:  128Mbit / 16MByte
              •                 W25Q256:  256Mbit / 32MByte

DO、/WP、/HOLD、DI 这四个引脚用于双重SPI和四重SPI使用,如果需要使用双重SPI或者四重SPI,那么只需要将这四个引脚接到STM32的GPIO口上即可;

W25Qxx的划分通常是首先分为若干个块Block,每个块又分为若干个扇区Sector,每个扇区又分为若干个页Page;

Flash 操作注意事项:

写入操作时:

写入操作前,必须先进行写使能
每个数据位只能由 1 改写为 0 ,不能由 0 改写为 1(这是Flash的擦除规则,假设原本地址是1010 1010 ,想要写入0101 0101,第二位0是不能变为1的,所以最终结果是0000 0000)
写入数据前必须先擦除,擦除后,所有数据位变为 1(要写入新数据必须先先擦除整个扇区,擦除后整个扇区都是1)
擦除必须按最小擦除单元进行(意思就是说:擦除必须擦除一个最小单元(可以是一个扇区,也可以是一页),倘若我想要擦除某个字节,那么只能先将数据复制保存至某个缓存区,然后擦除整页,最后再进行擦除某个字节的操作)
连续写入多字节时,最多写入一页的数据,超过页尾位置的数据,会回到页首覆盖写入(就是说:倘若要写入的字节数超过了这一页最多能容纳的字节数,那么就会从起始位置开始覆盖)
写入操作结束后,芯片进入忙状态,不响应新的读写操作(写入操作结束后,芯片内部Flash会有一个搬运的过程,这个时候芯片会进入忙状态,可以通过获取状态寄存器的最低位BUSY来获取芯片当前的状态,倘若BUSY=0,表示芯片忙完了,BUSY=1,表示芯片还在忙)

读取操作时:

直接调用读取时序,无需使能,无需额外操作,没有页的限制,读取操作结束后不会进入忙状态,但不能在忙状态时读取

W25Q64芯片的指令集:

        第一个Winbond Serial Flash就是厂商ID,0xEF(h后缀表示是十六进制);第二个Device ID是设备ID,0x4017

        Write Enable是写使能,只需要调用我们已经写好的MySPI_SwapByte写入0x06即可,后需不需要再跟任何操作即可完成写使能;

        Read Status Register-1是度状态寄存器,调用MySPI_SwapByte写入0x05的前提下,还需要发送所需要读取的 位0~位7;

        Page Program是对页进行操作,调用MySPI_SwapByte写入0x02的前提下,需要写入24位地址,分三次写,因为MySPI_SwapByte每次只能写三位,最后读出这24位地址上的数据 D7~D0;

        Block Erase(64KB)、Block Erase(32KB)是擦除块,分别擦除64KB、32KB;

        Sector Erase(4KB)是擦除删除,每次擦除4KB;调用MySPI_SwapByte写入0x20的前提下,写入24位地址,即可将这24位地址上的数据进行擦除;

        JEDEC ID是读取ID的操作,调用MySPI_SwapByte写入0x9F的前提下,读取MF7~MF0,8位厂商ID,在分别读取设备ID的高八位 ID15~ID8 和低八位 ID7~ID0;

        Read Data是读取数据的操作,调用MySPI_SwapByte写入0x03的前提下,分三次写入要读取的地址A23~A0,最后读取这24位地址上的数据 D7~D0;

4. 程序详解

        本节程序是基于STM32F407开发板的,使用模块为 W25Q64 和 4针OLED屏;(具体引脚接法上述已有介绍),通过将数据写入W25Q64,最终在读取数据;将结果显示在 OLED 上;

4.1 main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "Key.h"
#include "OLED.h"
#include "lcd.h"
#include "W25Q128.h"
#include "SPI.h"

//这两个ID是固定的,在手册中有显示 
uint8_t MID; //厂商ID
unsigned int DID; //设备ID

uint8_t ArrayWrite[] = {0x01, 0x02, 0x03, 0x04}; //定义一个数组,内容为要往W25Q64写入的数据,16进制的1 2 3 4
uint8_t ArrayRead[4]; //定义一个数组用来读取写入的值

int main(void)
{ 
	delay_init(168);      //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200
	
    OLED_Iic_Init();
    OLED_Init();
    
    W25Q64_Init();
	
	OLED_ShowString(1, 1, "MID:   DID:"); //OLED起始显示厂商ID和设备ID,芯片手册记录厂商ID为0xEF,设备ID为0x4017;
	OLED_ShowString(2, 1, "W:");
	OLED_ShowString(3, 1, "R:"); //作为标志,表示写入的数据和读取的数据
	
	W25Q64_ReadID(&MID, &DID); //调用函数获取读取的厂商ID和设备ID,函数W25Q64_ReadID参数为指针类型,所以取地址,获取该指针指向地址的数据
	OLED_ShowHexNum(1, 5, MID, 2);
	OLED_ShowHexNum(1, 12, DID, 4); //OLED_ShowHexNum显示16进制数
	
	W25Q64_SectorErase(0x000000); //通过W25Q64芯片手册,可以发现每个扇区的起始地址为0x000,每个扇区的终止地址是0xFFF
                                  //所以0x000000的最后三位可以随便写,表示的都是擦除同一个扇区,我们一般锁定起始地址0x000
	W25Q64_WriteProgram(0x000000, ArrayWrite, 4); //写一页,写入的数据为数组ArrayWrite[]的内容
	
	W25Q64_ReadData(0x000000, ArrayRead, 4); //获取数据,地址要和写入的地址对应;将读取的数据保存在数组ArrayRead[];
	
	OLED_ShowHexNum(2, 3, ArrayWrite[0], 2);
	OLED_ShowHexNum(2, 6, ArrayWrite[1], 2);
	OLED_ShowHexNum(2, 9, ArrayWrite[2], 2);
	OLED_ShowHexNum(2, 12, ArrayWrite[3], 2); //显示写入的ArrayWrite[]的内容
	
	OLED_ShowHexNum(3, 3, ArrayRead[0], 2);
	OLED_ShowHexNum(3, 6, ArrayRead[1], 2);
	OLED_ShowHexNum(3, 9, ArrayRead[2], 2);
	OLED_ShowHexNum(3, 12, ArrayRead[3], 2); //读出ArrayRead[]数组下的内容,将结果在OLED上显示
	
	while (1)
	{
		
	}
}

4.2 SPI.c

#include "stm32f4xx.h"             
#include "SPI.h"

//VCC --- 3.3V
//GND --- GND
//CS --- PB6
//DO(MISO) --- PB7
//CLK --- PB8
//DI(MOSI) --- PB9

//输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入
void MySPI_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
    
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;  //模式需要设置为输出
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;  //设置为推挽输出
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_8|GPIO_Pin_9; //分别对应输出DI、CLK、CS
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7; //对应于DO引脚,Flash芯片输出,对应STM32F4引脚设置为输入
    GPIO_Init(GPIOB,&GPIO_InitStructure);
    
    GPIO_WriteBit(GPIOB,GPIO_Pin_6,Bit_SET); //初始化片选信号线设置为高电平,表示主机SPI处于空闲状态
    GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_RESET); //初始化CLK低电平,表示空闲状态下,SCK为低电平,也就是CPOL=0;
                                               //CPHA=0表示SCK第一个边沿移入数据,第二个边沿移出数据
}
//通讯开始
void MySPI_Start(void)
{
    GPIO_WriteBit(GPIOB,GPIO_Pin_6,Bit_RESET);//片选信号线拉低,表示SPI通讯的开始
}
//通讯结束
void MySPI_Stop(void)
{
    GPIO_WriteBit(GPIOB,GPIO_Pin_6,Bit_SET);//片选信号线拉高,表示SPI通讯的结束
}
//交换一个字节,SPI是全双工通讯,MOSI和MISO同时进行工作,也就是发送和接收是同时开始的,所以SPI的通讯速率比IIC要快
unsigned char MySPI_SwapByte(unsigned char ByteSend)
{
    //交换的原则就是根据SCK高低电平的变换,将MOSI和MISO数据线上数据进行移入和移出
    unsigned char i,ByteReceive = 0x00;
    for(i=0;i<8;i++)
    {
        GPIO_WriteBit(GPIOB,GPIO_Pin_9,(ByteSend&(0x80>>i))); //初始化SCK低电平,所以SCK低电平期间,主机取出要发送数据的最高位放在MOSI数据线上
        GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_SET); //SCK置高电平
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1) //因为SPI发送和接收是同步进行的,所以主机将数据放至MOSI数据线的同时,从机也将数据放至MISO数据线上了
            //此时读取MISO数据线的电平,因为PA7设置上拉输入,所以若PA7引脚为高电平,则表示有数据交换
        {
            ByteReceive = ByteReceive | (0x80>>i);//将接收的这一位放至变量ByteReceive的最高位,依次移位,获取完成的一个字节
        }
        GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_RESET); //SCK置低电平,完成一位的发送接收
    }
    return ByteReceive;
    //这里解释一下,为什么只判断了主机的电平变换,因为SPI可以设置主发送主接收、主发送从接收、主接收从发送;
    //所谓设置模式,简单来说就是,你可以发送,但是我不看你发送的内容就是了;
}



4.3 SPI.h

#ifndef _SPI__H_
#define _SPI__H_
#include "sys.h"

void MySPI_Init(void);
void MySPI_Start(void);
void MySPI_Stop(void);
unsigned char MySPI_SwapByte(unsigned char ByteSend);


#endif

4.4 W25Q128.c

        这里纠正一下:原本打算使用的是 W25Q128 芯片,最后因为某些原因最终还是使用了 W25Q64 芯片,所以文件命名问题不要在意!!!(所有程序都是基于W25Q64芯片的)

#include "stm32f4xx.h"          
#include "W25Q128.h"
#include "SPI.h"


//VCC --- 3.3V
//GND --- GND
//CS --- PB6
//DO(MISO) --- PB7
//CLK --- PB8
//DI(MOSI) --- PB9

//W25Q64初始化
void W25Q64_Init(void)
{
    //W25Q64初始化只需要初始化SPI即可;
    MySPI_Init(); 
}

//获取W25Q64的ID
//根据W25Q64的芯片手册可以知道:W25Q64的厂商ID是0xEF,设备ID是0x4017;
void W25Q64_ReadID(unsigned char *MID,unsigned int *DID) //MID是8位厂商ID,DID是16位设备ID
{
    //通过W25Q64的芯片手册提供的指令:获取W25Q64的ID需要调用SPI交换字节函数MySPI_SwapByte写入0x9F,紧接着读取8位厂商ID和16位设备ID即可
    MySPI_Start(); //SPI起始信号
    //#define W25Q64_JEDEC_ID								0x9F
    MySPI_SwapByte(W25Q64_JEDEC_ID); //MySPI_SwapByte主机发送0x9F给从机,表示查询ID号
    //#define W25Q64_DUMMY_BYTE							0xFF
    *MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE); //和从机W25Q64交换8位厂商ID
    *DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE); //第一次和从机W25Q64交换设备ID的高八位 ID15~ID8
    *DID = *DID << 8; //16位设备ID,低八位左移至高八位,低八位置0
    *DID = *DID | MySPI_SwapByte(W25Q64_DUMMY_BYTE); //第二次和从机W25Q64交换设备ID的低八位 ID7~ID0,使用或运算将低八位和高八位拼接为完整的16位设备ID
    MySPI_Stop(); //SPI停止信号
}

//W25Q64写使能
void W25Q64_WriteEnable(void)
{
    //W25Q64的芯片手册提供的指令:Write Enable是写使能,只需要主机给从机发送数据0x06即可,后序不需要任何指令就可以完成写使能操作
    MySPI_Start();
    //#define W25Q64_WRITE_ENABLE							0x06
	MySPI_SwapByte(W25Q64_WRITE_ENABLE); //MySPI_SwapByte主机发送0x06给从机,表示写使能
	MySPI_Stop();
}

//W25Q64等待忙碌
void W25Q64_WaitBusy(void)
{
    //W25Q64等待忙碌BUSY是因为:芯片在接收到数据以后还需要内部进行搬运的操作,这需要一定的时间,所以在接收到数据以后,芯片会进入忙状态BUSY;
    //可以通过获取状态寄存器的最低位BUSY来得知W25Q64是否处于忙状态;
    //BUSY=0表示芯片不处于忙状态;BUSY=1表示芯片处于忙状态;
    uint32_t TimeOut;
    MySPI_Start(); //SPI起始信号
    //#define W25Q64_READ_STATUS_REGISTER_1				0x05
    MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1); //主机发送0x05给从机W25Q64,表示Read Status Register-1 读取状态寄存器,状态寄存器的最低位为BUSY;
	TimeOut = 100000; //设置一个一定超过忙状态的时间,通过查询W25Q64数据手册,BUSY忙状态的时间最多为 3ms ;
    //#define W25Q64_DUMMY_BYTE							0xFF
    while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01)
	{   //Read Status Register-1 读取状态寄存器,MySPI_SwapByte主机发送0x05给从机,紧接着和从机交换8位状态寄存器的值 S7~S0
        //MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01 表示取出状态寄存器的最低位BUSY,如果是1则表示芯片处于忙状态,则一直在 while 循环中循环
        //while循环中设置一个递减的时间TimeOut,这个时间值远远大于BUSY忙状态的时间,这个时间递减到0则表示忙状态一定是结束了,Break跳出循环
		TimeOut --;
		if (TimeOut == 0)
		{
			break;
		}
	}
	MySPI_Stop(); //SPI停止信号
}

//W25Q64写一页数据
//W25Q64的芯片手册提供的指令:Page Program 表示对Flash芯片的页进行操作
//具体流程是:MySPI_SwapByte主机发送0x02给从机,紧接分三次和从机交换地址 A23~A16、A15~A8、A7~A0,之所以分三次是因为MySPI_SwapByte函数的类型是unsigned char,每次只能操作8位
//最后主机和从机交换这24位地址上的数据 D7~D0
void W25Q64_WriteProgram(uint32_t Address,unsigned char *DataArray,unsigned int Count)
{//第一个参数表示要操作的这32位地址;第二个参数表示Address地址上的8位数据;第三个表示要获取的数据长度;
    unsigned int i;
    
    W25Q64_WriteEnable(); //写数据操作首先就要写使能,就像我们使用时钟、GPIO口一样,需要首先使能时钟和GPIO口,这里不过多解释!
    MySPI_Start(); //SPI起始信号
    //#define W25Q64_PAGE_PROGRAM							0x02
    MySPI_SwapByte(W25Q64_PAGE_PROGRAM); //MySPI_SwapByte主机发送0x02给从机
	MySPI_SwapByte(Address >> 16); //32位地址右移16位表示将原本第15~31位放到第0~15位;MySPI_SwapByte每次操作8位,所以该程序表示和从机交换地址 A23~A16
	MySPI_SwapByte(Address >> 8);  //32位地址右移8位表示将原本第8~31位放到第0~23位; MySPI_SwapByte每次操作8位,所以该程序表示和从机交换地址 A15~A8
	MySPI_SwapByte(Address);    //MySPI_SwapByte每次操作8位,所以该程序表示和从机交换地址 A7~A0
    for(i = 0; i < Count; i ++)
    {
        MySPI_SwapByte(DataArray[i]); //紧接着主机和从机交换这24位地址上数据 D7~D0;
        //采用for循环,循环的时间复杂度为Count;
        //表示接收完这24位地址上的数据 D7~D0,接着接收数据,直到把长度为 Count 的数据接收完以后,跳出for循环
    }
    MySPI_Stop(); //SPI停止信号
    
    W25Q64_WaitBusy(); //等待芯片接收数据以后芯片内部搬运操作结束
}

//W25Q64擦除一页
//W25Q64的芯片手册提供的指令:Block Erase(64KB)、Block Erase(32KB)、Sector Erase(4KB)
//简单说一下,这三个擦除的区别,Flash芯片写之前必须要擦除,擦除会使得整个最小单元全部变为1;
//Flash芯片一般是首先将整个内存分为若干个块Block,将每一个块分为若干个扇区Sector,每一个扇区分为若干页Page;具体分成多少根据W25QXX的类型而定
//如果我们想要擦除某个字节,必须先将这一扇区的数据复制到数据缓存区中,然后擦除整个扇区,然后再将数据缓存中的内容重新写入擦除后的扇区中,擦除某个字节的操作在这个过程中进行
//并不是我们想要擦除哪个地址,就单独去擦除这一块地址就行;
//所以绝大多数情况下,我们并不希望擦除的数据过多,因此在此我们选择擦除扇区Sector,每次擦除4KB;
//*******************************************************************************************
//具体流程是:MySPI_SwapByte主机发送0x20给从机,紧接分三次和从机交换地址 A23~A16、A15~A8、A7~A0,就可以擦除这24位地址上的数据了
void W25Q64_SectorErase(uint32_t Address)
{
    W25Q64_WriteEnable(); //首先开始写使能
	
	MySPI_Start(); //SPI起始信号
    //#define W25Q64_SECTOR_ERASE_4KB						0x20
	MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB); //MySPI_SwapByte主机发送0x20给从机
	MySPI_SwapByte(Address >> 16); //和从机交换地址 A23~A16
	MySPI_SwapByte(Address >> 8); //和从机交换地址 A15~A8
	MySPI_SwapByte(Address); //和从机交换地址 A7~A0
	MySPI_Stop(); //SPI停止信号
	
	W25Q64_WaitBusy(); //等待芯片内部搬运过程结束
}

//W25Q64读取数据
//W25Q64的芯片手册提供的指令:Read Data
//具体流程是:MySPI_SwapByte主机发送0x03给从机,紧接分三次和从机交换地址 A23~A16、A15~A8、A7~A0,最后和从机W25Q64交换这24位地址上数据 D7~D0
void W25Q64_ReadData(uint32_t Address,unsigned char *DataArray,uint32_t Count)
{第一个参数表示要操作的这32位地址;第二个参数表示Address地址上的8位数据;第三个表示要获取的数据长度;
    uint32_t i;
	MySPI_Start(); //SPI起始信号
    //#define W25Q64_READ_DATA							0x03
	MySPI_SwapByte(W25Q64_READ_DATA); //MySPI_SwapByte主机发送0x03给从机
	MySPI_SwapByte(Address >> 16); //和从机交换地址 A23~A16
	MySPI_SwapByte(Address >> 8); //和从机交换地址 A15~A8
	MySPI_SwapByte(Address); //和从机交换地址 A7~A0
	for (i = 0; i < Count; i ++)
	{
        //#define W25Q64_DUMMY_BYTE							0xFF
		DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE); //将主机从Address地址上读取的长度为Count的数据保存到DataArray数组中
	}
	MySPI_Stop(); //SPI停止信号
}


4.5 W25Q128.h

#ifndef _W25Q128__H_
#define _W25Q128__H_
#include "sys.h"

#define W25Q64_WRITE_ENABLE							0x06
#define W25Q64_WRITE_DISABLE						0x04
#define W25Q64_READ_STATUS_REGISTER_1				0x05
#define W25Q64_READ_STATUS_REGISTER_2				0x35
#define W25Q64_WRITE_STATUS_REGISTER				0x01
#define W25Q64_PAGE_PROGRAM							0x02
#define W25Q64_QUAD_PAGE_PROGRAM					0x32
#define W25Q64_BLOCK_ERASE_64KB						0xD8
#define W25Q64_BLOCK_ERASE_32KB						0x52
#define W25Q64_SECTOR_ERASE_4KB						0x20
#define W25Q64_CHIP_ERASE							0xC7
#define W25Q64_ERASE_SUSPEND						0x75
#define W25Q64_ERASE_RESUME							0x7A
#define W25Q64_POWER_DOWN							0xB9
#define W25Q64_HIGH_PERFORMANCE_MODE				0xA3
#define W25Q64_CONTINUOUS_READ_MODE_RESET			0xFF
#define W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID		0xAB
#define W25Q64_MANUFACTURER_DEVICE_ID				0x90
#define W25Q64_READ_UNIQUE_ID						0x4B
#define W25Q64_JEDEC_ID								0x9F
#define W25Q64_READ_DATA							0x03
#define W25Q64_FAST_READ							0x0B
#define W25Q64_FAST_READ_DUAL_OUTPUT				0x3B
#define W25Q64_FAST_READ_DUAL_IO					0xBB
#define W25Q64_FAST_READ_QUAD_OUTPUT				0x6B
#define W25Q64_FAST_READ_QUAD_IO					0xEB
#define W25Q64_OCTAL_WORD_READ_QUAD_IO				0xE3

#define W25Q64_DUMMY_BYTE							0xFF

//W25Q64初始化
void W25Q64_Init(void);
void W25Q64_ReadID(unsigned char *MID,unsigned int *DID);
void W25Q64_WriteEnable(void);
void W25Q64_WaitBusy(void);
void W25Q64_WriteProgram(uint32_t Address,unsigned char *DataArray,unsigned int Count);
void W25Q64_SectorErase(uint32_t Address);
void W25Q64_ReadData(uint32_t Address,unsigned char *DataArray,uint32_t Count);


#endif

4.6 OLED.c

        OLED模块通过杜邦线接到了STM32F407开发板上,通过软件模拟IIC的方式进行驱动;(在使用的过程中需要注意:F1开发板和F4开发板的OLED初始化函数是不一样的,在移植的过程中需要特别注意!!!)

#include "OLED.h"
#include "delay.h"
#include "OLED_Font.h"

/*
引脚说明:
模拟IIC初始化(PE8 PE10)
PE5 -- OLED_SCL
PE6 -- SDA  (数据线是输入及输出作用)


*/



void OLED_Iic_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	
	//使能GPIOE,GPIOD组时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_5|GPIO_Pin_6;    	//引脚5 6
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_OUT; 	//输出模式
	GPIO_InitStruct.GPIO_OType	= GPIO_OType_PP; 	//推挽输出
	GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_100MHz; //输出速度
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;
	
	GPIO_Init(GPIOE, &GPIO_InitStruct);
	
	
	//让总线空闲
	OLED_SCL = 1;
	OLED_SDA_OUT = 1;


}

//数据模式变化函数
void  OLED_Iic_Sda_Mode(GPIOMode_TypeDef GPIO_Mode)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_6;    	//SDA
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode; 		//模式
	GPIO_InitStruct.GPIO_OType	= GPIO_OType_PP; 	//推挽输出
	GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz; //输出速度
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;
	
	GPIO_Init(GPIOE, &GPIO_InitStruct);

}

//起始信号
void  OLED_Iic_Start(void)
{
	//输出模式
	OLED_Iic_Sda_Mode(GPIO_Mode_OUT);
	//保证为空闲状态
	OLED_SCL = 1;
	OLED_SDA_OUT = 1;	
	delay_us(5);
	
	OLED_SDA_OUT = 0;  //SDA由高变低电平,实现电平跳变
	delay_us(5);
	OLED_SCL = 0;      //钳住总线
}
//停止信号
void  OLED_Iic_Stop(void)
{
	//输出模式
	OLED_Iic_Sda_Mode(GPIO_Mode_OUT);
	
	//保证两边均为低电平
	OLED_SCL = 0;
	OLED_SDA_OUT = 0;
	delay_us(5);
	
	OLED_SCL = 1;
	delay_us(5);
	OLED_SDA_OUT = 1;  //两个信号拉高,总线空闲,此时IIC停止数据传输
	
	
}

//发送一位数据 数据要么是1,要么是0  ack:要么是0,要么:1
//ack = 0;发送有效应用  ack = 1;发送非应答
void  OLED_Iic_Send_Ack(u8 ack)
{
	//输出模式
	OLED_Iic_Sda_Mode(GPIO_Mode_OUT);
	
	//低电平,允许变更
	OLED_SCL = 0;
	//准备数据
	if(ack == 1) //想要引脚输出1
	{
		OLED_SDA_OUT = 1;
	}
	if(ack == 0) //想要引脚输出0
	{
		OLED_SDA_OUT = 0;
	}
	//形成脉冲周期
	delay_us(5);
	OLED_SCL = 1;
	delay_us(5);
	OLED_SCL = 0;
}

//发送一个字节
void  OLED_Iic_Send_Byte(u8 data)
{
	
	u8 i;
	
	//输出模式
	OLED_Iic_Sda_Mode(GPIO_Mode_OUT);
	
	//低电平,允许变更
	OLED_SCL = 0;
	
	for(i=0; i<8; i++)
	{
	
		//准备数据
		if(  data  & (1<<(7-i)) )
		{
			OLED_SDA_OUT = 1;
		}
		else
		{
			OLED_SDA_OUT = 0;
		}
		
	
	
		//形成脉冲周期
		delay_us(5);
		OLED_SCL = 1;
		delay_us(5);
		OLED_SCL = 0;
	}
}


//接收一位数据
u8  OLED_Iic_Recv_Ack(void)
{
	
	u8 ack = 0;
	
	//输入模式
	OLED_Iic_Sda_Mode(GPIO_Mode_IN);
	
	//形成脉冲周期
	OLED_SCL = 0;

	
	delay_us(5);
	OLED_SCL = 1;
	delay_us(5);
	
	//高电平接收数据,数据根据引脚电平来决定
	if(OLED_SDA_IN == 1)
	{
		ack = 1;
	}
	if(OLED_SDA_IN == 0)
	{
		ack = 0;
	}

	OLED_SCL = 0;
	
	
	return ack;
}


//接收一个字节数据 一个字节八位
u8  OLED_Iic_Recv_Byte(void)
{
	
	u8 i, data = 0;  //0000 0000
	
	//输入模式
	OLED_Iic_Sda_Mode(GPIO_Mode_IN);
	
	//形成脉冲周期
	OLED_SCL = 0;

	for(i=0; i<8; i++)
	{
		delay_us(5);
		OLED_SCL = 1;
		delay_us(5);
	
		//高电平接收数据,数据根据引脚电平来决定
		if(OLED_SDA_IN == 1)
		{
			data |= (1<<(7-i));  //收到为1时,将对应的位置1即可
		}

		
		OLED_SCL = 0;
	
	}
	
	
	return data;
}

void  OLED_I2C_WriteByte(uint8_t addr,uint8_t data)
{
	
	//启动信号
	OLED_Iic_Start();

	//发送设备地址(一个字节)
	OLED_Iic_Send_Byte(OLED_ADDRESS);//器件地址 -- 默认0x78
	//等待应答
	while(OLED_Iic_Recv_Ack());
	//发送寄存器地址(一个字节)
	OLED_Iic_Send_Byte(addr);;//寄存器地址
	//等待应答
	while(OLED_Iic_Recv_Ack());
	//发送数据(一个字节)
	OLED_Iic_Send_Byte(data);//发送数据
	//等待应答
	 while(OLED_Iic_Recv_Ack());
	
	OLED_Iic_Stop();//关闭I2C1总线
	
	
	
}

void OLED_WriteCommand(unsigned char I2C_Command)//写命令
{
	OLED_I2C_WriteByte(0x00, I2C_Command);
}

void OLED_WriteData(unsigned char I2C_Data)//写数据
{
	OLED_I2C_WriteByte(0x40, I2C_Data);
}

/**
  * @brief  OLED设置光标位置
  * @param  Y 以左上角为原点,向下方向的坐标,范围:0~7
  * @param  X 以左上角为原点,向右方向的坐标,范围:0~127
  * @retval 无
  */
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
	OLED_WriteCommand(0xB0 | Y);					//设置Y位置
	OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4));	//设置X位置高4位
	OLED_WriteCommand(0x00 | (X & 0x0F));			//设置X位置低4位
}

/**
  * @brief  OLED清屏
  * @param  无
  * @retval 无
  */
void OLED_Clear(void)
{  
	uint8_t i, j;
	for (j = 0; j < 8; j++)
	{
		OLED_SetCursor(j, 0);
		for(i = 0; i < 128; i++)
		{
			OLED_WriteData(0x00);
		}
	}
}

/**
  * @brief  OLED显示一个字符
  * @param  Line 行位置,范围:1~4
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的一个字符,范围:ASCII可见字符
  * @retval 无
  */
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{      	
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]);		//显示下半部分内容
	}
}

/**
  * @brief  OLED显示字符串
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串,范围:ASCII可见字符
  * @retval 无
  */
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i++)
	{
		OLED_ShowChar(Line, Column + i, String[i]);
	}
}

/**
  * @brief  OLED次方函数
  * @retval 返回值等于X的Y次方
  */
uint32_t OLED_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y--)
	{
		Result *= X;
	}
	return Result;
}

/**
  * @brief  OLED显示数字(十进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~4294967295
  * @param  Length 要显示数字的长度,范围:1~10
  * @retval 无
  */
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

/**
  * @brief  OLED显示数字(十进制,带符号数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-2147483648~2147483647
  * @param  Length 要显示数字的长度,范围:1~10
  * @retval 无
  */
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
{
	uint8_t i;
	uint32_t Number1;
	if (Number >= 0)
	{
		OLED_ShowChar(Line, Column, '+');
		Number1 = Number;
	}
	else
	{
		OLED_ShowChar(Line, Column, '-');
		Number1 = -Number;
	}
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

/**
  * @brief  OLED显示数字(十六进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFFFFFF
  * @param  Length 要显示数字的长度,范围:1~8
  * @retval 无
  */
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i, SingleNumber;
	for (i = 0; i < Length; i++)							
	{
		SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;
		if (SingleNumber < 10)
		{
			OLED_ShowChar(Line, Column + i, SingleNumber + '0');
		}
		else
		{
			OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');
		}
	}
}

/**
  * @brief  OLED显示数字(二进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');
	}
}

/**
  * @brief  OLED初始化
  * @param  无
  * @retval 无
  */
void OLED_Init(void)
{
	delay_ms(100); //这里的延时很重要
	
	OLED_WriteCommand(0xAE); //display off
	OLED_WriteCommand(0x20);	//Set Memory Addressing Mode	
	OLED_WriteCommand(0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	OLED_WriteCommand(0xb0);	//Set Page Start Address for Page Addressing Mode,0-7
	OLED_WriteCommand(0xc8);	//Set COM Output Scan Direction
	OLED_WriteCommand(0x00); //---set low column address
	OLED_WriteCommand(0x10); //---set high column address
	OLED_WriteCommand(0x40); //--set start line address
	OLED_WriteCommand(0x81); //--set contrast control register
	OLED_WriteCommand(0xff); //亮度调节 0x00~0xff
	OLED_WriteCommand(0xa1); //--set segment re-map 0 to 127
	OLED_WriteCommand(0xa6); //--set normal display
	OLED_WriteCommand(0xa8); //--set multiplex ratio(1 to 64)
	OLED_WriteCommand(0x3F); //
	OLED_WriteCommand(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	OLED_WriteCommand(0xd3); //-set display offset
	OLED_WriteCommand(0x00); //-not offset
	OLED_WriteCommand(0xd5); //--set display clock divide ratio/oscillator frequency
	OLED_WriteCommand(0xf0); //--set divide ratio
	OLED_WriteCommand(0xd9); //--set pre-charge period
	OLED_WriteCommand(0x22); //
	OLED_WriteCommand(0xda); //--set com pins hardware configuration
	OLED_WriteCommand(0x12);
	OLED_WriteCommand(0xdb); //--set vcomh
	OLED_WriteCommand(0x20); //0x20,0.77xVcc
	OLED_WriteCommand(0x8d); //--set DC-DC enable
	OLED_WriteCommand(0x14); //
	OLED_WriteCommand(0xaf); //--turn on oled panel
		
	OLED_Clear();				//OLED清屏
}

4.7 OLED.h

#ifndef __OLED_I2C_H
#define	__OLED_I2C_H

#include "stm32f4xx.h"
#include "sys.h"
#define OLED_ADDRESS	0x78 //通过调整0R电阻,屏可以0x78和0x7A两个地址 -- 默认0x78

#define OLED_SCL   		PEout(5)
#define OLED_SDA_OUT   	PEout(6)
#define OLED_SDA_IN   	PEin(6)

void OLED_Iic_Init(void);
void  OLED_Iic_Sda_Mode(GPIOMode_TypeDef GPIO_Mode);
void  OLED_Iic_Start(void);
void  OLED_Iic_Stop(void);
void  OLED_Iic_Send_Ack(u8 ack);
void  OLED_Iic_Send_Byte(u8 data);
u8  OLED_Iic_Recv_Ack(void);
u8  OLED_Iic_Recv_Byte(void);
void  OLED_I2C_WriteByte(uint8_t addr,uint8_t data);
	
void I2C_WriteByte(uint8_t addr,uint8_t data);
void OLED_WriteCommand(unsigned char I2C_Command);
void OLED_WriteData(unsigned char I2C_Data);

void OLED_Init(void);
void OLED_SetCursor(uint8_t Y, uint8_t X);
void OLED_Clear(void);
uint32_t OLED_Pow(uint32_t X, uint32_t Y);
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char);
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String);
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length);
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);

#endif

4.8 OLED_Font.h

/************************************************************************************
* 
* Description:
* 1. 128*64点整OLED模块功能演示程序的字表,仅适用heltec.taobao.com所售产品;
* 2. 字表由打包资料中的“取字软件”计算得出;
* 3. 取字方式 -- 共阴、列行式、逆向输出
*
* Others: none;
*
* Function List: none;
*
* History: none;
*
*************************************************************************************/

/***************************16*16的点阵字体取模方式:共阴——列行式——逆向输出*********/
unsigned char F16x16[] =
{
	// 年(0) 月(1) 日(2) 星(3) 期(4) 一(5) 二(6) 三(7) 四(8) 五(9) 六(10) 日(11)

	0x00,0x20,0x18,0xC7,0x44,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0x04,0x00,0x00,
	0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00,/*"年",0*/

	0x00,0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0xFE,0x00,0x00,0x00,
	0x80,0x40,0x30,0x0F,0x02,0x02,0x02,0x02,0x02,0x02,0x42,0x82,0x7F,0x00,0x00,0x00,/*"月",1*/

	0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x00,0x00,0x00,0x00,/*"日",2*/

	0x00,0x00,0x00,0xBE,0x2A,0x2A,0x2A,0xEA,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,0x00,
	0x00,0x44,0x42,0x49,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x41,0x40,0x00,0x00,/*"星",3*/

	0x00,0x04,0xFF,0x24,0x24,0x24,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00,
	0x88,0x48,0x2F,0x09,0x09,0x19,0xAF,0x48,0x30,0x0F,0x02,0x42,0x82,0x7F,0x00,0x00,/*"期",4*/

	0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"一",5*/

	0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,
	0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,/*"二",6*/

	0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x00,0x00,
	0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,/*"三",7*/

	0x00,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,
	0x00,0x7F,0x28,0x24,0x23,0x20,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x7F,0x00,0x00,/*"四",8*/

	0x00,0x02,0x42,0x42,0x42,0xC2,0x7E,0x42,0x42,0x42,0x42,0xC2,0x02,0x02,0x00,0x00,
	0x40,0x40,0x40,0x40,0x78,0x47,0x40,0x40,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x00,/*"五",9*/

	0x20,0x20,0x20,0x20,0x20,0x20,0x21,0x22,0x2C,0x20,0x20,0x20,0x20,0x20,0x20,0x00,
	0x00,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x01,0x02,0x04,0x18,0x60,0x00,0x00,/*"六",10*/
	
	0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x00,0x00,0x00,0x00,/*"日",11*/
	
	0x40,0x40,0x42,0xCC,0x00,0x40,0xA0,0x9E,0x82,0x82,0x82,0x9E,0xA0,0x20,0x20,0x00,
	0x00,0x00,0x00,0x3F,0x90,0x88,0x40,0x43,0x2C,0x10,0x28,0x46,0x41,0x80,0x80,0x00,/*"设",12*/

	0x00,0x17,0x15,0xD5,0x55,0x57,0x55,0x7D,0x55,0x57,0x55,0xD5,0x15,0x17,0x00,0x00,
	0x40,0x40,0x40,0x7F,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7F,0x40,0x40,0x40,0x00,/*"置",13*/

	0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,
	0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x01,0x06,0x40,0x80,0x7F,0x00,0x00,0x00,/*"时",14*/

	0x00,0xF8,0x01,0x06,0x00,0xF0,0x12,0x12,0x12,0xF2,0x02,0x02,0x02,0xFE,0x00,0x00,
	0x00,0xFF,0x00,0x00,0x00,0x1F,0x11,0x11,0x11,0x1F,0x00,0x40,0x80,0x7F,0x00,0x00,/*"间",15*/
	
	0x00,0xF8,0x01,0x22,0x20,0x22,0x2A,0xF2,0x22,0x22,0x22,0x22,0x02,0xFE,0x00,0x00,
	0x00,0xFF,0x00,0x00,0x1F,0x01,0x01,0x7F,0x09,0x11,0x0F,0x40,0x80,0x7F,0x00,0x00,/*"闹",16*/

	0x20,0x10,0x2C,0xE7,0x24,0x24,0x00,0xF0,0x10,0x10,0xFF,0x10,0x10,0xF0,0x00,0x00,
	0x01,0x01,0x01,0x7F,0x21,0x11,0x00,0x07,0x02,0x02,0xFF,0x02,0x02,0x07,0x00,0x00,/*"钟",17*/
	
	0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0xFF,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00,
	0x80,0x90,0x88,0x46,0x40,0x40,0x20,0x2F,0x10,0x10,0x08,0x04,0x02,0x00,0x00,0x00,/*"步",18*/

	0x90,0x52,0x34,0x10,0xFF,0x10,0x34,0x52,0x80,0x70,0x8F,0x08,0x08,0xF8,0x08,0x00,
	0x82,0x9A,0x56,0x63,0x22,0x52,0x8E,0x00,0x80,0x40,0x33,0x0C,0x33,0x40,0x80,0x00,/*"数",19*/

	0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
	0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"温",20*/

	0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
	0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度",21*/

	0x10,0x60,0x02,0x8C,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
	0x04,0x04,0x7E,0x01,0x44,0x48,0x50,0x7F,0x40,0x40,0x7F,0x50,0x48,0x44,0x40,0x00,/*"湿",22*/

	0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
	0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度",23*/


};

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

unsigned char BMP1[] =
{
	0x00,0x03,0x05,0x09,0x11,0xFF,0x11,0x89,0x05,0xC3,0x00,0xE0,0x00,0xF0,0x00,0xF8,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x28,0xFF,0x11,0xAA,0x44,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x01,0x38,0x44,0x82,0x92,
	0x92,0x74,0x01,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x44,0xC7,0x01,0x7D,
	0x7D,0x7D,0x7D,0x01,0x7D,0x7D,0x7D,0x7D,0x01,0x7D,0x7D,0x7D,0x7D,0x01,0xFF,0x00,
	0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,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,0x00,0x00,0x00,0x00,
	0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,
	0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x00,0x00,
	0x6D,0x6D,0x6D,0x6D,0x6D,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x40,0x40,
	0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0xDB,0xDB,0xDB,0xDB,0x00,0x00,
	0xDB,0xDB,0xDB,0xDB,0xDB,0x00,0x00,0xDB,0xDB,0xDB,0xDB,0xDB,0x00,0x00,0xDB,0xDB,
	0xDB,0xDB,0xDB,0x00,0x00,0xDA,0xDA,0xDA,0xDA,0xDA,0x00,0x00,0xD8,0xD8,0xD8,0xD8,
	0xD8,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,
	0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x80,
	0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x00,0x00,
	0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x06,0x06,
	0x06,0x06,0x06,0x00,0x00,0x06,0x06,0x06,0xE6,0x66,0x20,0x00,0x06,0x06,0x86,0x06,
	0x06,0x00,0x00,0x06,0x06,0x06,0x06,0x86,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x00,
	0x00,0x86,0x86,0x86,0x86,0x86,0x80,0x80,0x86,0x86,0x06,0x86,0x86,0xC0,0xC0,0x86,
	0x86,0x86,0x06,0x06,0xD0,0x30,0x76,0x06,0x06,0x06,0x06,0x00,0x00,0x06,0x06,0x06,
	0x06,0x06,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x06,0x06,0x06,0x06,0x06,
	0x00,0x00,0x06,0x06,0x06,0x06,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,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x1C,0x00,0xFE,0x00,0x01,
	0x02,0x00,0xC4,0x18,0x20,0x02,0x9E,0x63,0xB2,0x0E,0x00,0xFF,0x81,0x81,0xFF,0x00,
	0x00,0x80,0x40,0x30,0x0F,0x00,0x00,0x00,0x00,0xFF,0x00,0x23,0xEA,0xAA,0xBF,0xAA,
	0xEA,0x03,0x3F,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x0C,0x08,0x00,0x00,0x01,0x01,0x01,
	0x01,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x81,0x80,0x80,0x81,0x80,
	0x81,0x80,0x80,0x80,0x80,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
	0x01,0x00,0x01,0x01,0x09,0x0C,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
	0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,
	0x00,0x1E,0x21,0x40,0x40,0x50,0x21,0x5E,0x00,0x1E,0x21,0x40,0x40,0x50,0x21,0x5E,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xC1,0xC1,0xFF,
	0xFF,0xC1,0xC1,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0xFC,0xF3,0xEF,0xF3,0xFC,
	0x80,0xFF,0x80,0xEE,0xEE,0xEE,0xF5,0xFB,0xFF,0x9C,0xBE,0xB6,0xB6,0x88,0xFF,0x00,/*"D:\DreamSpark\OLED\MP3_UI.bmp",0*/
};

/*OLED字模库,宽8像素,高16像素*/
const uint8_t OLED_F8x16[][16]=
{
	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
};

5. 实验结果

        可以发现:OLED屏上显示厂商ID和设备ID;并且分为在第二行和第三行显示了写入的十六进制数 0x01、0x02、0x03、0x04 和读出的十六进制数 0x01、0x02、0x03、0x04;整个实验思路很清晰,就是往Flash芯片写入数据,紧接着再读出数据;写入的数据和读出的数据相同则表示实验成功,Flash芯片是掉电不丢失的;

        本来以为软件模拟SPI还是比较简单的,但是搜集资料 (理解+整理) 写这篇博客也BUSY了一下午的时间!!!(感悟:看起来简单的事自己做起来不一定简单,希望看到这里的读者也能够静下心来去做每一件简单的事,不仅仅是做一个单片机的小实验,任何事都是!)

        这篇博客是建立在硬件驱动SPI的基础上的进行扩充的,如有关于SPI的疑问,请移至本博客开头的SPI协议详解!

        在正点的F4例程中是没有软件模拟SPI的,希望上述内容可以对读者有所帮助。以上的程序每一步都做了详解的备注,如何任何问题,欢迎留言交流!!!

  • 9
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32中,可以通过软件模拟实现SPI通信。SPI(Serial Peripheral Interface)是一种串行通信协议,它通常用于连接微控制器与外部设备,如传感器、存储器等。 以下是一个简单的示例代码,演示了如何在STM32上使用软件模拟SPI: ```c #include "stm32f4xx.h" #define SPI_CLK_PIN GPIO_Pin_5 #define SPI_MISO_PIN GPIO_Pin_6 #define SPI_MOSI_PIN GPIO_Pin_7 // 初始化SPI引脚 void SPI_GPIO_Init(void) { GPIO_InitTypeDef gpioInitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); gpioInitStruct.GPIO_Pin = SPI_CLK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN; gpioInitStruct.GPIO_Mode = GPIO_Mode_OUT; gpioInitStruct.GPIO_OType = GPIO_OType_PP; gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpioInitStruct); } // 发送一个字节数据 void SPI_SendByte(uint8_t byte) { int8_t i; for (i = 7; i >= 0; i--) { GPIO_ResetBits(GPIOA, SPI_CLK_PIN); if ((byte >> i) & 0x01) { GPIO_SetBits(GPIOA, SPI_MOSI_PIN); } else { GPIO_ResetBits(GPIOA, SPI_MOSI_PIN); } GPIO_SetBits(GPIOA, SPI_CLK_PIN); } } // 接收一个字节数据 uint8_t SPI_ReceiveByte(void) { int8_t i; uint8_t byte = 0; for (i = 7; i >= 0; i--) { GPIO_ResetBits(GPIOA, SPI_CLK_PIN); if (GPIO_ReadInputDataBit(GPIOA, SPI_MISO_PIN)) { byte |= (1 << i); } GPIO_SetBits(GPIOA, SPI_CLK_PIN); } return byte; } int main(void) { // 初始化SPI引脚 SPI_GPIO_Init(); // 发送一个字节 SPI_SendByte(0x55); // 接收一个字节 uint8_t receivedByte = SPI_ReceiveByte(); while (1) { // 主循环 } } ``` 上面的代码中,首先定义了SPI通信所使用的引脚(SCK、MISO和MOSI),然后实现了初始化SPI引脚的函数`SPI_GPIO_Init()`,以及发送和接收一个字节数据的函数`SPI_SendByte()`和`SPI_ReceiveByte()`。 在`SPI_SendByte()`函数中,通过循环逐位发送字节数据。在每个时钟周期中,首先将SCK引脚拉低,然后根据字节数据相应位的值,将MOSI引脚设置为高电平或低电平,最后将SCK引脚拉高,完成一次数据传输。 在`SPI_ReceiveByte()`函数中,通过循环逐位接收字节数据。在每个时钟周期中,首先将SCK引脚拉低,然后读取MISO引脚的电平值,如果为高电平,则将相应位的值设置为1,最后将SCK引脚拉高,完成一次数据接收。 在主函数中,可以调用`SPI_SendByte()`和`SPI_ReceiveByte()`函数来实现SPI通信。 需要注意的是,由于软件模拟SPI需要通过GPIO模拟SPI通信的时钟和数据线,因此通信速度可能较慢。如果需要更高的通信速度,建议使用硬件SPI

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值