以我在公司項目移植ILI9327DS為例:
移植時,我拿到的文檔包括廠商提供的代碼僅提供Init代碼和一個datasheet文檔。mtk寫代碼時最重要的一點就是進行宏控制。
1.定義宏 LCD_ILI9327DS_ACTIVE
定義位置可以lcd.c ,lcd_sw.h或者按照定義模塊。在在客戶定制里邊定義(在這個位置定義需要new)
#define LCD_ILI9327DS_ACTIVE
客戶定制:
COMTOM_OPTION += LCD_ILI9327DS_ACTIVE
2。在lcd.c加入ILI9327DS的相關函數
重點是Init ,這個部分參考廠商代碼。
3。 查看datasheet里邊會有進入或者退出休眠模式的說明。
Enter_sleep_mode(10h) Exit_sleep_mode (11h)
函數書寫void LCD_Enter_Sleep_ILI9327DS(void)
{
LCD_CtrlWrite_ILI9327DS(0x10);//這個函數在lcd_sw.h中定義
}
說明:關於LCD_CtrlWrite_ILI9327DS的書寫需要知道,總線的工作方式和液晶的工作方式這里都是采用了8位傳輸。
#define LCD_CtrlWtire_ILI9327DS(_data){\
SET_LCD_CMD_PARAMETER(0,LCD_CMD,(_data & 0xFF));\
LCD_SEND_DMA_CMD(1);\
}
void LCD_Exit_Sleep_ILI9327DS(void)
{
//可以采用兩用方法一種是采用datasheet 中的退出命令另一種就是重新初始化一遍
//1
LCD_CtrlWtire_ILI9327DS(0x11);
// LCD_Init_ILI9327DS(0,0);
}
4.塊寫函數BlockWrite書寫。
往屏輸出數據的函數。我們在LCM上看到的各種繽紛圖像,都是通過這個函數來實現的。在這個函數里面我們要設置LCD屏幕顯示的一些位置參數,並把它寫道相應的寄存器里面。
看datasheet時,提供兩個命令2ah和2bh,分為是Set_column_address和Set_page_address.他們分別有四個參數。
上圖解釋(startx&0x100)>>8;
void LCD_Block_Write_ILI9327DS(kal_uint16 startx,kal_uint16 starty,kal_uint16 endx,kal_uint16 endy)
{
while (LCD_IS_RUNNING);//LCD_ISRUNING由lcd狀態寄存器和 lcd運行狀態位決定
{
unsigned int i,j,tmp1,tmp2;
if(endx> ( LCD_WIDTH -1 ) )
endx= (LCD_WIDTH -1);
if(endy > ( LCD_HEIGHT - 1 ))
endy = ( LCD_HEIGHT - 1 );
SET_LCD_CMD_PARAMETER(0,LCD_CMD,0x2A);
SET_LCD_CMD_PARAMETER(1,LCD_DATA,((startx&0x100)>>8));
SET_LCD_CMD_PARAMETER(2,LCD_DATA,(startx&0x0FF));
SET_LCD_CMD_PARAMETER(3,LCD_DATA,((endx&0x100)>>8));
SET_LCD_CMD_PARAMETER(4,LCD_DATA,(endx&0x0FF));
SET_LCD_CMD_PARAMETER(5,LCD_CMD,0x2B);
SET_LCD_CMD_PARAMETER(6,LCD_DATA,((starty&0x100)>>8));
SET_LCD_CMD_PARAMETER(7,LCD_DATA,(starty&0x0FF));
SET_LCD_CMD_PARAMETER(8,LCD_DATA,((endy&0x100)>>8));
SET_LCD_CMD_PARAMETER(9,LCD_DATA,(endy&0x0FF));
//Write_memory_start;
SET_LCD_CMD_PARAMETER(10,LCD_CMD,0x2c);
SET_LCD_ROI_CTRL_NUMBER_OF_CMD(11);
}
ENABLE_LCD_TRANSFER_COMPLETE_INT;
ENABLE_LCD_ROI_CTRL_CMD_FIRST;
while (LCD_IS_RUNNING) {};
START_LCD_TRANSFER;
}
//
LCD_Funcs LCD_func_ILI9327DS = {
LCD_Init_ILI9327DS,
LCD_PWRON_ILI9327DS,
LCD_SetContrast_ILI9327DS,
LCD_ON_ILI9327DS,
LCD_BlockWrite_ILI9327DS,
LCD_Size_ILI9327DS,
LCD_EnterSleep_ILI9327DS,
LCD_ExitSleep_ILI9327DS,
LCD_Partial_On_ILI9327DS,
LCD_Partial_Off_ILI9327DS,
LCD_Partial_line_ILI9327DS,
/*Engineering mode*/
LCD_GetParm_ILI9327DS,
LCD_SetBias_ILI9327DS,
LCD_Contrast_ILI9327DS,
LCD_LineRate_ILI9327DS,
LCD_Temp_Compensate_ILI9327DS
#ifdef LCM_ROTATE_SUPPORT
,LCD_Set_Scan_Direction_ILI9327DS
#endif
#ifdef LQT_SUPPORT/*Do not remove LQT code segment*/
,LCD_gamma_test
,LCD_flicker_test
#endif
,0 // NULL function for SetFrmMarker Function.
,LCD_IOCTRL_ILI9327DS
};
上述是ILI9327DS需要的成員函數,里邊多數為不做操作的。
5。搞定后就是Lcd _id了。datasheet給我們的命令式EFh,它有六個屬性第四位和第五位是lcd_id為0x9327;
有兩種方法一種直接送值,另外一種是自適應的方法。編寫方法讀取reg.
void read_lcd_device_code(void)
{
unsigned short value=0;
#ifdef LCD_ILI9327DS_ACTIVE
value =0x9325;
#endif
switch(value)
{
#ifdef LCD_ILI9327DS_ACTIVE
case 0x9327:
MainLCD =& LCD_func_ILI9327DS;
break;
#endif
}
}
///自適應
void read_lcd_device_code(void)
{
unsigned value=0,value1=0;
#ifdef LCD_ILI9327DS_ACTIVE
LCD_CtrlWrite_ILI9327DS(0xef);//讀取lcd ID/
value1 = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
value1 = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
value1 = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
value = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR) <<8;
value |= (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);value1 = (*(volatile kal_uint8 *)MAIN_LCD_DATA_ADDR);
#endif
switch(value)
{
#ifdef LCD_ILI9327DS_ACTIVE
case 0x9327:
MainLCD =& LCD_func_ILI9327DS;
break;
#endif
}
}
new之后慢慢調試出現的錯誤。
2010-7-27
結束//
來南京第四周了,各方面依然過得還行。和我一塊住的麗姐和魏大哥,操飛以及他老婆都是非常好相處的人。每天麗姐都為我們住的屋子打掃一下啊,使得我們住的非常舒心。雖然離開了上海,但還是和在上海的兄弟們有聯系,大家一起進步吧。要感謝優思給了我可以去優思實習的機會,令我能夠在畢業后迅速找到一份工作。當然另一個人是一定要感謝的那就是學院的李文華老師。O(∩_∩)O~