STM32驱动0.96寸OLED液晶屏(12864液晶屏)

  1  序言

  在利用单片机是设计产品的过程中常常需要利用一些数据显示设备来显示一些关键信息,常用的做法是利用串口将数据传送到计算机上显示,或者是利用蓝牙模块将数据送到移动终端上显示,那么还有一种方法,就是将数据直接显示在一块小的液晶屏幕上,这种方式也是十分的方便快捷的。那么如何要在我们打单片机系统上添加一块液晶显示屏到底该怎么做呢?我相信这也是许多在网上搜OLED液晶显示屏驱动程序的小伙伴们最为关心的问题。本片文章将以STM32F103单片机为例,讲解如何在单片机系统上面加一块液晶显示屏,并且使其能够显示我们想要的数据,文字符号或者图片信息等。

  2  如何利用STM32单片机驱动12864液晶屏

  STM32单片机是目前市面上使用最为广泛的单片机,该单片机型号众多,每种型号适用于不同的工作要求,大致可分为F0、F1、F4、F7等系列。那么我所使用的单片机型号为STM32F103RC,其他型号的液晶屏驱动程序也是类似的,差异并不是非常大,而所使用的液晶屏幕为市面上常见的0.96寸OLED液晶屏幕(也叫12864液晶屏),都是淘宝上买的,价格也就几十块钱。如图2-1所示。

STM32驱动0.96寸OLED液晶屏(12864液晶屏)_第1张图片

 Fig. 1:0.96寸OLED液晶显示屏及STM32F103RC单片机做小系统外观图 

  2.1  0.96寸OLED端口含义

  说道硬件的引脚连接,这个问题似乎也没多大难度,但是很多刚开始接触这一块知识的小伙伴在网上搜了好多资料之后就纳闷了,例如:网上的所提到的SCL,SDA引脚是啥啊?我这液晶屏上面怎么没有啊?或者是这个程序里面的DIN,CLK是指的那个端口啊?我这硬件上也没有啊。图2.1-1显示了市面上两种常见的OLED液晶显示屏的端口标号。

STM32驱动0.96寸OLED液晶屏(12864液晶屏)_第2张图片

 Fig. 2.1-1:两种常见的液晶显示屏端口标号

  两种液晶片的引脚数不一样,左边的有7个引脚,而右边的只有6个。其次,端口的标号也不完全一样,第一个分别标为GND,VCC,D0,D1,RES,DC和CS第二个分别标为GND,VCC,SCL,SDA,RST,D/C。除了GND和VCC小伙伴们也许已经猜到了,其他的引脚是什么含义,有什么用应该也不是非常的清楚。

  先讲解右边的,右边的端口标号是最为直观的:

    GND --- 接地端口

    VCC --- 接3.3V电源端口

    SCL --- CLK时钟信号端口

    SDA --- MOSI数据端口

    RST --- 复位端口

    D/C --- 数据/命令选择引脚

  弄懂了每个引脚的含义,其实左边的标号不一样,只要知道它最本质的含义,也对我们编写程序产生不了多大影响。左边的端口号的含义分别为:

    GND --- 接地端口

    VCC --- 接3.3V电源端口

    D0 --- CLK时钟信号(等同于上面的SCL)

    D1 --- 数据端口(等同于上面的SDA)

    RES --- 复位端口(等同于上面的RST)

    DC --- 数据/命令选择引脚(等同于上面的D/C)

    CS --- 片选引脚(低电平有效,也就是所需要接低电平,我实际试验过不接该引脚也是可以正常使用的)

  其实弄清楚含义之后左边的只是比右边的多了一个CS片选引脚,而这个引脚也是无关紧要的,所以说其实本质上两者是一样的。

  2.2  0.96寸OLED液晶屏引脚与单片机系统引脚的硬件连接

  具体说来怎么连接,我所理解的在STM32中含有CLK时钟信号有两个一个是IIC,另一个是SPI,两种通讯方式都有时钟信号,但是这里的时钟信号端口是不是必须接IIC和SPI的CLK端口呢?经过我的测试所得到的答案是否定的,并不需要刻意将OLED液晶屏端口的CLK端口和数据端口接IIC的时钟及数据引脚或者是SPI的时钟及数据引脚。

  我的连接方式为:

    GND --- GND

    VCC --- VCC

    D0(SCL) --- PC0

    D1(SDA) --- PC1

    RES(RST) --- PC2

    DC(D/C) --- PC3

    CS --- 悬空 

  连接实物图如图2.2-1所示

  

 Fig. 2.2-1:STM32与0.96寸OLED实物连接图

  2.3  0.96寸OLED液晶屏驱动程序

  OLED驱动C文件程序如下:

#include "oled.h"       
#include "oledfont.h" 

//#include "bmp.h"
    
#if OLED_MODE==1
/**
  * @brief 向SSD1106写入一个字节
    * @param dat:要写入的数据/命令  cmd:数据/命令标志 0,表示命令;1,表示数据
    * @retval None
  */
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{
    DATAOUT(dat);        
    if(cmd)
      OLED_DC_Set();
    else 
        OLED_DC_Clr();           
    OLED_CS_Clr();
    OLED_WR_Clr();     
    OLED_WR_Set();
    OLED_CS_Set();      
    OLED_DC_Set();     
}                 
#else

/**
  * @brief 向SSD1106写入一个字节
    * @param dat:要写入的数据/命令 cmd:数据/命令标志 0,表示命令;1,表示数据;
    * @retval None
  */
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{    
    uint8_t i;              
    if(cmd)
      OLED_DC_Set();
    else 
      OLED_DC_Clr();          
    //OLED_CS_Clr();
    for(i=0;i<8;i++)
    {              
        OLED_SCLK_Clr();
        if(dat&0x80)
           OLED_SDIN_Set();
        else 
           OLED_SDIN_Clr();
        OLED_SCLK_Set();
        dat<<=1;   
    }                           
    //OLED_CS_Set();
    OLED_DC_Set();         
} 
#endif

/**
  * @brief 清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样
    * @param None
    * @retval None
  */
void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
    OLED_WR_Byte(0xb0+y,OLED_CMD);
    OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
    OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD); 
}   

/**
  * @brief 开启OLED显示
    * @param None
    * @retval None
  */ 
void OLED_Display_On(void)
{
    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
    OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}

/**
  * @brief 关闭OLED显示    
    * @param None
    * @retval None
  */   
void OLED_Display_Off(void)
{
    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
    OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}        

/**
  * @brief 清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样
    * @param None
    * @retval None
  */
void OLED_Clear(void)  
{  
    uint8_t i,n;            
    for(i=0;i<8;i++)  
    {  
        OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
        OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
        OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
        for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); 
    }                                                                         //更新显示
}

/**
  * @brief 在指定位置显示一个字符,包括部分字符
    * @param x:0~127   y:0~63   mode:0,反白显示  1,正常显示     size:选择字体 16/12 
    * @retval None
  */
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr)
{          
    unsigned char c=0,i=0;    
    c=chr-' ';                                                        //得到偏移后的值            
    if(x>Max_Column-1)
    {
        x=0;
        y=y+2;
    }
    if(SIZE==16)
    {
        OLED_Set_Pos(x,y);    
        for(i=0;i<8;i++)
        OLED_WR_Byte(D8X16[c*16+i],OLED_DATA);
        OLED_Set_Pos(x,y+1);
        for(i=0;i<8;i++)
        OLED_WR_Byte(D8X16[c*16+i+8],OLED_DATA);
    }
    else 
    {    
        OLED_Set_Pos(x,y+1);
        for(i=0;i<6;i++)
        {
            OLED_WR_Byte(D6X8[c][i],OLED_DATA);
        }
    }
}

/**
  * @brief m^n函数
    * @param None
    * @retval None
  */
uint32_t oled_pow(uint8_t m,uint8_t n)
{
    uint32_t result=1;     
    while(n--)result*=m;    
    return result;
}        

/**
  * @brief 显示2个数字
    * @param x,y :起点坐标
    *                 len :数字的位数,即显示几位有效数字
  *                 size:字体大小
  *                 mode:模式    0,填充模式;1,叠加模式
  *        num:数值(0~4294967295);
    * @retval None
  */           
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size)
{             
    uint8_t t,temp;
    uint8_t enshow=0;                           
    for(t=0;t)
    {
        temp=(num/oled_pow(10,len-t-1))%10;
        if(enshow==0&&t<(len-1))
        {
            if(temp==0)
            {
                OLED_ShowChar(x+(size/2)*t,y,' ');
                continue;
            }else enshow=1; 
              
        }
         OLED_ShowChar(x+(size/2)*t,y,temp+'0'); 
    }
} 

/**
  * @brief 显示一个字符号串
    * @param 
    * @retval None
  */
void OLED_ShowString(uint8_t x,uint8_t y,char *chr)
{
    unsigned char j=0;
    while(chr[j]!='\0')
    {        OLED_ShowChar(x,y,chr[j]);
            x+=8;
        if(x>120){x=0;y+=2;}
            j++;
    }
}

/**
  * @brief 显示汉字
    * @param 
    * @retval None
  */
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
{                      
    uint8_t t,adder=0;
    OLED_Set_Pos(x,y);    
    for(t=0;t<32;t++)
        {
                OLED_WR_Byte(SHOW[2*no][t],OLED_DATA);
                adder+=1;
     }    
        OLED_Set_Pos(x,y+1);    
    for(t=0;t<32;t++)
            {    
                OLED_WR_Byte(SHOW[2*no+1][t],OLED_DATA);
                adder+=1;
      }                    
}

/**
  * @brief 显示显示BMP图片
    * @param 显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7
    * @retval None
  */
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{     
 unsigned int j=0;
 unsigned char x,y;
  
  if(y1%8==0) y=y1/8;      
  else y=y1/8+1;
    for(y=y0;y)
    {
        OLED_Set_Pos(x0,y);
    for(x=x0;x)
        {      
            OLED_WR_Byte(BMP[j++],OLED_DATA);            
        }
    }
} 

/**
  * @brief 初始化SSD1306
    * @param None
    * @retval None
  */                    
void GPIO_OLED_InitConfig(void)
{     
    GPIO_InitTypeDef GPIO_OLEDInitStruct;                                                //定义一个GPIO口初始化结构体ledInitStruct
    RCC_APB2PeriphClockCmd(GPIO_OLED_CLK, ENABLE);                                            //GPIOB端口RCC时钟使能
    GPIO_OLEDInitStruct.GPIO_Pin = GPIO_OLED_SCLK_Pin | GPIO_OLED_PIN_Pin |
                                                                 GPIO_OLED_RES_Pin  | GPIO_OLED_DC_Pin;   //指定引脚为12和13
    GPIO_OLEDInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;                                                 //配置成输出模式
    GPIO_OLEDInitStruct.GPIO_Speed = GPIO_Speed_50MHz;                                   //传输速率配置成50HZ
    GPIO_Init(GPIOC, &GPIO_OLEDInitStruct);                                              //调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO     
     GPIO_SetBits(GPIOB, GPIO_OLED_SCLK_Pin|GPIO_OLED_PIN_Pin|GPIO_OLED_RES_Pin|GPIO_OLED_DC_Pin);

  OLED_RST_Set();
    Delay_ms(100);
    OLED_RST_Clr();
    Delay_ms(100);
    OLED_RST_Set(); 
                      
    OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
    OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
    OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
    OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
    OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
    OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
    OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
    OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
    OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
    OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
    OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
    OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset    Shift Mapping RAM Counter (0x00~0x3F)
    OLED_WR_Byte(0x00,OLED_CMD);//-not offset
    OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
    OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
    OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
    OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
    OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
    OLED_WR_Byte(0x12,OLED_CMD);
    OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
    OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
    OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
    OLED_WR_Byte(0x02,OLED_CMD);//
    OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
    OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
    OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
    OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) 
    OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
    
    OLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ 
    OLED_Clear();
    OLED_Set_Pos(0,0);     
}  

  上面程序是0.96寸OLED基于STM32单片机的主要驱动程序,完整程序可到我自己搭建的论坛网站下载,需要先注册一个论坛账户,然后就可以下载使用了。需要下载请点击链接

  上述代码只是一个驱动程序中的一部分代码,需要先初始化系统时钟,其次初始化调用OLED初始化函数,程序方可正常运行。

  备注:如果论坛网站链接无法打开,可能是实验室停电或者服务器关机或者花生壳机房故障所致,请联系我QQ:1771453853。

  3  实验结果

  我们利用液晶屏幕可显示数据,字符以及各种图片信息。

  3.1  利用液晶屏显示字符串数据信息

  首先,先来介绍显示字符串数据信息,因为这种信息显示是最为方便的。我们直接调用OLED_ShowString(uint8_t x,uint8_t y,char *chr)函数即可。

  参考主程序代码如下

#include "stm32f10x.h"
#include "oled.h"
#include "bsp_systick.h"

int main(void)
{
    char Buffer[15] = "Hello, World!";
    Systick_InitConfig();
    GPIO_OLED_InitConfig();
    OLED_Clear();
    OLED_ShowString(20, 2, Buffer);
    while(1);
}

  这个函数主要用于显示字符串数据,效果如图3.1-1所示。

 Fig.3.1-2  液晶屏显示字符串数据信息

  3.2  利用液晶屏显示数据信息

  我们的数据一般分为两种,一种是整型数据,一种是浮点型数据。整型数据好显示,我们可以用上述代码里面的OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size)函数。

  例如:我们在主函数中写下如下代码:

#include "stm32f10x.h"
#include "oled.h"
#include "bsp_systick.h"

int main(void)
{
    int Num = 125;
    float Data = 12.50;
    Systick_InitConfig();
    GPIO_OLED_InitConfig();
    OLED_Clear();
    OLED_ShowNum(20, 2, Num, 8, 16);
    OLED_ShowNum(20, 4, Data, 8, 16);
    while(1);
}    

  观察屏幕中的数据,如下所示:

STM32驱动0.96寸OLED液晶屏(12864液晶屏)_第3张图片

 Fig. 3.2-1液晶屏显示数据信息

  可以发现,整型数据被很好的显示出来,而浮点型数据则显示有误,12.5只保留了整数部分。怎么解决这个问题?

  我们可以用sprintf()函数将浮点数据转化为字符串数据进行显示,代码如下所示:

#include "stm32f10x.h"
#include "oled.h"
#include "bsp_systick.h"

int main(void)
{
    float Data = 12.50;
    char Buffer[5];
    sprintf(Buffer, "%0.2f", Data);    
    Systick_InitConfig();
    GPIO_OLED_InitConfig();
    OLED_Clear();
    OLED_ShowString(20, 2, Buffer);
    while(1);
}

  这样就很好地解决了浮点型数据的显示问题,我个人觉得这个方法非常的重要,也非常的实用,毕竟我们生活中传感器采集到的数据大多数都是浮点型数据。

  效果如图3.2-2所示。

 Fig. 3.2-2 浮点型数据转化为字符串数据显示

  大家在做传感器数据显示的时候也可以尝试用这种方法,非常的方便。

  3.3  利用液晶屏显示中文信息

  显示中文信息需要用到字模工具,下载可到本人搭建的论坛下载: --> PCtoLCD论坛下载

  也可以从百度云盘下载: --> PCtoLCD百度网盘下载 若需要提取码,则提取码为:lyhc

  字模软件的配置与使用方式如图

STM32驱动0.96寸OLED液晶屏(12864液晶屏)_第4张图片

 Fig. 3.3-1  字模软件PCtoLCD2002配置与使用方法

 

   将生成的代码复制到字模文件oledfont.h中,我们在oledfont.h文件中新建一个函数,将该代码复制到该文件中。

char SHOW[][32]={
    {0x20,0x24,0x24,0x24,0xFE,0x23,0x22,0x20,0x20,0xFF,0x20,0x22,0x2C,0xA0,0x20,0x00},
    {0x00,0x08,0x48,0x84,0x7F,0x02,0x41,0x40,0x20,0x13,0x0C,0x14,0x22,0x41,0xF8,0x00},/*"我",0*/
    {0x80,0x64,0x2C,0x34,0x24,0x24,0xEC,0x32,0x22,0x22,0x32,0x2E,0x23,0xA2,0x60,0x00},
    {0x00,0x41,0x21,0x91,0x89,0x87,0x4D,0x55,0x25,0x25,0x55,0x4D,0x81,0x80,0x80,0x00},/*"爱",1*/
    {0x00,0x80,0x60,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00},
    {0x01,0x00,0x00,0xFF,0x00,0x10,0x0C,0x03,0x40,0x80,0x7F,0x00,0x01,0x06,0x18,0x00},/*"你",2*/
    {0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0xF0,0x00,0x00,0x00},
    {0x00,0x00,0x0F,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x0F,0x00,0x00,0x00},/*"中",3*/
    {0x00,0xFE,0x02,0x12,0x92,0x92,0x92,0xF2,0x92,0x92,0x92,0x12,0x02,0xFE,0x00,0x00},
    {0x00,0xFF,0x40,0x48,0x48,0x48,0x48,0x4F,0x48,0x4A,0x4C,0x48,0x40,0xFF,0x00,0x00},/*"国",4*/
    {0x00,0x00,0xFF,0x05,0x05,0xF5,0x55,0x5D,0x55,0x55,0x55,0x55,0xF5,0x05,0x01,0x00},
    {0x40,0x30,0x0F,0x80,0xA0,0x97,0xBD,0x55,0x55,0x55,0x55,0x55,0xB7,0x80,0x80,0x00},/*"厦",5*/
    {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00},
    {0x80,0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x03,0x0C,0x10,0x20,0x40,0x80,0x80,0x00},/*"大",6*/
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    {0x00,0x00,0x58,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",7*/
};

  接下来,我们需要在主程序里通过调用OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)函数来实现中文字符的显示。

#include "stm32f10x.h"
#include "oled.h"
#include "bsp_systick.h"

int main(void)
{
    Systick_InitConfig();
    GPIO_OLED_InitConfig();
    OLED_Clear();
   /* (x, y, 汉字序号) */ OLED_ShowCHinese(
10, 2, 0); OLED_ShowCHinese(24, 2, 1); OLED_ShowCHinese(38, 2, 2); OLED_ShowCHinese(52, 2, 7); OLED_ShowCHinese(66, 2, 3); OLED_ShowCHinese(80, 2, 4); OLED_ShowCHinese(10, 5, 0); OLED_ShowCHinese(24, 5, 1); OLED_ShowCHinese(38, 5, 2); OLED_ShowCHinese(52, 5, 7); OLED_ShowCHinese(66, 5, 5); OLED_ShowCHinese(80, 5, 6); while(1); }

  显示结果如下图所示

 Fig. 3.3-2 OLED液晶显示中文字符

   3.4  利用液晶屏幕显示图片信息

  图片信息的显示其实并不麻烦,而获取图片代码的过程稍稍有些许麻烦。

  先以图3.4-1为例,将其利用PCtoLCD的图像转换功能转换为代码。

 STM32驱动0.96寸OLED液晶屏(12864液晶屏)_第5张图片

 Fig. 3.4-1:PCtoLCD图像转换实例文件

  在输入到软件之前需要通过图像处理软件调整图像分辨率并做二值化处理(就是将图像变成黑白色,分辨率调整为129x64)

  过程我就省略了,对此有需求或者有兴趣的小伙伴请在评论区留言。

  转换的代码放在bmp.h文件内,如下所示

#ifndef __BMP_H
#define __BMP_H
unsigned char BMP[] =
{
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,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,0xC0,0xE0,0xE0,0xF0,0xF8,
    0xF8,0xBC,0x1C,0x1C,0x0E,0x0E,0xFF,0xFF,0xFF,0xBF,0xBF,0xE7,0x63,0x63,0x43,0x43,
    0x63,0x63,0xFF,0x9F,0x9F,0xFF,0x3F,0x3F,0x0E,0x0E,0x1C,0x1C,0xBC,0xF8,0xF8,0xF0,
    0xE0,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,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0xF0,0xFE,0xFE,0xFF,0xE7,0xF3,0xF3,0xE7,0xCF,0xCF,0xF7,
    0x8D,0x8C,0x86,0x87,0xFD,0xFD,0xFE,0xFF,0xFF,0xFE,0xFA,0xFA,0xFA,0xFA,0xFA,0xFA,
    0xFE,0xFF,0xFF,0xFE,0xFD,0xFD,0x87,0x87,0x8F,0x8F,0xFF,0xC7,0xC7,0xE3,0xF1,0xF1,
    0xE7,0xFF,0xFE,0xFE,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x1F,0xFF,0xFF,0xFE,0xFC,0xFD,0xFD,0xFD,0xF7,0xF7,0x9E,0x6F,0xFF,
    0xFB,0x7F,0xFC,0xF4,0xFF,0xEE,0xE6,0xE7,0xEF,0xFF,0xFF,0xFF,0xFF,0xEF,0xE7,0xE6,
    0xEE,0xFF,0xF4,0xFC,0x7F,0xFB,0xFF,0x6F,0x9E,0xE7,0xE7,0xFD,0xFD,0xFD,0xFC,0xFE,
    0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x07,0x0F,0x1F,0x1F,0x3B,0x7F,0xFF,0x7F,0xFE,0xFE,0xFD,
    0xFF,0xFF,0x9B,0xFF,0xFC,0xFC,0xFC,0xE4,0xF4,0xF4,0x84,0x8C,0xFC,0xFC,0xFF,0xFB,
    0xFF,0xFF,0xFD,0xFE,0xFE,0x7F,0xFF,0x7F,0x3F,0x1F,0x1F,0x0F,0x07,0x07,0x01,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,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,0x00,0x01,0x03,
    0x03,0x03,0x03,0x03,0x03,0x07,0x07,0x07,0x07,0x03,0x03,0x03,0x03,0x03,0x03,0x01,
    0x00,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,0xD8,
    0xF8,0xFC,0xBC,0xBC,0xBC,0xBC,0xFC,0xDC,0xDE,0xDE,0xFE,0xFE,0xFE,0x7E,0x7E,0x6E,
    0x4C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xE0,0xE0,0xE0,0xC0,0xC0,
    0x40,0x60,0xE0,0xE0,0xE0,0xC0,0xC0,0xC0,0xC0,0xE0,0x20,0x20,0xF0,0xF0,0xF0,0xF0,
    0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x18,0xFC,0xFC,0xF8,0xF8,0xF8,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,
    0xFC,0xFE,0xFE,0xB6,0xE0,0xE0,0xFC,0xDC,0xFF,0xFF,0xBE,0xDE,0xD4,0xF6,0xFE,0xFE,
    0x7E,0x0C,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF8,0xFC,0xFF,0xFF,0x1F,
    0x1F,0x83,0xFD,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7E,0x36,0x36,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x37,0x1F,
    0x1F,0x1F,0x3F,0x00,0x00,0x07,0x1F,0x1F,0x1B,0x1B,0x1F,0x1F,0xFF,0xFF,0xFF,0xFF,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x1C,0x1C,0xBC,0xFC,0xFC,0xFC,
    0xFE,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xEF,0xE7,0xC7,0x87,0x0F,0x0F,0x06,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x3C,0x3C,0x38,0x1C,0x0E,0x0F,0x0F,0x1F,
    0x1F,0xBF,0xBF,0xBF,0xFF,0xFF,0xFF,0xDF,0x97,0xC6,0xC6,0xC7,0xCF,0xCF,0x9E,0x1E,
    0x1E,0x1E,0xC0,0xF0,0xF0,0xFC,0x7F,0x7F,0x3F,0x0F,0x0F,0x03,0x00,0x10,0x10,0x4D,
    0x6F,0x6F,0x37,0x3F,0x3F,0x1D,0x3D,0x3F,0x3F,0x7F,0xF2,0xF2,0xF0,0xE0,0xE0,0xE0,
    0x60,0x60,0x40,0x00,0x00,0x00,0x00,0x0F,0x0F,0x1F,0x0F,0x07,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x04,0x04,0x0C,0x1C,0x1C,0x1C,0x3F,0x3F,0x3F,0x1F,0x00,0x00,
    0x00,0x00,0x00,0x00,0x18,0x1C,0x1C,0x0E,0x0E,0x0E,0x07,0x07,0x03,0x03,0x01,0x00,
    0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x07,0x0F,0x1F,0x1F,0x3E,0x3E,0x3E,0x1C,0x18,
    0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0x33,0x33,0x73,
    0x71,0x71,0xF9,0x7F,0x7F,0x3F,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
};


#endif

  在主程序中需要调用OLED_DrawBMP();函数,主函数代码如下

#include "stm32f10x.h"
#include "oled.h"
#include "bsp_systick.h"
#include "bmp.h"

int main(void)
{
    Systick_InitConfig();
    GPIO_OLED_InitConfig();
    OLED_Clear();
    OLED_DrawBMP(0,0,126,8,BMP);
    
    while(1);
}

  显示结果如图3.4-2所示

 Fig. 3.4-1: 液晶屏图片显示实验

  至此,几个关于0.96寸OLED的STM32驱动显示实验就基本展示完毕了。

  4  总结

  1、OLED的液晶显示屏幕使我们做项目中起到一个数据显示的作用,可以显示数据,字符(各种阿拉伯字符,英文字符,汉字字符等等),图片等。

  2、在显示浮点型数据时采用sprintf();函数将浮点型数据转化为字符型数据能很好的解决浮点数数据的显示问题,如果小伙伴们有更好的办法,如能在评论区添加我联系方式告知的话,万分感激。

  3、市面上的0.96寸OLED液晶屏的引脚标号千奇百怪,但是它核心的引脚实际上就只有四个,分别是的数据、时钟、复位以及数据命令选择引脚。

  4、液晶屏的数据和时钟引脚无需刻意连接单片机的IIC或者SPI的数据时钟引脚。

  5、完整工程代码请到我的论坛中下载,下载需要先注册一个账户,然后就可以下载了,如果网站打不开,还请联系我QQ:1771453853,谢谢。完整工程代码下载请点击!

 

  如果觉得我的文章对你有帮助,请别忘了关注一下,屏幕左下角的推荐点一下哟!谢谢!

  2019.2.20 于厦门

你可能感兴趣的:(STM32驱动0.96寸OLED液晶屏(12864液晶屏))