STM32學習筆記——OLED屏


STM32學習筆記——OLED屏

  OLED屏的特點:

    1.  模塊有單色和雙色可選,單色為純藍色,雙色為黃藍雙色(本人選用雙色);

    2.  顯示尺寸為0.96寸

    3.  分辨率為128*64

    4.  多種接口方式,該模塊提供了總共 5 種接口包括: 6800、 8080 兩種並行接口方式、 3線或4線的SPI接口,IIC接口方式

    5.  不需要高壓,直接接3.3V就可以工作;(可以與stm32的引腳直接相接)

   

  OLED圖片:

    

 

 

 

  OLED引腳介紹:

    CS:OLED片選信號

    RST:OLED復位端口

    DC: 命令/數據選擇端口(0:讀寫命令, 1: 讀寫數據)

    SCLK(D0):串口時鍾線

    SDIN(D1): 串口數據線  

                              4線SPI寫操作時序圖:

          

    OLED的常用命令:

            

     設置OLED顯示內存的尋址方式:

        設置的命令:

     

  0x00: 表示水平尋址方式

  0x01: 表示垂直尋址方式 

  0x10: 表示頁尋址方式(默認方式)

     

   stm32與OLED屏接口的引腳介紹:

      CS————GPIOD3;

      RST————GPIOD4;

      DC—————GPIOD5;

      D0——————GPIOD6;

      D1——————GPIOD7;

   

  程序代碼:

      1.   相關宏定義

 1 #define OLED_CS(X)        X?GPIO_SetBits(GPIOD, GPIO_Pin_3):GPIO_ResetBits(GPIOD, GPIO_Pin_3)    //X為1時對應GPIO端口輸出高電平,X為0時對應GPIO端口輸出低電平
 2 
 3 #define OLED_RST(X)        X?GPIO_SetBits(GPIOD, GPIO_Pin_4):GPIO_ResetBits(GPIOD, GPIO_Pin_4)    
 4 
 5 #define OLED_DC(X)        X?GPIO_SetBits(GPIOD, GPIO_Pin_5):GPIO_ResetBits(GPIOD, GPIO_Pin_5)
 6 
 7 #define OLED_D0(X)        X?GPIO_SetBits(GPIOD, GPIO_Pin_6):GPIO_ResetBits(GPIOD, GPIO_Pin_6)    
 8 
 9 #define OLED_D1(X)        X?GPIO_SetBits(GPIOD, GPIO_Pin_7):GPIO_ResetBits(GPIOD, GPIO_Pin_7)    
10 
11 
12 #define OLED_Order 0     //定義寫命令
13 #define OLED_Data  1     //定義寫數據

      2.  GPIO初始化代碼:      

 1 void OLED_GPIO_Init(void)
 2 {
 3     GPIO_InitTypeDef GPIO_InitStruct;
 4     
 5     //開啟GPIOD的時鍾
 6     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
 7     //設置GPIO的基本參數
 8     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
 9     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;    //推挽輸出
10     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;    //輸出速度50MHz
11     
12     GPIO_Init(GPIOD, &GPIO_InitStruct);
13     
14     GPIO_SetBits(GPIOD, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);
15 }

    3. SPI 寫數據/命令

 1 /*        SPI寫數據/命令
 2  *    Mode :O:寫命令   1:寫數據
 3  *    data :數據/命令
 4  *
 5 */
 6 void SPI_Write(char data, int Mode)
 7 {    
 8     int i = 0;
 9     if(Mode)
10     {
11         OLED_DC(1);        //DC引腳輸入高,表示寫數據
12     }
13     else
14     {
15         OLED_DC(0);        //DC引腳輸入低,表示寫命令
16     }
17     OLED_CS(0);            //CS引腳輸入低,片選使能
18     for(i = 0; i < 8; i++)
19     {
20         OLED_D0(0);        //D0引腳輸入低
21         if(data & 0x80)    //判斷傳輸的數據最高位為1還是0
22         {
23             OLED_D1(1);    //D1引腳輸入高
24         }
25         else
26         {
27             OLED_D1(0);    //D1引腳輸入低
28         }
29         OLED_D0(1);        //D1引腳輸入高
30         data <<= 1;        //將數據左移一位
31     }
32     OLED_DC(0);            //DC引腳輸入低
33     OLED_CS(1);            //CS引腳輸入高,片選失能
34 }

    4. 設置OLED屏的顯示坐標:

      

    例如:設置頁地址為0xB2; 列地址的低4位為0x03,列地址的高4位為0x00;則顯示的位置如下圖:

 

    代碼:

 1 /*        設置OLED屏的顯示坐標
 2  *      X : 表示OLED的水平坐標(0—127)
 3  *      Y : 表示OLED的頁(0—7)
 4  *        
 5 */
 6 void OLED_Coord(unsigned char x, unsigned char y)
 7 {
 8     SPI_Write((0xb0+(y & 0x0f)), OLED_Order);        //設置OLED顯示的頁    
 9     SPI_Write((((x & 0xf0)>>4) | 0x10), OLED_Order);//設置OLED水平坐標的高4位
10     SPI_Write((x & 0x0f)|0x01, OLED_Order);                //設置OLED水平坐標的低4位
11 }

    清除OLED的顯示代碼:

 1 /*
 2  *        清除OLED的顯示
 3  *
 4  *
 5 */
 6 void OLED_Clear(void)
 7 {
 8     int i = 0, j = 0;
 9     for(i = 0; i < 8; i++)
10     {
11         OLED_Coord(0, i);
12         for(j = 0; j < 128; j++)
13         {
14             SPI_Write(0x00, OLED_Data);
15         }
16     }
17 }

      關閉OLED顯示代碼:

 1 /*        關閉OLED顯示
 2  *
 3  *
 4 */
 5 void OLED_Display_Off(void)
 6 {
 7     //電荷泵設置(初始化時必須打開,否則看不到顯示)
 8     SPI_Write(0x8D, OLED_Order);
 9     SPI_Write(0x10, OLED_Order);//bit2   0:關閉        1:打開
10     SPI_Write(0xAE, OLED_Order);//0xAE:關閉顯示
11 }

      開啟OLED顯示代碼:

 1 /*
 2  *        開啟OLED顯示
 3  *
 4 */
 5 void OLED_Display_On(void)
 6 {
 7     //電荷泵設置(初始化時必須打開,否則看不到顯示)
 8     SPI_Write(0x8D, OLED_Order);
 9     SPI_Write(0x14, OLED_Order);//bit2   0:關閉        1:打開
10     SPI_Write(0xAF, OLED_Order);//0xAF:開顯示    
11 }

    OLED顯示的參數的初始化:

      1. 在設置OLED的參數時,並不需要把所有的參數都設置一次;有些參數是默認的(可以不進行設置),只是需要設置一寫必要的參數;

        (如:0xAF: 開顯示, 0x8D:電荷泵設置(初始化是必須打開,否則看不到顯示))

       2.代碼(初始化代碼中,介紹了大部分命令):

 1 /*        OLED顯示參數的初始化
 2  *
 3  *
 4  *
 5 */
 6 void OLED_Init(void)
 7 {
 8     OLED_GPIO_Init();
 9     
10     OLED_RST(1);
11     delay_ms(100);
12     OLED_RST(0);
13     delay_ms(100);
14     OLED_RST(1);
15     
16     SPI_Write(0xAE, OLED_Order);//0xAE:關顯示   
17     
18     SPI_Write(0x00, OLED_Order);//設置低列地址
19     SPI_Write(0x10, OLED_Order);//設置高列地址
20     
21     //設置行顯示的開始地址(0-63)
22     //40-47: (01xxxxx)
23     SPI_Write(0x40, OLED_Order);
24     
25     //設置對比度
26     SPI_Write(0x81, OLED_Order);
27     SPI_Write(0xff, OLED_Order);//這個值越大,屏幕越亮(和上條指令一起使用)(0x00-0xff)
28     
29     SPI_Write(0xA1, OLED_Order);//0xA1: 左右反置,  0xA0: 正常顯示(默認0xA0)
30     SPI_Write(0xC8, OLED_Order);//0xC8: 上下反置,  0xC0: 正常顯示(默認0xC0)
31     
32     //0xA6: 表示正常顯示(在面板上1表示點亮,0表示不亮)
33     //0xA7: 表示逆顯示(在面板上0表示點亮,1表示不亮)
34     SPI_Write(0xA6, OLED_Order);
35     
36     SPI_Write(0xA8, OLED_Order);//設置多路復用率(1-64)
37     SPI_Write(0x3F, OLED_Order);//(0x01-0x3f)(默認為3f)
38     
39     
40     //設置顯示抵消移位映射內存計數器
41     SPI_Write(0xD3, OLED_Order);
42     SPI_Write(0x00, OLED_Order);//(0x00-0x3f)(默認為0x00)
43     
44     //設置顯示時鍾分頻因子/振盪器頻率
45     SPI_Write(0xD5, OLED_Order);
46     //低4位定義顯示時鍾(屏幕的刷新時間)(默認:0000)分頻因子= [3:0]+1
47     //高4位定義振盪器頻率(默認:1000)
48     SPI_Write(0x80, OLED_Order);//
49     
50     //時鍾預充電周期
51     SPI_Write(0xD9, OLED_Order);
52     SPI_Write(0xF1, OLED_Order);//[3:0],PHASE 1;   [7:4] PHASE 2
53     
54     //設置COM硬件應腳配置
55     SPI_Write(0xDA, OLED_Order);
56     SPI_Write(0x12, OLED_Order);//[5:4]  默認:01
57     
58     SPI_Write(0xDB, OLED_Order);//
59     SPI_Write(0x40, OLED_Order);//
60     
61     //設置內存尋址方式
62     SPI_Write(0x20, OLED_Order);
63     //00: 表示水平尋址方式
64     //01: 表示垂直尋址方式
65     //10: 表示頁尋址方式(默認方式)
66     SPI_Write(0x02, OLED_Order);//    
67     
68     //電荷泵設置(初始化時必須打開,否則看不到顯示)
69     SPI_Write(0x8D, OLED_Order);
70     SPI_Write(0x14, OLED_Order);//bit2   0:關閉        1:打開
71     
72     //設置是否全部顯示 0xA4: 禁止全部顯示
73     SPI_Write(0xA4, OLED_Order);
74 
75     //0xA6: 表示正常顯示(在面板上1表示點亮,0表示不亮)
76     //0xA7: 表示逆顯示(在面板上0表示點亮,1表示不亮)
77     SPI_Write(0xA6, OLED_Order);//
78     
79     SPI_Write(0xAF, OLED_Order);//0xAF:開顯示
80     
81     SPI_Write(0xAF, OLED_Order);//0xAF:開顯示
82     
83     OLED_Clear();
84 }

      顯示16*16的漢字函數代碼:

 1 /*        顯示漢字
 2  *        x:表示顯示的水平坐標
 3  *        y: 表示顯示的垂直坐標
 4  *        *p: 表示要顯示漢字模組的首地址
 5 */
 6 void OLED_ShowChinese(int x, int y, const unsigned char *p)
 7 {
 8     int i = 0;
 9     OLED_Coord(x, y);
10     for(i = 0; i < 32; i+=2)
11     {
12         SPI_Write(p[i], OLED_Data);
13     }
14     OLED_Coord(x, y+1);
15     for(i = 1; i < 32; i+=2)
16     {
17         SPI_Write(p[i], OLED_Data);
18     }
19 }

      顯示ASCII碼的函數代碼:

 1 /*        顯示ASCII
 2  *        x:表示顯示的水平坐標
 3  *        y: 表示顯示的垂直坐標
 4  *        *p: 表示要顯示漢字模組的首地址
 5 */
 6 void OLED_ShowChar(int x, int y, const unsigned char *p)
 7 {
 8     int i = 0;
 9     OLED_Coord(x, y);
10     for(i = 0; i < 16; i+=2)
11     {
12         SPI_Write(p[i], OLED_Data);
13     }
14     OLED_Coord(x, y+1);
15     for(i = 1; i < 16; i+=2)
16     {
17         SPI_Write(p[i], OLED_Data);
18     }
19 }

    注意1:在使用PCtoLCD2002完美版進行取模時,如果取模的字高大於8時一定要注意;

      如果字高16;取模的順序是:從第一列開始,前8個點為第一個字節,后8個點為第二個字節

     然后第二列取模,前8個點為第三個字節,后8個點為第四個字節,以此類推,而OLED屏的內存

     尋址方式為0x10: 表示頁尋址方式(默認方式)時,那么顯示時將會亂碼;因為是按頁來顯示的,

     那么第一個字節顯示在第一列,而第二個字節本應該顯示在第二頁的第一列,而被錯誤的顯示在第一頁的第二列,以此類推,導致顯示亂碼;

      (這就是為什么OLED_ShowChar()函數和OLED_ShowChinese()函數中, 前面先顯示數組下標為偶數的數組, 后面顯示數組下標為奇數的數組)

    

 

 

    OLED顯示的main函數代碼:

 1 int main(void)
 2 {
 3     SysTick_Init();
 4     OLED_Init();
 5     
 6     OLED_ShowChinese(0, 0, xing);//‘姓’    
 7     OLED_ShowChinese(18, 0, ming);//‘名’
 8     OLED_ShowChar(36, 0, ASCII_Colon);//‘:’
 9     OLED_ShowChinese(0, 2, xue);//‘學’    
10     OLED_ShowChinese(18, 2, hao);//‘號’
11     OLED_ShowChar(36, 2, ASCII_Colon);//‘:’    
12 //    SPI_Write(0x2F, OLED_Order);    //0x2F:激活滾動        0x2E:關閉滾動
13 //    //設置滾動方式:
14 //    //        0x26/0x27        :水平滾動(右向/左向)
15 //    //        0x29/0x2A        :水平和垂直滾動(右向/左向)
16 //    //        0xA3            :垂直滾動
17 //    SPI_Write(0x27, OLED_Order);    
18 //    SPI_Write(0x00, OLED_Order);
19 //    SPI_Write(0x00, OLED_Order);
20 //    SPI_Write(0x00, OLED_Order);
21 //    SPI_Write(0x03, OLED_Order);
22 //    SPI_Write(0x30, OLED_Order);    
23     while(1);

    注意:在使用滾動命令時,一定要先寫入0x2F, 激活滾動

 

    取模數組:

 1 const unsigned char xing[]=
 2 {    0x10,0x40,0x10,0x22,0xF0,0x15,0x1F,0x08,
 3     0x10,0x16,0xF0,0x21,0x40,0x40,0x3C,0x42,
 4     0x10,0x42,0x10,0x42,0xFF,0x7F,0x10,0x42,
 5     0x10,0x42,0x10,0x42,0x00,0x40,0x00,0x00};/*"姓",0*/
 6 const unsigned char A[]=
 7 {    0x00,0x20,0x00,0x3C,0xC0,0x23,0x38,0x02,
 8     0xE0,0x02,0x00,0x27,0x00,0x38,0x00,0x20};/*"A",0*/
 9 const unsigned char ming[]=
10 {    0x00,0x04,0x20,0x04,0x20,0x04,0x10,0x02,
11     0x08,0xFE,0x14,0x43,0x67,0x43,0x84,0x42,
12     0x44,0x42,0x24,0x42,0x14,0x42,0x0C,0x42,
13     0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00};/*"名",0*/
14 const unsigned char ASCII_Colon[]=
15 {    0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,
16     0xC0,0x30,0x00,0x00,0x00,0x00,0x00,0x00};/*":",0*/    
17 const unsigned char xue[]=
18 {    0x40,0x04,0x30,0x04,0x11,0x04,0x96,0x04,
19     0x90,0x04,0x90,0x44,0x91,0x84,0x96,0x7E,
20     0x90,0x06,0x90,0x05,0x98,0x04,0x14,0x04,
21     0x13,0x04,0x50,0x04,0x30,0x04,0x00,0x00};/*"學",0*/
22 const unsigned char hao[]=
23 {    0x80,0x00,0x80,0x00,0x80,0x00,0xBE,0x06,
24     0xA2,0x05,0xA2,0x04,0xA2,0x04,0xA2,0x04,
25     0xA2,0x44,0xA2,0x84,0xA2,0x44,0xBE,0x3C,
26     0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00};/*"號",0*/

      OLED的命令基本上已經在上面介紹,還有一些屏幕顯示滾動的命令;本人沒有進行一一實驗;

    實驗現象:

 


免責聲明!

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



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