2010年12月1日 星期三

Nokia5110的點陣液晶,SPI實驗 (2/2)

上一篇: Nokia5110的點陣液晶,SPI實驗 (1/2) 
雖然沒有成功,不過在示波器的訊號量測後更確定,上偏結束時提的確認點.
有幾點要確認,
  • Reset LOW的時間
  • SPI傳輸與SCE還有DC相對應的波形
  • SPI的SDI與SCLK的Sampling Phase

其實都沒問題.
(圖1)



所以再回頭認真的看一下 PDC8544 資料 才發現上回因為是晚上愛睏的情況下寫的,居然在這些地方犯下這麼簡單的錯誤.不過這也告訴我們,儀器量測還是有其必要性.眼見為憑的方式讓我們可以將懷疑的點,作釐清與縮小範圍.



(圖2)

圖2 就是為了測量這些波形時,接出來的量測訊號線.
雖然目前已經成功將LCM的基本控制完成,不過對於在螢幕上顯示字母,字串的function還是不夠完善,我想後面應該再做個Font engine ,或甚至 Graphic engine.先列於此再容後續補上.

現在還是回頭講講 LCM的基本控制.
首先就6個控制訊號線(圖3):
(圖3)

  1. RST:RESET訊號, LOW的時候RESET(PIO3_0), 最短LOW的時間要100ns. 還有就是也有列出電源供應後到reset之間最長不能超過30ms
  2. SCE: SPI Select 訊號,Low時表示SDIN與SCLK上的資料是要給這個LCM
  3. DC:Data與Command之分,High表示Data,Low表示Command
  4. SDIN:Data與Command訊號,接至MCU端SPI的MOSI
  5. SCLK :SPI Clock,Rising edge的時候取樣SDIN上訊號.(6.1.8      SCLK: SERIAL CLOCK LINE Input for the clock signal: 0.0 to 4.0 Mbits/s.)
  6. LIGHT:背光控制,LOW為亮,High則關閉背光
基本上,上述的控制訊號比較會有問題的大概是在屬於SPI的訊號上(SCE,SDIN,SCLK),確定5.點中敘述的重點為取樣點以及SCLK的最快限制,大致上就沒有太大問題.

接下來換看看PCD8544中的Command table (表1) 故意放大點比較能見表中的字.

(表1)
扣除保留的命令後,又WRITE DATA也不算command,所以剩下7個command.

在 lcm_pcd8544.h中,


#define _CMD_FUNCTION_SET_ 0x20
#define _MASK_FUNCTION_SET_ 0x07

#define _CMD_DISPLAY_CONTROL_ 0x08
#define _MASK_DISPLAY_CONTROL_ 0x05

#define _CMD_SET_Y_ADDR_ 0x40
#define _MASK_SET_Y_ADDR_ 0x07

#define _CMD_SET_X_ADDR_ 0x80
#define _MASK_SET_X_ADDR_ 0x7f

#define _CMD_TEMP_CONTROL_ 0x04
#define _MASK_TEMP_CONTROL_ 0x03

#define _CMD_BIAS_SYSTEM_ 0x10
#define _MASK_BIAS_SYSTEM_ 0x07

#define _CMD_SET_Vop_ 0x80
#define _MASK__SET_Vop_ 0x7f


_MASK_XXXXXX 為該資料有效位址的遮蔽位元
完成以下巨集之後,將來若要下某命令的值,就寫下CMD_XXXX(0xXX),就會自動過濾避免誤算數值.(其實這就是第一次點錯的原因,想睡覺所以算錯16進制 XD )

#define CMD_FUNSET(A) (_CMD_FUNCTION_SET_|(_MASK_FUNCTION_SET_&A))
#define CMD_DISPCON(A) (_CMD_DISPLAY_CONTROL_|(_MASK_DISPLAY_CONTROL_&A))
#define CMD_SETADR_Y(A) (_CMD_SET_Y_ADDR_|(_MASK_SET_Y_ADDR_&A))
#define CMD_SETADR_X(A) (_CMD_SET_X_ADDR_|(_MASK_SET_X_ADDR_&A))
#define CMD_TEMPCON(A) (_CMD_TEMP_CONTROL_|(_MASK_TEMP_CONTROL_&A))
#define CMD_BIASSYS(A) (_CMD_BIAS_SYSTEM_|(_MASK_BIAS_SYSTEM_&A))
#define CMD_SETVop(A) (_CMD_SET_Vop_|(_MASK__SET_Vop_&A))


 (表2)
表2為 Commad 中的控制位元解釋,請參考下表 初始值
在lcm_pcd8544.c中,


#define INIT_BYTES 6
uint8_t init_command[INIT_BYTES]={
CMD_FUNSET(0x01),
CMD_SETVop(0x04),
CMD_FUNSET(0x00),
CMD_DISPCON(0x04),
CMD_SETADR_Y(0),
CMD_SETADR_X(0),
};

是參考資料中 13 APPLICATION INFORMATION
Table 6 Programming example 所得再做修改 Vop 以及定位在(X,Y)=(0,0) 的位址.

(圖4)

圖4,簡單的說明, X,Y 位置對應螢幕的關係位置,另外透露的就是DATA BYTE中的BIT對應 LCD上pixel的關係.

(圖5)
所以對應到圖5的 A 這個字來說,我就需要拆解成4個BYTE 如下:


uint8_t font_raw_A[]={/*A*/ 0x1e,0x09,0x09,0x1e,0x00};



最後一個BYTE 0x00為空白所留.

最後集合 LCM 初始化動作 在 void pcd8544_init(void) 中,


void pcd8544_init(void)
{
/*initiate gpio for lcm*/
lcm_init_gpio();

/*reset low active*/
pcd8544_reset();

/* initialize SSP port*/
SSPInit();

/* clear RAM*/
pcd8544_clearRam();

/*initiate register*/
pcd8544_write_data_command(TYPE_COMMAND, INIT_BYTES, (uint8_t *)init_command);

/*display test*/
pcd8544_test();

}


依序步驟為:
  1. 初始化IO,包含 RST,SCE,DC,SDIN,SCLK,LIGHT 這六個訊號線
  2. reset 訊號 low reset LCM
  3. 初始化LPC1114 SPI 介面相關暫存器
  4. 清除PCD8544中的RAM,將全部寫入0x00
  5. 將table  init_command 寫入PCD8544中
  6. 顯示測試,圖1 中的這些字就是在這個測試函式中完成
以上是不是很簡單?

因為這款LCM是dot matrix ,沒有內建 font ram ,因此字的顯示需要將它當作是畫圖般控制.
如前面所說的,將來會再多個font engine來將這個project 達到較完整的階段.

參考範例請至此下載  Download


0 留言:

張貼留言

Related Posts Plugin for WordPress, Blogger...