目錄
- 序言
- OLED簡介
- 模塊介紹
- 引腳定義
- SSD1306控制芯片驅動
- 時序圖講解
- SSD1306常用命令
- 命令設置SSD1306
- 如何顯示字符
- 測試結果
- 資料下載
序言
液晶屏通常作為嵌入式設備的顯示終端,用于顯示一些關鍵信息,將信息直接顯示在一塊小的液晶屏幕上。
液晶屏除了可以作為顯示終端外,還可以作為調試信息輸出的一個終端。
在調試硬件程序的時候,通常會對程序進行調試,想輸出一些狀態或者信息來體現程序當前的運行狀態,一般我們會選擇串口打印輸出內容,或者LED的不同閃爍頻率代表不同狀態,當然我們也可以使用一個液晶屏來顯示不同內容,這種方式也是十分的方便快捷的。
OLED簡介
OLED,即有機發光二極管(Organic Light-Emitting Diode),又稱為有機電激光顯示(Organic Electroluminesence Display, OELD)。OLED由于同時具備自發光,不需背光源、對比度高、厚度薄、視角廣、反應速度快、可用于撓曲性面板、使用溫度范圍廣、構造及制程較簡單等優異之特性,被認為是下一代的平面顯示器新興應用技術。LCD都需要背光,而OLED不需要,因為它是自發光的。這樣同樣的顯示,OLED效果要來得好一些。OLED的尺寸難以大型化,但是分辨率確可以做到很高。
模塊介紹
- 尺寸:0.96寸
- 控制芯片:SSD1306
- 管腳數量:7
- 引腳間距:2.54mm
- 分辨率:128*64,可以顯示漢字、ASCII、圖案,對比度高
- 可視角度:>160度
- 無需背光(OLED屏的特點)
- 供電:3V-5V
有的模塊是不跟5V接口兼容的,使用前一定要確認好。
引腳定義
- GND:電源地
- VCC:2.2V~5.5V
- D0:SCL,CLK時鐘
- D1:SDA,MOSI數據
- RES:RST復位
- D/C:數據/命令選擇
- CS:片選,接地
此模塊可以采用SPI或IIC通信方式,最多只需要4個IO口既可驅動。
SPI電路連接:
GND---地
VCC---3.3V或5V
D0---接單片機IO,作為SPI總線的CLK時鐘引腳,時鐘
D1---接單片機IO,作為SPI總線的MOSI數據引腳,數據輸入
RES---接單片機IO
D/C---接單片機IO,高電平為寫數據,低電平為寫命令
CS---片選,接地(可不連接單片機IO),選中SSD1306
IIC電路連接:
GND---地
VCC---3.3V或5V
D0---接單片機IO,作為IIC的SCL引腳
D1---接單片機IO,作為IIC的SDA引腳
CS---接地
SSD1306控制芯片驅動
時序圖講解
我們以STM32單片機為例,使用5個GPIO模擬SPI總線與SSD1306總線進行通訊。
因為STM32與OLED屏的通訊只是單向數據傳輸,即只存在STM32向OLED屏發送數據,不涉及到讀取返回數據,所以我們要實現顯示功能之前,需要根據SPI寫操作時序圖,先實現一個向SSD1306寫入一個字節的函數實現。
SSD1306使用4Wire SPI寫操作的時序圖
封裝一個向SSD1306寫入一個字節的函數,
函數原型為:void OLED_WR_Byte(uint8_t dat,uint8_t cmd);
其中:dat為待寫入的數據或者命令;cmd為數據或命令標志,0表示命令;1表示數據。
由上面SPI操作的時序圖可知,IO引腳的時序如下所示:
- 首選看發送的字節是命令還是數據,如果是命令,OLED_DC(D/C)引腳置0,即低電平;如果是數據,OLED_DC(D/C)引腳置1,即高電平。
if(cmd)
OLED_DC_Set();
else
OLED_DC_Clr();
- 片選OLED_CS(CS)引腳置0,即拉低(硬件電路中CS引腳也可以直接與GND相連,這樣就不用操作CS引腳了)。
OLED_CS_Clr();
- 1個字節的數據有8位,將8位數據由高到低的順序發出,數據要在OLED_SCLK(D0)引腳的上升沿之前設置好,所以要先將OLED_SCLK(D0)置低,然后將一位數據送至OLED_SDIN(D1)引腳,然后將OLED_SCLK(D0)置高,這樣一位數據就發送出去了,如此循環8次,一個字節的數據就發送出去了。
for(i=0;i<8;i++)
{
OLED_SCLK_Clr();
if(dat&0x80)
OLED_SDIN_Set();
else
OLED_SDIN_Clr();
OLED_SCLK_Set();
dat<<=1;
}
- 8位數據發送完畢之后,將OLED_CS(CS)引腳拉高,即置1,恢復至初始狀態。
OLED_CS_Set();
OLED_CS_Set();
OLED_DC_Set();
*代碼完整實現
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_CS_Set();
OLED_DC_Set();
}
SSD1306常用命令
其他命令,可以詳見SSD1306 datasheet的第28頁。從這頁開始,對SSD1306的指令有詳細的介紹。(手冊的下載鏈接,見文尾資料下載)
命令設置SSD1306
有了寫字節的函數封裝:void OLED_WR_Byte(uint8_t dat,uint8_t cmd);然后查詢手冊中的命令字,我們可以發送命令初始化SSD1306,比如:
- 關閉顯示面板
OLED_WR_Byte(0xAE,OLED_CMD);
- 設置頁地址模式
OLED_WR_Byte(0x20,OLED_CMD);
SSD1306有3種內存尋址模式,分別是:頁尋址模式(page addressing mode), 水平尋址模式(horizontal addressing mode)和垂直尋址模式(vertical addressing mode),分別對應的命令字節為:20h、21h、22h,因為OLED模塊復位之后默認是 page addressing mode,所以下面只講頁尋址模式;其他兩種模式跟頁尋址模式的差異就是地址指針自增方式不一樣,詳情可以參考一下SSD1306的數據手冊。
如何顯示字符
在初始化OLED之后,如何在屏幕上顯示字符呢?
在這之前,先了解一下SSD1306內部的RAM;SSD1306內部有個SRAM稱為GDDRAM(Graphic Display Data RAM),大小是128 × 64 bits,被分為8個 PAGE,用于單色128×64點陣顯示,當我們往這個RAM寫入數據,就會顯示特定內容,如圖:
上面'COL'的含義是GDDRAM列(column)
在頁尋址模式下,每當對RAM進行讀寫操作之后,列地址指針會自動+1,直到列地址指針指向列結束地址后,會重新指向列開始地址;而且在該模式下,一定要設置新的頁面和列地址才能訪問下一個頁面的內容,所以設置顯示字符之前一般都會調用下面幾句語句來確定顯示位置:
OLED_WR_Byte (0xb0+i,OLED_CMD); //設置頁地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //設置顯示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //設置顯示位置—列高地址
封裝設置顯示位置的函數如下:
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);
}
例如如果頁地址設為B2h,低列地址為03h,而高列地址為00h,那么也就意味著開始列是PAGE2的SEG3,而RAM的獲取指針定位到下圖中。而輸入的數據將會被寫入列3的位置。
所以確定好了顯示位置,直接輸出字符對應的像素數據數組就好了。
測試結果
測試電路連接:
GND---地
VCC---3.3V
D0---接PB9,作為SPI總線的CLK時鐘引腳,時鐘
D1---接PB8,作為SPI總線的MOSI數據引腳,數據輸入
RES---接PB7
D/C---接PB6,高電平為寫數據,低電平為寫命令
CS---片選,接PB5,接地選中SSD1306