寫在前面:
本文章旨在總結備份、友善以後查詢,由于是個人總結,如有不對,歡迎指正;另外,内容大部分來自網絡、書籍、和各類手冊,如若侵權請告知,馬上删帖緻歉。
先看一下官方手冊上給出的驅動流程:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLwcGRNl3aU9UeRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLwUDNyMTN0EjM4ATNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
然後下面是個人用的驅動流程:
void OLED_Init(void)
{
OLED_Config();
OLED_SCK(HIGH); // 空閑态時,SCLK處于高電平
OLED_CS(HIGH); // 關閉選擇輸入
/* 從上電到下面開始初始化要有足夠的時間,即等待 RC複位完畢 */
OLED_RST(LOW); // 複位(低電平有效)
OLED_Delay_ms(100);
OLED_RST(HIGH);
OLED_Delay_ms(30);
OLED_Write_Cmd(0xAE); // 關閉OLED -- turn off oled panel
OLED_Write_Cmd(0xD5); // 設定顯示時鐘分頻因子/振蕩器頻率 -- set display clock divide ratio/oscillator frequency
OLED_Write_Cmd(0x80); // \ set divide ratio, Set Clock as 100 Frames/Sec
OLED_Write_Cmd(0x20); // 設定記憶體尋址模式 -- Set Memory Addressing Mode (0x00 / 0x01 / 0x02)
OLED_Write_Cmd(0x02); // \ Page Addressing
OLED_Write_Cmd(0xA8); // 設定多路傳輸比率 -- set multiplex ratio (16 to 63)
OLED_Write_Cmd(0x3F); // \ 1 / 64 duty
OLED_Write_Cmd(0xDA); // 設定列引腳硬體配置 -- set com pins hardware configuration
OLED_Write_Cmd(0x12); // \ Sequential COM pin configuration,Enable COM Left/Right remap
/* ----- 方向顯示配置 ----- */
OLED_Write_Cmd(0xA1); // 設定段重映射 -- Set SEG / Column Mapping 0xA0左右反置(複位值) 0xA1正常(重映射值)
OLED_Write_Cmd(0xC8); // 設定行輸出掃描方向 -- Set COM / Row Scan Direction 0xc0上下反置(複位值) 0xC8正常(重映射值)
/* ----- END ----- */
OLED_Write_Cmd(0x40); // 設定設定螢幕(GDDRAM)起始行 -- Set Display Start Line (0x40~0x7F)
OLED_Write_Cmd(0xD3); // 設定顯示偏移 -- set display offset (0x00~0x3F)
OLED_Write_Cmd(0x00); // \ not offset
OLED_Write_Cmd(0x81); // 設定對比度 -- set contrast control register (0x00~0x100)
OLED_Write_Cmd(0xCF); // \ Set SEG Output Current Brightness
OLED_Write_Cmd(0xD9); // 設定預充電期間的持續時間 -- set pre-charge period
OLED_Write_Cmd(0xF1); // \ Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_Write_Cmd(0xDB); // 調整VCOMH調節器的輸出 -- set vcomh (0x00 / 0x20 / 0x30)
OLED_Write_Cmd(0x20); // \ Set VCOM Deselect Level
OLED_Write_Cmd(0x8D); // 電荷泵設定 -- set Charge Pump enable / disable (0x14 / 0x10)
OLED_Write_Cmd(0x14); // \ Enable charge pump during display on
OLED_Write_Cmd(0xA4); // 全局顯示開啟(黑屏/亮屏) -- Entire Display On (0xA4 / 0xA5)
OLED_Write_Cmd(0xA6); // 設定顯示方式(正常/反顯) -- set normal display (0xA6 / 0xA7)
OLED_Write_Cmd(0xAF); // 打開OLED -- turn on oled panel
OLED_Fill(0x00); // 初始清屏
OLED_Coord(0,0); // 設定原點坐标(0, 0)
}
一、 圖形顯示資料RAM (GDDRAM)
先來認識一下圖形是怎樣顯示的
圖一:
如上面圖一所示:RAM分為8頁,從PAGE0到PAGE7;列位址有128個,從SEG0到SEG127。
每一頁裡面有八位資料(bits),資料書寫為從低位LSB到高位MSB,如下面圖二所示:
圖二:
然後,在上面流程裡面有:
/* ----- 方向顯示配置 ----- */
OLED_Write_Cmd(0xA1); // 設定段重映射 -- Set SEG / Column Mapping 0xA0左右反置(複位值) 0xA1正常(重映射值)
OLED_Write_Cmd(0xC8); // 設定行輸出掃描方向 -- Set COM / Row Scan Direction 0xc0上下反置(複位值) 0xC8正常(重映射值)
/* ----- END ----- */
這兩個書寫指令,第一個對應的是段重映射(左右反置),第二個對應的是列輸出掃描(上下反置),掃描方式如圖一綠色所示(映射值),黑色的為正常(複位值),對應的指令具體解釋請往下慢慢看
二、 指令表
Ⅰ、 基本指令簡介
Ⅱ、 應用指令詳解
1、位址設定指令
(1)頁位址模式下設定列起始位址低位(Set Lower Column Start Address For Page Addressing Mode)(00h~0Fh)
此指令用于在頁位址模式下設定GDDRAM的列起始位址(8位)的低4位, 每一次資料通路都會增加列位址。
(2)頁位址模式下設定列起始位址高位(Set Higher Column Start Address For Page Addressing Mode)(10h~1Fh)
此指令用于在頁位址模式下設定GDDRAM的列起始位址(8位)的高4位, 每一次資料通路都會增加列位址。
(3)設定記憶體位址模式(Set Memory Addressing Mode)(20h)
SSD1306中有3種不同的記憶體尋址模式:頁尋址模式、水準尋址模式和垂直尋址模式。此指令将記憶體尋址方式設定為上述三種模式之一。其中,“COL”表示GDDRAM列(column)
頁位址模式(A[1:0]=10b)
當處于此模式時, 在GDDRAM通路後(讀/寫), 列位址指針将自動增加1。如果列位址指針到達列終止位址, 列位址指針将複位到列起始位址, 但頁位址指針不會改變。
為了通路GDDRAM中下一頁的内容, 使用者必須設定新的頁位址和列位址。頁位址模式下頁以及列位址指針的行為如下圖所示
通常在頁位址模式下通路GDDRAM, 需要如下步驟來定義起始RAM通路指針指向:
-通過指令(B0h-B7h)設定目标顯示位置頁起始位址
-通過指令(00h-0Fh)設定列起始位址低位
-通過指令(10h-1Fh)設定列起始位址高位
例如, 如果頁位址是B2h, 列位址低位是03h, 列位址高位是10h, 則表示起始列為PAGE2的SEG3, GDDRAM通路指針的指向如下圖所示
水準位址模式(A[1:0]=00b)
當處于此模式時, 在GDDRAM通路後(讀/寫), 列位址指針将自動增加1。如果列位址指針到達列終止位址, 列位址指針将複位到列起始位址, 且頁位址指針将自動增加1。
水準位址模式下頁以及列位址指針的行為如下圖所示, 如果列位址指針和頁位址指針都到達各自的終止位址時, 他們将被重置為列開始位址和頁開始位址。(圖中虛線)
垂直位址模式(A[1:0]=01b)
當處于此模式時, 在GDDRAM通路後(讀/寫), 頁位址指針将自動增加1。如果頁位址指針到達頁終止位址, 頁位址指針将複位到頁起始位址, 且列位址指針将自動增加1。
垂直位址模式下頁以及列位址指針的行為如下圖所示, 如果列位址指針和頁位址指針都到達各自的終止位址時, 他們将被重置為列開始位址和頁開始位址。(圖中虛線)
通常在GDDRAM讀寫和水準/垂直尋址模式下,定義RAM通路指針位置需要以下步驟::
-通過指令(21h)設定目标顯示位置列起始位址以及列終止位址
-通過指令(22h)設定目标顯示位置頁起始位址以及頁終止位址
(4)設定列位址(Set Column Address)(21h)
此指令用于設定GDDRAM的列起始位址和列結束位址, 并使列位址指針(指向GDDRAM中目前通路的列位址)指向列起始位址。
若記憶體位址模式為水準位址模式, 在通路一列資料後, 列位址指針将增加到下一個列位址。當結束通路終止列位址時, 列位址指針将複位至列起始位址, 且行位址指針将增加到下一行。
(5)設定頁位址(Set Page Address)(22h)
此指令用于設定GDDRAM的頁起始位址和頁結束位址, 并使頁位址指針(指向GDDRAM中目前通路的頁位址)指向頁起始位址。
若記憶體位址模式為垂直位址模式, 在通路一頁資料後, 頁位址指針将增加到下一個頁位址。當結束通路終止頁位址時, 頁位址指針将複位至頁起始位址。
下圖展示了例子中列位址指針和頁位址指針的移動方式: 列起始位址設為2, 列終止位址設為125, 頁起始位址設為1, 頁終止位址設為6, 并使用水準位址模式。
在此情況下, GDDRAM資料可通路範圍是從第2列到第125列,僅從第1頁到第6頁。同時列位址指針被設為2, 頁位址指針被設為1。在通路資料後, 列位址自動增加1, 以通路下一個RAM位置進行下一次讀取/寫入操作(圖中實線)
每當列位址指針通路完結束列位址(125)時, 列位址指針複位到列2, 頁位址指針自動增加1(圖中實線), 當通路終止頁位址6和終止列位址125所在資料後, 頁位址指針複位到1, 列位址指針複位到2(圖中虛線)
2、圖形加速指令
(1)水準滾動配置(Horizontal Scroll Setup)(26h/27h)
此指令用于配置水準滾動參數和确定滾動起始頁、終止頁和滾動速度
在發出此指令之前,必須禁用水準滾動條(2Eh)。否則,RAM内容可能被破壞。
SSD1306的水準滾動設計為128列滾動, 以下是使用水準滾動的例子:
向右滾動一列
向左滾動一列
水準滾動配置例子
(2)連續垂直和水準滾動配置(Continuos Vertical and Horizontal Scroll Setup)(29h/2Ah)
此指令用于設定連續的垂直滾動參數,并确定滾動的起始頁、結束頁、滾動速度和垂直滾動偏移量。
指令29h/2Ah的位元組B[2:0]、C[2:0]和D[2:0]用于設定連續水準滾動。位元組E[5:0]用于設定連續垂直滾動偏移量。所有這些位元組一起用于設定連續對角滾動(水準+垂直)。如果垂直滾動偏移位元組E[5:0]設定為0,則隻執行水準滾動(和指令26/27h一樣)
同樣,在發出此指令之前,必須禁用水準滾動條(2Eh)。否則,RAM内容可能被破壞。
以下是使用垂直和水準滾動的例子:
(3)禁用滾動(Deactivate Scroll)(2Eh)
此指令用于停止滾動,發送2Eh指令以禁用滾動操作後,需要重寫ram資料。
(4)啟用滾動(Activate Scroll)(2Fh)
此指令用于啟動滾動, 并且隻有在滾動設定指令定義滾動設定參數後才應發出:26h/27h/29h/2Ah。最後調用滾動參數指令的配置将覆寫之前調用過滾動參數指令的配置
在激活滾動之後,禁止執行以下操作
①對RAM的通路
②改變水準滾動配置參數
(5)設定垂直滾動區(Set Vertical Scroll Area)(A3h)
此指令用于設定垂直滾動區, 對于垂直滾動功能(29/2Ah), 垂直滾動的行數可以大于或小于多路傳輸比率(MUX ratio)
附:OLED12864驅動程式