7、OLED實驗、8080、SPI

1、學習 SSD1306 型OLED的使用,區別8088與080 接口以及 4 線 SPI接口的寫數據與命令的區別。

2、8080 並行接口的發明者是 INTEL,該總線也被廣泛應用於各類液晶顯示器,ALIENTEK OLED 模塊也提供了這種接口,使得 MCU 可以快速的訪問 OLED。ALIENTEK

 OLED 模塊的 8080 接口方式需要如下一些信號線:

CS:OLED 片選信號。

WR:向 OLED 寫入數據。

RD:從 OLED 讀取數據。

D[7:0]:8 位雙向數據線。

RST(RES):硬復位 OLED。

DC:命令/數據標誌(0,讀寫命令;1,讀寫數據)。

模塊的 8080 並口讀/寫的過程爲:先根據要寫入/讀取的數據的類型,設置 DC 爲高(數據)/低(命令),然後拉低片選,選中 SSD1306,接着我們根據是讀數據,還是要寫

數據置 RD/WR

爲低,然後:

在 RD 的上升沿,  使數據鎖存到數據線(D[7:0])上; 

在 WR 的上升沿,使數據寫入到 SSD1306 裏面;

SSD1306 的 8080 並口寫時序圖如圖:


實現代碼爲:

//向SSD1306寫入一個字節。
//dat:要寫入的數據/命令
//cmd:數據/命令標誌 0,表示命令;1,表示數據;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
DATAOUT(dat);    
  OLED_RS=cmd;
OLED_CS=0;   
OLED_WR=0;  
OLED_WR=1;
OLED_CS=1;  
OLED_RS=1;  
}      

SPI 模式:

SPI的通信原理很簡單,它以主從方式工作,這種模式通常有一個主設備和一個或多個從設備,需要至少4根線,事實上3根也可以(單向傳輸時)。也是所有基於SPI的設備共有的,它們是SDI(數據輸入)、SDO(數據輸出)、SCLK(時鐘)、CS(片選)。

(1)SDO – 主設備數據輸出,從設備數據輸入;

(2)SDI – 主設備數據輸入,從設備數據輸出;

(3)SCLK – 時鐘信號,由主設備產生;

(4)CS – 從設備使能信號,由主設備控制。

其中,CS是控制芯片是否被選中的,也就是說只有片選信號爲預先規定的使能信號時(高電位或低電位),對此芯片的操作纔有效。這就允許在同一總線上連接多個SPI設備成爲可能。

其數據寫入方式:


實現代碼:基本思路是在8個時鐘週期內,將數據的最高位與0x80進行比較,如果爲真,寄存器將記錄下數值。

//向SSD1306寫入一個字節。
//dat:要寫入的數據/命令
//cmd:數據/命令標誌 0,表示命令;1,表示數據;
void OLED_WR_Byte(u8 dat,u8 cmd)
{
u8 i;  
OLED_RS=cmd; //寫命令 
OLED_CS=0;  
for(i=0;i<8;i++)
{  
OLED_SCLK=0;
if(dat&0x80)OLED_SDIN=1;
else OLED_SDIN=0;
OLED_SCLK=1;
dat<<=1;   //將數據進行左移動,方便之後的數值採集(移動到最高位)
}  
OLED_CS=1;  
OLED_RS=1;    

3、字符集點陣的製作,可以參考以下鏈接:

http://blog.csdn.net/exbob/article/details/6532772

http://wenku.baidu.com/link?url=F6tJTZcH6AYxGOaX_-YqFx0-OsPmUd7zxPTZRGiVK0AwHxrtAvX0I11dDP6zMKOqDlAjC2GxnmdKx6i7v-lBf94kvA0H2mXrsQQCidYT-JS

同時我們可以用以下的代碼實現字符點陣的顯示,思路就是首先判斷字體一個字符對應點陣集所需要佔的字節數,然後在確定所要顯示的字符與空格符的相差數值,因爲我們所

編寫的字符點陣是從空格符開始,兩者相減得到的數值就是該字符在字符點陣中的行數。一個字節又有8個位,我們在每一個字節數中都對每一位進行一次判斷,(通過數據

的左移,最高位與0x80進行與運算)。

//在指定位置顯示一個字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白顯示;1,正常顯示  
//size:選擇字體 16/12 
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
{          
u8 temp,t,t1;
u8 y0=y;
u8 csize=(size/8+((size%8)?1:0))*(size/2);//得到字體一個字符對應點陣集所佔的字節數
chr=chr-' ';//得到偏移後的值 
    for(t=0;t<csize;t++)
    {   
if(size==12)temp=asc2_1206[chr][t]; //調用1206字體
else if(size==16)temp=asc2_1608[chr][t];//調用1608字體
else if(size==24)temp=asc2_2412[chr][t];//調用2412字體
else return; //沒有的字庫
        for(t1=0;t1<8;t1++)
{
if(temp&0x80)OLED_DrawPoint(x,y,mode);
else OLED_DrawPoint(x,y,!mode);
temp<<=1;
y++;

                        //用於判斷是否要換到另一列

if((y-y0)==size)
{
y=y0;
x++;
break;
}
}    
    }          
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章