摘? 要:文章對OLED模塊及其驅(qū)動芯片SSD1306、OLED的顯示畫面與顯示存儲器之間的關(guān)系、OLED寫命令或?qū)憯?shù)據(jù)時序等進(jìn)行了深入的研究與分析,揭示了OLED模塊寫命令或?qū)憯?shù)據(jù)的顯示過程與工作原理,總結(jié)了OLED顯示像素點(diǎn)的步驟,并根據(jù)所總結(jié)的步驟編寫出顯示程序代碼,編譯后把代碼燒錄到16位單片機(jī)STM32F103ZET6芯片上運(yùn)行,成功實(shí)現(xiàn)OLED顯示點(diǎn)線與漢字的功能,為后期深入圖形顯示以及其他類型顯示屏的顯示研究打下堅(jiān)實(shí)的基礎(chǔ)。
關(guān)鍵詞:OLED;SSD1306;時序分析;程序代碼;字符顯示
中圖分類號:TN383? ? 文獻(xiàn)標(biāo)識碼:A? 文章編號:2096-4706(2023)13-0053-06
Analysis and Implementation of OLED Screen Display
SU Jieren
(Guangzhong Panyu Polytechnic, Guangzhou? 511483, China)
Abstract: In this paper, a in-depth research and analysis on the OLED module and its driver chip SSD1306, the relationship between OLED display screen and display memory, OLED writing command or writing data timing is conducted. It reveals the display process and working principle of OLED module writing commands or writing data, summarizes the steps of OLED displaying pixels, and writes display program code based on the summarized steps. After compilation, the code is burned and run on the 16 bit Single-Chip Microcomputer STM32F103ZET6 chip, successfully achieving the function of OLED displaying dots, lines, and Chinese characters, laying a solid foundation for further research on graphic display and display other types of display screens.
Keywords: OLED; SSD1306; time series analysis; program code; character display
0? 引? 言
OLED是電子產(chǎn)品制作中較為常用的顯示屏之一,其顯示所用的驅(qū)動代碼技術(shù)也相當(dāng)穩(wěn)定成熟,用戶可以直接在網(wǎng)絡(luò)上下載修改使用,但這樣用戶只是知道在OLED上如何顯示出字符或圖片,不能很好地理解OLED的工作原理及顯示過程。本文深入淺出地介紹了OLED模塊的寫命令或?qū)憯?shù)據(jù)時序及其顯示代碼的編寫過程,便于讀者理解OLED的顯示步驟和工作原理。
1? OLED屏介紹
OLED[1]即有機(jī)發(fā)光二極管,又稱為有機(jī)電激光顯示(Organic Electroluminescence Display),它具有自發(fā)光、對比度高、厚度薄、視角廣、使用溫度范圍廣、反應(yīng)速度快等優(yōu)點(diǎn)。它不需背光源,可用于撓曲性面板,是新一代平面顯示器應(yīng)用技術(shù)。
文章介紹的是I2C接口0.96英寸的OLED模塊,各引腳接口說明如表1所示。模塊的分辨率為128 × 64,具有并行6800、并行8080、串行SPI、串行I2C四種接口方式,可通過OLED模塊上的BS1/BS2端口設(shè)置接口方式,當(dāng)BS1設(shè)置為1,BS2設(shè)置為0時,OLED模塊為I2C接口方式。
2? OLED驅(qū)動芯片SSD1306
OLED使用SSD1306芯片作為驅(qū)動[2]芯片,SSD1306的顯存總共為128 × 64 bit大小,SSD1306將這些顯存分成8頁,每頁包含128個字節(jié),總共8頁,剛好是128 × 64的點(diǎn)陣大小,如表2所示。
OLED模塊的分辨率為128 × 64,屏幕的每個像素恰巧與SSD1306顯存的點(diǎn)陣一一對應(yīng),往SSD1306的顯存點(diǎn)陣寫邏輯“1”,則OLED屏幕對應(yīng)的像素點(diǎn)被點(diǎn)亮,OLED畫面像素點(diǎn)與SSD13066儲存器點(diǎn)陣映射關(guān)系如圖1所示。
MCU對OLED屏幕顯示操作都是通過對SSD1306芯片進(jìn)行寫命令或?qū)憯?shù)據(jù)操作實(shí)現(xiàn)的,部分指令如表3所示。
如命令0x81,設(shè)置對比度,包含兩個字節(jié),第一個0x81為命令,隨后發(fā)送的一個字節(jié)為要設(shè)置的對比度的值。這個值設(shè)置得越大屏幕就越亮。如命令0x8D,包含兩個字節(jié),第一個為命令字,第二個為設(shè)置值,第二個字節(jié)的BIT2表示電荷泵的開關(guān)狀態(tài),該位為1開啟電荷泵,該位為0則關(guān)閉電荷泵。在模塊初始化的時候,這個命令必須要開啟,否則是看不到屏幕顯示的。
對SSD1306芯片寫命令或?qū)憯?shù)據(jù)操作,采用分割法進(jìn)行分析,時序[3]如圖2所示。
根據(jù)寫命令或?qū)憯?shù)據(jù)操作特點(diǎn)繪制分割線,并在分割線處標(biāo)記ABCDEFGHI,對標(biāo)記點(diǎn)進(jìn)行分析:
AB:S為IIC開始信號。
BC:IIC總線上設(shè)備的從地址位構(gòu)成如圖3所示,設(shè)置為0x78。
其中,R/W#表示讀寫選擇位,R/W#設(shè)置為邏輯“0”時,主機(jī)發(fā)送命令或數(shù)據(jù)到IC,R/W#設(shè)置為邏輯“1”時,主機(jī)讀取IC數(shù)據(jù)。SA0為從地址位,由SSD1306芯片D/C#引腳電平來決定,D/C#引腳接VCC時SA0=1,D/C#引腳接地時SA0=0。通常設(shè)置D/C#引腳接地,而MCU與驅(qū)動IC交互時,都是MCU發(fā)送命令或數(shù)據(jù)到IC,也就是只有寫數(shù)據(jù),沒有讀數(shù)據(jù),所以R/W#設(shè)置為邏輯“0”,因此得到從機(jī)地址為01111000b,即0x78。
CD:IIC應(yīng)答信號。
DE:控制字節(jié)位構(gòu)成如圖4所示,主要由Co和D/C#位組成,后跟六個“0”。
其中,Co表示連續(xù)設(shè)置位,設(shè)置為邏輯“0”時,傳輸?shù)男畔現(xiàn)G(Data byte)字節(jié)。D/C#位確定Data byte用作命令或數(shù)據(jù)。D/C#位設(shè)置為邏輯“0”時,將Data byte定義為命令。D/C#位設(shè)置為邏輯“1”時,則將Data byte定義為數(shù)據(jù)。若寫命令,Control byte=00000000b,即0x00;若寫數(shù)據(jù),Control byte=01000000b,即0x40。
EF:答IIC應(yīng)信號。
FG:命令或數(shù)據(jù),由D/C#位決定。
GH:答IIC應(yīng)信號。
HI:IIC結(jié)束信號。
注意:如需發(fā)送多個控制指令,則重復(fù)DH的操作。根據(jù)以上分析得出寫命令與寫數(shù)據(jù)函數(shù)[4]:
// 寫命令函數(shù)
void Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();? ? ? ? ? // AB:S為IIC開始信號
Write_IIC_Byte(0x78); //BC:從地址,SA0=0,R/W#=0
IIC_Ack();? ? ? ? ? ? // CD:IIC應(yīng)答信號
Write_IIC_Byte(0x00); // Co=0,D/C#=0,寫命令
IIC_Ack();? ? ? ? ? ? //EF:IIC應(yīng)答信號。
Write_IIC_Byte(IIC_Command);? // FG:命令
IIC_Ack();? ? ? ? ? ? //GH:IIC應(yīng)答信號。
IIC_Stop();? ? ? ? ? ?//HI:IIC結(jié)束信號
}
// 寫數(shù)據(jù)函數(shù)
void Write_IIC_Command(unsigned char IIC_Data)
{
IIC_Start();? ? ? ? ? // AB:S為IIC開始信號
Write_IIC_Byte(0x78); //BC:從地址,SA0=0,R/W#=0
IIC_Ack();? ? ? ? ? ? // CD:IIC應(yīng)答信號
Write_IIC_Byte(0x40); // Co=0,D/C#=1,寫數(shù)據(jù)
IIC_Ack();? ? ? ? ? ? //EF:IIC應(yīng)答信號。
Write_IIC_Byte(IIC_Data);? // FG:數(shù)據(jù)
IIC_Ack();? ? ? ? ? ?//GH:IIC應(yīng)答信號。
IIC_Stop();? ? ? ? ? ?//HI:IIC結(jié)束信號
}
3? OLED顯示分析
OLED顯示字符[5]過程分為以下三步:
1)OLED初始化。
2)寫入顯示的地址。
3)寫入顯示的內(nèi)容。
3.1? OLED初始化
OLED的初始化在模塊設(shè)計(jì)時已經(jīng)規(guī)定好,只需MCU向OLED模塊發(fā)送相關(guān)的指令即可完成,過程如下:
Write_IIC_Cmd(0xae);//關(guān)閉顯示
Write_IIC_Cmd(0x00);//設(shè)置列低地址
Write_IIC_Cmd(0x10);//設(shè)置高低地址
Write_IIC_Cmd(0x40);//設(shè)置顯示開始行
Write_IIC_Cmd(0xb0);//設(shè)置頁尋址模式頁面起始地址
Write_IIC_Cmd(0x81);//設(shè)置對比度
Write_IIC_Cmd(0xff);
Write_IIC_Cmd(0xa1);//設(shè)置段重新映射
Write_IIC_Cmd(0xa6);//設(shè)置正常顯示
Write_IIC_Cmd(0x3f);
Write_IIC_Cmd(0xc8);//設(shè)置COM輸出掃描方向
Write_IIC_Cmd(0xd3);//設(shè)置顯示偏移
Write_IIC_Cmd(0x00);
Write_IIC_Cmd(0xd5);//設(shè)置時鐘分頻比/振蕩器頻率
Write_IIC_Cmd(0xf0);
Write_IIC_Cmd(0xd9);//設(shè)置預(yù)充電周期
Write_IIC_Cmd(0x22);
Write_IIC_Cmd(0xda);//設(shè)置COM引腳硬件配置
Write_IIC_Cmd(0x02);//設(shè)置為頁尋址模式
Write_IIC_Cmd(0xdb);//設(shè)置VCOMH取消選擇級別
Write_IIC_Cmd(0x49);
Write_IIC_Cmd(0x8d);
Write_IIC_Cmd(0x14);
Write_IIC_Cmd(0xaf);//設(shè)置顯示器開
Oled_Clear();//清屏
3.2? 寫入顯示的地址
根據(jù)SSD1306顯存點(diǎn)陣特點(diǎn),若要確定OLED顯示的地址,需要通過確定尋址模式、確定第幾個PAGE、確定第幾列三個步驟[6]來完成。
SSD1306有128×64個點(diǎn),在SSD1306顯存寫入邏輯“1”就可以點(diǎn)亮對應(yīng)OLED屏幕上的點(diǎn)。但是對SSD1306顯存寫入邏輯“1”的順序是怎樣的呢?根據(jù)手冊分析SSD1306顯存寫入邏輯“1”模式有三種:頁尋址模式、水平尋址模式、垂直尋址模式,如圖5所示。
所以,三個步驟如下:
1)確定OELD的寫入模式為頁尋址模式,通過Addressing SetingCommand Table中的A[1:0]位設(shè)置完成,其中A[1:0]=00b為水平尋址模式,A[1:0]=01b為垂直尋址模式,A[1:0]=10b為頁尋址模式,如表4所示。
設(shè)置如下:
Oled_Write_Cmd(0x20);
Oled_Write_Cmd(0x02); //設(shè)置為頁尋址模式
2)確定是第幾個PAGE,通過Addressing SetingCommand Table中的B[7:0]的低3位X2 X1 X0設(shè)置完成,X2 X1 X0取000~111值,對應(yīng)為0~7頁,如表5所示。
設(shè)置如下:
Oled_Write_Cmd(0xb0+i),其中i的取值范圍為0~7,i為0時對應(yīng)的是第0頁。
3)確定0~127列中的第幾列,分別通過Addressing SetingCommand Table中的00~0F、10~1F的低4位設(shè)置完成,如表6所示。
設(shè)置如下:
Oled_Write_Cmd(0x00);// 設(shè)置8位起始列地址的低四位,列地址在每個數(shù)據(jù)接收后自加1。
Oled_Write_Cmd(0x10);// 設(shè)置8位起始列地址的高四位,列地址在每個數(shù)據(jù)接收后自加1。
3.3? 寫入數(shù)據(jù)(點(diǎn)或線)
經(jīng)過前面的準(zhǔn)備,接下來只需調(diào)用寫數(shù)據(jù)函數(shù)給OLED寫入顯示的數(shù)據(jù)即可點(diǎn)亮屏幕上對應(yīng)的像素點(diǎn)。程序如下:
Oled_Write_Data(0x00);// 0000 0000, 無顯示
Oled_Write_Data(0xff);// 1111 1111, 顯示一條線
4? 實(shí)驗(yàn)結(jié)果
程序經(jīng)過編譯后燒錄到STM32F103ZET6 [7]芯片運(yùn)行后,可見OLED屏幕顯示一條線,效果如圖6所示。如需顯示文字則通過取模軟件把文字生成代碼,再把代碼寫到OLED的顯存里即可顯示出對應(yīng)的文字了。如顯示“番”字[8],通過PCtoLCD2002軟件取模[9],如圖7所示,得到“番”代碼如下:
char zifu[2][16]={{0x20,0x20,0x22,0xA6,0x6A,0x22,0x22,0x7E,0x21,0x21,0x69,0xA5,0x21,0x20,0x20,0x00},{0x02,0x02,0x01,0xFF,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0xFF,0x01,0x02,0x02,0x00}};
由于一個漢字為2個字節(jié)[10]長度,即16位長度,而SSD1306顯存1頁才1個字節(jié)長度,即8位長度,因此需要將漢字拆成上下兩個部分,漢字上部分代碼寫入顯存的第1頁,下部分代碼寫入顯存的第2頁,從而湊成了一個完整的漢字。
程序如下:
Write_IIC_Cmd(0xb0+0);//確定第0頁
Write_IIC_Cmd(0x00);//設(shè)置列低地址
Write_IIC_Cmd(0x10);//設(shè)置列高地址
for(i=0;i<16;i++) Write_IIC_Data(zifu[0][i]);
//寫第1頁數(shù)據(jù)
Write_IIC_Cmd(0xb0+1); //確定第1頁
Write_IIC_Cmd(0x00);//設(shè)置列低地址
Write_IIC_Cmd(0x10);//設(shè)置列高地址
for(i=0;i<16;i++) Write_IIC_Data(zifu[1][i]);
//寫第2頁數(shù)據(jù),
程序編譯燒錄后系統(tǒng)運(yùn)行“番”字,顯示效果如圖8所示。其他文字、圖形與“番”字的顯示過程一樣,同樣需要通過字符取模軟件生成代碼后寫到OLED的顯存里才能顯示。
5? 結(jié)? 論
本文實(shí)現(xiàn)了OLED顯示點(diǎn)線與漢字的功能,驗(yàn)證了SSD1306時序分析的分割法、OLED顯示像素點(diǎn)三步驟的可行性,讀者可以借鑒此方法與步驟分析其他類型顯示屏的顯示原理。尚待解決的問題是沒有對OLED顯示屏的顯示坐標(biāo)位置與顯示數(shù)據(jù)的關(guān)系進(jìn)行深入分析,沒有寫出顯示坐標(biāo)位置與顯示數(shù)據(jù)的具體函數(shù)。
參考文獻(xiàn):
[1] 王紅敏,王燕,劉軍強(qiáng),等.基于Arduino控制的OLED顯示模塊的電子實(shí)踐教學(xué)研究 [J].高教學(xué)刊,2021,161(3):7-11.
[2] 任克強(qiáng),王傳強(qiáng).基于STC8F1K08S2的串口驅(qū)動OLED顯示系統(tǒng)設(shè)計(jì) [J].電子器件,2022,45(1):40-44.
[3] 張艷秋.F2812與外設(shè)之間的時序分析 [J].計(jì)測技術(shù),2017,37(S1):277-280.
[4] 劉林芳.嵌入式系統(tǒng)中C語言編程軟件設(shè)計(jì) [J].電子技術(shù)與軟件工程,2021,195(1):24-25.
[5] 蘇杰仁.字符型LCD1602顯示分析與實(shí) [J].科技資訊,2022,20(22):9-12+160.
[6] 肖文文,胡平平.OLED字符顯示和圖形繪制系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn) [J].北京信息科技大學(xué)學(xué)報(bào):自然科學(xué)版,2011,26(6):70-75.
[7] 曾一凡,楊振南,王亞勇.基于STM32的智能物料搬運(yùn)機(jī)器人的設(shè)計(jì) [J].儀器儀表用戶,2023,30(1):9-12.
[8] 趙華峰.LCD1602模塊的漢字顯示研究 [J].現(xiàn)代信息科技,2020,4(17):35-37.
[9] 王海梅.取模軟件在LED顯示屏設(shè)計(jì)中的使用與分析 [J].科技信息,2014,463(6):54.
[10] 陳一鳴.基于51單片機(jī)的圖形液晶顯示器漢字顯示方法分析 [J].自動化與儀器儀表,2011,158(6):70-71+75.
作者簡介:蘇杰仁(1981—),男,漢族,廣東肇慶人,講師,碩士研究生,主要研究方向:智能產(chǎn)品開發(fā)。
收稿日期:2023-02-06
基金項(xiàng)目:廣州市職業(yè)院校教師教學(xué)創(chuàng)新團(tuán)隊(duì)項(xiàng)目(2022JSJXCXTD001)