


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