少廢話,先上效果圖
螢幕顯示效果
全家福
觀看演示效果:
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