oled顯示屏本質(zhì)上就是一些微小的發(fā)光管的集合,它的顯示原理和led排燈一 樣,給1就亮,給0就滅,oled自帶顯存來存儲這些值的集合。 值的注意的是,它是實時的,你往顯存里面寫1,那么對應(yīng)位置會立刻變化,很多人以為,oled的顯示是先往顯存里面寫數(shù)據(jù),寫完一塊數(shù)據(jù)更新一塊顯示,其實不是這樣的,oled和led排燈類似就是為了體現(xiàn)它是實時的這一特點,立刻在屏幕上面體現(xiàn)顯存里面的內(nèi)容。
如果是一塊stm32在控制oled顯示,通常的做法是在32里面開辟一塊內(nèi)存來存儲oled顯存里面的數(shù)據(jù),這樣做的好處是修改都是在32這一端修改,可以極大的提升速度,避免了從oled的顯存里面讀取數(shù)據(jù)這一過程。以12864oled舉例,可以在stm32里面開辟一塊oled[128][8]這樣的內(nèi)存來存儲顯存數(shù)據(jù)。
分割線。上面是為了說明我曾經(jīng)犯的一個錯誤,誤以為oled的顯示不是實時的,曾經(jīng)以為oled是根據(jù)頁來刷新顯示,每次需要等一頁的數(shù)據(jù)都刷新完畢,不管數(shù)據(jù)是否發(fā)生變化,才會刷新顯示。
一、通過顯示緩存刷新oled
1 開辟內(nèi)存空間,模擬oled顯存
2 將內(nèi)從空間里面的數(shù)據(jù)修改成所需要的顯示數(shù)據(jù)
3 將內(nèi)存空間的數(shù)據(jù)寫入顯存
//OLED的顯存
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
uint16_t OLED_GRAM[128][8];
//更新顯存到LCD
void OLED_Refresh_Gram(void)
{
uint8_t i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //設(shè)置頁地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //設(shè)置顯示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //設(shè)置顯示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
}
}
二、直接寫數(shù)據(jù)到oled
直接是通過寫數(shù)據(jù)函數(shù)寫入oled
//顯示16*16漢字
void OLED_ShowCHinese(unsigned char x , unsigned char y , unsigned char no)
{
unsigned char t,adder=0;
oled_set_pos(x,y);
for(t = 0 ;t < 16; t++)
{
OLED_WriteData(Hzk[2 * no][t]);
adder += 1;
}
oled_set_pos(x , y + 1);
for(t = 0 ; t < 16; t++)
{
OLED_WriteData(Hzk[2*no+1][t]);
adder += 1;
}
}
再看下通訊方式的數(shù)據(jù)快慢
一般IIC總線速度為400kbps,假設(shè)咱們的IIC通訊已經(jīng)是最快了達到了這個速度,不考慮開啟總線、應(yīng)答信號和結(jié)束總線的時間開銷,大約折算為50kByte/s,而對于128*64的OLED屏來說,完整描述一個屏需要128*64/8=1024個字節(jié),咱們再退一步,不考慮發(fā)送器件地址、發(fā)送寄存器地址的開銷,那么一秒鐘可以傳送50k/1024≈49幀完整畫面,也就相當于,全屏刷新需要20ms左右。
實際上由于其他很多協(xié)議的開銷,也就出現(xiàn)了20多ms一幀的情況。解決這個問題的根本辦法,是換用SPI方式通信,一般SPI總線通訊速率可以到20Mbps,是IIC的50倍。如果還嫌慢,可以直接用8080并行總線方式(但是不確定OLED本身能否反應(yīng)過來那么快的數(shù)據(jù)速率)。
簡而言之,如果一屏我只需要更改一個數(shù)字的顯示,那么我完全沒有必要對整個屏幕刷屏,我只需要修改要修改的數(shù)字的顯示區(qū)域的像素就可以了。然而無論IIC SPI 還是8080,都是以一個字節(jié)為基本單位傳輸?shù)模虼水孅c的時候就可能出現(xiàn)把原先不要修改的點給覆蓋了這樣的情況。