STM32驅動0.96寸OLED液晶屏(12864液晶屏)


  1  序言

  在利用單片機是設計產品的過程中常常需要利用一些數據顯示設備來顯示一些關鍵信息,常用的做法是利用串口將數據傳送到計算機上顯示,或者是利用藍牙模塊將數據送到移動終端上顯示,那么還有一種方法,就是將數據直接顯示在一塊小的液晶屏幕上,這種方式也是十分的方便快捷的。那么如何要在我們打單片機系統上添加一塊液晶顯示屏到底該怎么做呢?我相信這也是許多在網上搜OLED液晶顯示屏驅動程序的小伙伴們最為關心的問題。本片文章將以STM32F103單片機為例,講解如何在單片機系統上面加一塊液晶顯示屏,並且使其能夠顯示我們想要的數據,文字符號或者圖片信息等。

  2  如何利用STM32單片機驅動12864液晶屏

  STM32單片機是目前市面上使用最為廣泛的單片機,該單片機型號眾多,每種型號適用於不同的工作要求,大致可分為F0、F1、F4、F7等系列。那么我所使用的單片機型號為STM32F103RC,其他型號的液晶屏驅動程序也是類似的,差異並不是非常大,而所使用的液晶屏幕為市面上常見的0.96寸OLED液晶屏幕(也叫12864液晶屏),都是淘寶上買的,價格也就幾十塊錢。如圖2-1所示。

 Fig. 1:0.96寸OLED液晶顯示屏及STM32F103RC單片機做小系統外觀圖 

  2.1  0.96寸OLED端口含義

  說道硬件的引腳連接,這個問題似乎也沒多大難度,但是很多剛開始接觸這一塊知識的小伙伴在網上搜了好多資料之后就納悶了,例如:網上的所提到的SCL,SDA引腳是啥啊?我這液晶屏上面怎么沒有啊?或者是這個程序里面的DIN,CLK是指的那個端口啊?我這硬件上也沒有啊。圖2.1-1顯示了市面上兩種常見的OLED液晶顯示屏的端口標號。

 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<len;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<y1;y++)
    {
        OLED_Set_Pos(x0,y);
    for(x=x0;x<x1;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);     
}  

    Github: >>>點擊訪問

    百度雲盤下載:點擊鏈接 提取碼為:59dx

  上述代碼只是一個驅動程序中的一部分代碼,需要先初始化系統時鍾,其次初始化調用OLED初始化函數,程序方可正常運行。

  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);
}    

  觀察屏幕中的數據,如下所示:

 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

  字模軟件的配置與使用方式如圖

 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的圖像轉換功能轉換為代碼。

 

 Fig. 3.4-1:PCtoLCD圖像轉換實例文件

  在輸入到軟件之前需要通過圖像處理軟件調整圖像分辨率並做二值化處理(就是將圖像變成黑白色,分辨率調整為128x64)

  過程我就省略了,對此有需求或者有興趣的小伙伴請在評論區留言。

  轉換的代碼放在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、完整工程代碼請到下載方式:>>>點擊獲取

  百度雲獲取方式:點擊鏈接 提取碼為:hmy6

 

  2019.2.20 於廈門


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM