OLED的波形曲線、進度條、圖片顯示(STM32 HAL庫 模擬SPI通信 5線OLED屏幕)詳細篇

少廢話,先上效果圖

屏幕顯示效果

       

全家福

 

觀看演示效果:

https://www.bilibili.com/video/BV13V411b78V

 

一、基礎認識及引腳介紹

屏幕參數:

尺寸:0.96英寸

分辨率:128*64

驅動芯片:SSD1306

驅動接口協議:SPI

引腳說明:

二、 SSD1306芯片介紹

SSD1306是一款帶控制器的用於OLED點陣圖形顯示系統的單片CMOS OLED/PLED驅動器。它由128個SEG(列輸出)和64個COM(行輸出)組成。

 

SSD1306嵌入了對比度控制器、顯示RAM和振盪器,從而減少了外部組件的數量和功耗。它有256級亮度控制。數據/命令可以通用硬件選擇3種通信方式:6800/8000串口、IIC接口和SPI接口。適用於手機子顯示器、MP3播放器、計算器等多種便攜應用。

 

模塊有多種通信方式,包括串口、IIC、SPI,其選擇通過硬件固化,如果使用IIC通信方式時可以選擇兩個IIC地址,其分別爲0x78和0x7A。

三、 通信方式(4線SPI)

所謂的4線SPI並非是收發一體的標準4線SPI協議,標準的4線SPI爲SCLK、CS、MOSI、MISO,模塊所述大的4線SPI是單向的,即MISO(主入從出)變成了D/C(數據命令選擇腳)。

該4線串行接口由串行時鐘SCLK、串行數據SDIN、數據命令選擇線D/C#、片選信號CS#組成.在四線SPI模式下,D0爲SCLK,D1爲SDIN。

其真實使用的是標準的3線SPI,也就是省略了MISO(主入從出)數據線。

 

數據命令選擇:DC爲高時表示數據,DC爲低時表示寫命令

片選:CS腳爲低電平是選中,如果不通信時將腳輸出高電平

數據通信:在SCLK的每一個上升邊上,SDIN按D7,D6,…D0,高位先寫出

 

通信時序圖

四、編程(CubeMX部分)

(一)   CubeMX基礎配置

選擇芯片(STM32F103C8T6)

打開外部的高速和低速晶振

所佔用的引腳

 

開啓SWD調試

所佔用的引腳

時鐘樹設置

設置系統時鐘爲最高速度,72MHZ

(二)  GPIO初始化

初始化電平分析

D0:SCLK,時鐘線,上升沿有效,所以默認輸出高電平

D1:SDIN,數據線,默認輸出電平隨意

RST:復位腳,低電平復位,默認電平爲低

DC:數據/命令選擇腳,默認輸出電平隨意

CS:片選引腳,默認輸出高電平

引腳選擇

使用單片機是STM32F103C8T6

考慮到已經使用的IO和硬件上的佈局,最好是將一個模塊的相關線放在一起,所以選擇如下接線方式:

D0   ---->  B5

D1   ---->  B6

RST  ---->  B7

DC   ---->  B8

CS   ---->  B9

(三)  CubeMX GPIO配置

所使用的IO

(四) 整體配置圖

五、 編程(程序部分)

(一)    分析原理

有IIC通信方式爲什麼要有SPI,我看可以簡單對比一下:

 

IIC通信方式:兩條數據線,通信數據較慢

SPI通信方式:四條數據線,通信數據腳快

 

這就看項目需要,如果需要刷屏速度的話當然選用SPI方式優秀

在此之前要知道,OLED SPI通信中不需要單片機讀取OLED模塊的任何數據,所以單片機按照一定的規則向SPI線上寫數據就可以了。在通信中單片機充當SPI的主機,OLED模塊爲SPI的從機。因爲主機不需要接收從機數據,所以標準的四線SPI中MISO線就沒必要存在了。通信使用的是標準的三線SPI,即CS、CLK、MOSI。

 

根據這個時序圖就可以瞭解如何變成,在CS爲低電平時就是芯片通信啓動;D/C是數據或者命令的選擇,也就是主機拉高拉低可以控制寫的數據是指令還是數據;SCLK(D0)是時鐘引腳,MOSI (D1 SDIN)爲數據已經。當SCLK上升沿的瞬間,從機將會讀取MOSI上的電平。發送一個字節時,是高位在前低位在後的。

所以發送一個字節大的函數,這實現了單向的數據傳輸SPI

實現步驟:

l  先保證時鐘線默認爲低電平

l  循環發送8位數據,發送最高位數據:

|  設置時鐘線爲低電平

|   判斷髮送的數據是1還是0,1則發送高電平,0則低低電平

|   設置時鐘線爲高電平(此時有上升沿)

l  數據左移一位,讓次高位在最高位上

l  循環發送8位數據,發送次高位數據:

|   設置時鐘線爲低電平

|   判斷髮送的數據是1還是0,1則發送高電平,0則低低電平

|   設置時鐘線爲高電平(此時有上升沿)

l  數據左移一位,……

l  ……

l  保證時鐘線最終爲高電平

代碼,需要交流可加本人微信,見文章結尾

數據和命令分發:

OLED SPI方式爲了更快的數據交互,有一個專門的引腳作爲數據和命令選擇腳,而IIC還要靠發送數據去做判斷,可想而知他們的速率會有相差。

D/C引腳就是數據/命令選擇,低電平寫命令,高電平寫數據

設計思路:

l  如果是命令,則拉高DC引腳

l  如果不是命令,則拉低DC引腳

l  CS引腳拉低表示選中從機,開啓通信

l  發送一個數據,則調用了前面的標準3線SPI通信函數

l  拉高DC引腳

l  拉高CS引腳,關閉通信

代碼,需要交流可加本人微信,見文章結尾

六、OLED進階版及曲線顯示

(一)驅動分析

想要了解OLED顯示曲線就必須瞭解其顯示本質,更加底層細緻的分析寄存器及顯示原理。

0.96寸的12864 OLED屏幕由128*64個發光二極管組成。

這是數據手冊的截圖

注意圖總的黑色和綠色,它只是告訴你可以反向,也就是0編號的位置可以換成127編號而已。

由此可見屏幕總共分爲8頁(page),每頁佔用Y軸的8行發光二極管和X軸的128個發光二極管,所以一頁總共佔用8*128=1024個發光二極管。

所以在真實的圖中表示:

這是數據手冊中其中一頁的表示

這是基於沒有做反轉時的介紹,如果反轉了就不是這樣了。反轉是在程序初始化是調用的,後面分析的初始化函數有介紹

其中“Each lattice represents one bit of image data”的翻譯是“每個格子代表一個圖像數據位”,因爲一頁剛好8個Y方向的各種,對應的剛好是U8類型,所以我們通常用一個U8表示一頁裏的一個列的顯示,一頁中共有128個列,所以一頁總共需要1*128=128個U8類型數據。並且從圖中可以看出,最下面的是最高位。

舉個栗子:

假如我們拿第二頁的第一列來說,其值的二進制爲11110000,其實點亮的是如下圖的紅色部分。

這也就說明高位點亮的是下面的位置。

(二)初始化函數及逐條分析

 1 void my_oled_init(){
 2   my_oled_rst();
 3     my_oled_write_byte(0xAE,OLED_CMD);//關閉顯示
 4     
 5     my_oled_write_byte(0x00,OLED_CMD);//X軸低位,起始X軸爲0
 6     my_oled_write_byte(0x10,OLED_CMD);//X軸高位
 7     my_oled_write_byte(0x40,OLED_CMD);//Y軸,可設區間[0x40,0x7F],設置爲0了
 8     
 9 
10     my_oled_write_byte(0xA1,OLED_CMD);//設置X軸掃描方向,0xa0左右反置 ,0xa1正常(左邊爲0列)
11     my_oled_write_byte(0xC8,OLED_CMD);//設置Y軸掃描方向,0xc0上下反置 ,0xc8正常(上邊爲0行)
12     my_oled_write_byte(0xA6,OLED_CMD);//位值表示的意義,0xa6表示正常,1爲點亮,0爲關閉,0xa7顯示效果相反
13     
14 
15     my_oled_write_byte(0x81,OLED_CMD);//命令頭,調節亮度,對比度,變化很小,但是仔細可以觀察出來
16     my_oled_write_byte(0xFF,OLED_CMD);//可設置區間[0x00,0xFF]
17     
18     my_oled_write_byte(0xA8,OLED_CMD);//命令頭,設置多路複用率(1 to 64)
19     my_oled_write_byte(0x3f,OLED_CMD);//--1/64 duty
20     
21     my_oled_write_byte(0xD3,OLED_CMD);//命令頭,設置顯示偏移移位映射RAM計數器(0x00~0x3F)
22     my_oled_write_byte(0x00,OLED_CMD);//不偏移
23     
24     my_oled_write_byte(0xd5,OLED_CMD);//命令頭,設置顯示時鐘分頻比/振盪器頻率
25     my_oled_write_byte(0x80,OLED_CMD);//設置分割比率,設置時鐘爲100幀/秒
26     
27     my_oled_write_byte(0xD9,OLED_CMD);//命令頭,--set pre-charge period
28     my_oled_write_byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
29     
30     my_oled_write_byte(0xDA,OLED_CMD);//命令頭,--set com pins hardware configuration
31     my_oled_write_byte(0x12,OLED_CMD);
32     
33     my_oled_write_byte(0xDB,OLED_CMD);//命令頭,--set vcomh
34     my_oled_write_byte(0x40,OLED_CMD);//Set VCOM Deselect Level
35     
36     my_oled_write_byte(0x20,OLED_CMD);//命令頭,設置尋址模式
37     my_oled_write_byte(0x10,OLED_CMD);//頁面尋址模式(重置) (0x00/0x01/0x02)
38     
39     my_oled_write_byte(0x8D,OLED_CMD);//命令頭,--set Charge Pump enable/disable
40     my_oled_write_byte(0x14,OLED_CMD);//--set(0x10) disable
41     
42     my_oled_write_byte(0xA4,OLED_CMD);//恢復到RAM內容顯示(重置)
43 
44     my_oled_clear();//清屏
45     
46     my_oled_write_byte(0xAF,OLED_CMD); //開啓顯示
47 
48 }

局部分析:

設置尋址模式

A[1:0] = 00b,水平尋址模式

A[1:0] = 01b,垂直尋址模式

A[1:0] = 10b,頁面尋址模式(重置)

A[1:0] = 11b,無效

00b,水平尋址模式

01b,垂直尋址模式

10b,頁面尋址模式

尋址模式對應着我們的取模:

我們取模軟件設置的刷新方式:

從左到右從上到下:對應了頁面尋址模式

縱向8點下高位:縱向右8個點,最下面的點爲最高位

其它相關逐條分析內容,可加本人微信獲取,見文末

  (三)  寄存器配置補充(詳細)

需要資料可加本人微信,見文末

 


 

 

觀看演示效果:https://www.bilibili.com/video/BV13V411b78V

 

原文鏈接:https://www.cnblogs.com/dongxiaodong/p/14321569.html

 

如需資料可加本人微信

 

微信號:dongxiaodongwx

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章