在嵌入式的主流 LCD屏中主要支持兩大類的硬件接口,一種是常見的RGB接口,另外一種是MCU接口.后面因為最早是針對單片機的領域在使用,因此得名.后在中低端手機大量使用,其主要特點是價格便宜的.
MCU-LCD接口的標準術語是Interface 80,因此在很多文檔中用I80 來指MCU-LCD屏。
MCU-LCD屏它與RGB-LCD屏主要區別在于顯存的位置.RGB-LCD的顯存是由系統內存充當的,因此其大小只受限于系統內存的大小,這樣 RGB-LCD可以做出較大尺寸,象現在4.3"只能算入門級,而MID中7",10"的屏都開始大量使用.而MCU-LCD的設計之初只要考慮單片機的 內存較小,因此都是把顯存內置在LCD模塊內部.然后軟件通過專門顯示命令來更新顯存,因此MCU屏往往不能做得很大.同時顯示更新速度也比RGB- LCD慢.
量示數據傳輸模式也有差別。
????? RGB屏只需顯存組織好數據。啟動顯示后。LCD-DMA會自動把顯存通過RGB接口送到LCM。
???? 而MCU屏則需要發送畫點的命令來修改MCU內部RAM。(即不能直接MCU屏RAM)
所以RGB顯示速度明顯比MCU快,而且播放視頻方面,MCU-LCD也比較慢.
?
S3C6410 即支持RGB-LCD屏,也支持MCU-LCD屏.而對MCU-LCD屏的顯示模塊的顯存顯示,它除了支持傳統的繪制命令,也支持一種特有的類似RGB- LCD屏的顯示模式。即顯示數據仍然在系統內存中組織,顯示時通過DMA傳輸到顯示器控制器,由硬件來產生繪制命令。相對純軟件繪制模式,這種方法速度更 快。
MCU-LCD管腳分析
---------------------------------------------------------------------
兩種屏通過管腳直接就可以看出來的。RGB屏管腳主要分為兩類
控制腳是VSYNC/HSYNC/VDEN/VCLK S3C6410最高支持24個數據腳,數據腳是 VD[23-0];
MCU接口標準名稱是 I80 Interface.
MCU管腳的控制腳有5個
- CS 片選信號
- ?RS (置1為寫數據,置0為寫命令)
- /WR (為0表示寫數據)
- /RD (為0表示讀數據)
- RESET 復位LCD( 用固定命令系列 0 1 0來復位)
數據腳一般是18個,即DB[17:0],這樣表示大部MCU最高支持18bpp
?
S3C6410 I80管腳
S3C6410采用非標準命令,因此有如下對應關系,控制腳
- SYS_CSx 對應CS
- SYS_OE 對應RD
- SYS_WE對應WR
- SYS_RS對應RS
- 這里沒有對應RESET,直接采用某一個IO口來代替。
?在mini6410中 這里采用VD[21]即GPJ5來充當RESET腳
- 數據腳 輸出VDOUT[17:0],與RGB管腳不一樣的是,MCU-LCD還帶有 VDIN[17:0],即顯存中的數據可以通過命令讀取出來。
?
mini6410 LCM接口
?? 我們測試是采用學生公司的MCU LCM,愛諾信2.8"的mcu屏。因為接口不是完全兼容,因此只能用采用復雜連線板來匹配。開發板使用的是mini6410。
??
注意這里RGB-LCD和I80接口是復用的。一塊S3C6410同時支持兩個LCD,mini6410用排線引出來LCD,這里我們把原來的4.3 "LCD的取下,然后再用自制排線接上。
這個LCM按其管腳要求配置成 16bpp(565)。這是LCM一側的跳線配置。
??相應的,在S3C6410一側使用VD[0-15]
?
因此在S3C6410 一側,采用VD[0-15]來與其對接
I80 硬件連線
??mini6410板上,我們這樣進行連線。
-
- RESET : 這里使用VD[21]來當RESET線,即 GPJ5的output腳.
- CS0:????這里復用了HSYNC信號腳,即使用GPJ8
- OE:??? 在引腳上懸空,即始終為高,這樣不影響結果。
- WE:??? 復用了VCLK信號腳,即采用?GPJ11腳
- RS???? 復用了VDEN信號腳,即采用?GPJ10腳
?
I80 硬件波形分析
---------------------------------------------------------
?啟動波形
? 根據I80的要求,每次如果需要RESET LCD屏,需要用軟件發送 101序列。
? 這是MCU-LCD IC里的RESET波形圖
這里我們實測LCD屏的啟動波形
??MCU-LCD初始化屏幕,一般出現如下畫面表示硬件連線正確,并且初始化成功.
寫入波形
? 在MCU-LCD中,用RS腳來區別是向MCU屏發送命令還是數據。而且通常每一種MCU屏有一組初始化命令,它具體的序列取決了不同硬件,所以不同型號的MCU-LCD屏初始化命令序列是不一樣的,這個要由生產廠家來提供。
參考S3C6410提供的I80標準波形,在寫入時,WE必須是低電平,RS取決于寫入命令還數據。CS是片選有效,是低電平有效。
以下是LCM模塊提供寫命令時序圖,基本跟S3C6410的波形一致。
以下波形是實測MCU-LCD波形,可以看到比較明顯在,在MCU-LCD初始化時,CS腳被頻繁的置低有效。這是在發送一系列的初始化命令,然后隨后一直為高,表示在發送顯示數據。
這是放大后波形
S3C6410 MCU-LCD編程 -----------------------------------------------------------------------------
MCU需要專門的繪點函數修改LCM內部RAM。。在S3C6410我們有兩種方法來繪制MCU-LCD,一種是通用通用方法,在單片機以32位CPU都可以使用。另外一種是S3C6410的擴展,稱為I80 RGB Trigger模式,它是
先在系統內存組織好顯存.然后通過DMA傳輸到LCM內部存儲器上。這種模式的顯示速度大大優于專門畫點命令的函數,應該做較多優化。 我們兩種模式都實測了,前者是繪制的速度相當于之慢,無法實用(可能跟算法效率也有關系),因此我們有實用價值主要采用RGB 捕獲模式的流程。 我們后面主要是這個流程,這個在S3C6410算法最早由
梁熠章實現驗證。
按照S3C6410的要求,MCU-LCD編程流程如下.這個算法里很多流程比如WINDOWS/OSD的操作可以直接重用RGB-LCD的代碼。
因此我們首先按MCU-LCD的屏的要求,
1.首先是發送RESET信號,這個取決于硬件連續。在我們板上使用 GPJ5來充當RESET腳
| //MCU屏要求,每次Reset要求送一個 1,0,1的波形 void?LCD_MCU_Reset() { #ifdef?LCD_TYPE_MCU_NOAIS28 ????rGPJCON?=?(rGPJCON?&?~(0x3<<10))?|?(0x1<<10); ?????rGPJDAT?|=?(0X1<<5); ?????Delay(100); ????? rGPJDAT?&=?~(0X1<<5); ?????Delay(100); ????rGPJDAT?|=?(0X1<<5); ????Delay(100); #endif } |
2.是配置LCD類型為 I80接口. 這里有兩步,一是配置?將rMIFPCON的SEL_BYPASS[3] 設為0 ,旁路掉Modem引腳.
rMIFPCON &= ~(0x1 << 3); 二是將接口配置為I80 的接口. rSPCON = (rSPCON & ~3) | (0x00 << 0);
三.設置MCD-LCD硬件參數 這里仍然采用RGB-LCD的經驗值來進行調整,頻率采用 HCLK的16分之一.bpp采用16. 信號捕獲模式完全等同于RGB模式, rVIDCON1 = IVCLK_RISE_EDGE | IHSYNC_NORMAL | IVSYNC_NORMAL | IVDEN_NORMAL ; 2.8"分辨率分別是240x320。用VIDTCON2配置 rVIDTCON2 = LINEVAL(pDevice->height -1 ) | HOZVAL(pDevice->width -1); 另外I80有自己的專用時序參數,這里使用I80IFCONA0來配置,主要各段時序的時間長度,這由具體板的參數來讀取。我們取一組經驗值
rI80IFCONA0 = (LCD_CS_SETUP << 16)| (LCD_WR_SETUP << 12) | (LCD_WR_ACT << 8)|(LCD_WR_HOLD ?<< 4)|(1<<2)|(1<<0); 四.
諾愛信2.8"的LCD 初始化命令 這是產家規定一組序列參數
| LCD_MCU_Write_Register(0x00E3,0x3008); ???? LCD_MCU_Write_Register(0x00E7,0x0012); ???? LCD_MCU_Write_Register(0x00EF,0x1231); ????? ???? LCD_MCU_Write_Register(0x0001,0x0100); ???? LCD_MCU_Write_Register(0x0002,0x0700); ???? LCD_MCU_Write_Register(0x0003,0x1030);? ????? ???? LCD_MCU_Write_Register(0x0004,0x0000); ???? LCD_MCU_Write_Register(0x0008,0x0207); ???? LCD_MCU_Write_Register(0x0009,0x0000); ???? LCD_MCU_Write_Register(0x000A,0x0000); ???? LCD_MCU_Write_Register(0x000C,0x0000); ???? LCD_MCU_Write_Register(0x000D,0x0000); ???? LCD_MCU_Write_Register(0x000F,0x0000); ????? ???? LCD_MCU_Write_Register(0x0010,0x0000);? ??????? LCD_MCU_Write_Register(0x0011,0x0007); ??????? LCD_MCU_Write_Register(0x0012,0x0000); ??????????LCD_MCU_Write_Register(0x0013,0x0000); ??????????Delay(10); ?????????? LCD_MCU_Write_Register(0x0010,0x1490);? ??????? LCD_MCU_Write_Register(0x0011,0x0227); ??????? Delay(10); ??????? LCD_MCU_Write_Register(0x0012,0x001A); ??????? Delay(10); ?????????? LCD_MCU_Write_Register(0x0013,0x0700);//1000 ?????????? LCD_MCU_Write_Register(0x0029,0x0001);// 0015? ??????? ??????? LCD_MCU_Write_Register(0x002B,0x000C); ??????? Delay(10); ??????? LCD_MCU_Write_Register(0x0020,0x0000); ??????LCD_MCU_Write_Register(0x0021,0x0000);? ?????? ???? LCD_MCU_Write_Register(0x0030,0x0000); ???? LCD_MCU_Write_Register(0x0031,0x0607); ???? LCD_MCU_Write_Register(0x0032,0x0305); ???? LCD_MCU_Write_Register(0x0035,0x0000); ???? LCD_MCU_Write_Register(0x0036,0x1604); ???? LCD_MCU_Write_Register(0x0037,0x0204); ???? LCD_MCU_Write_Register(0x0038,0x0001); ???? LCD_MCU_Write_Register(0x0039,0x0707); ???? LCD_MCU_Write_Register(0x003C,0x0000); ???? LCD_MCU_Write_Register(0x003D,0x000F); ????? ?????? ???? LCD_MCU_Write_Register(0x0050,0x0000); ???? LCD_MCU_Write_Register(0x0051,0x00EF); ???? LCD_MCU_Write_Register(0x0052,0x0000); ???? LCD_MCU_Write_Register(0x0053,0x013F); ????? ???? LCD_MCU_Write_Register(0x0060,0xa700);? ???? LCD_MCU_Write_Register(0x0061,0x0001); ???? LCD_MCU_Write_Register(0x006A,0x0000); ????? ???? LCD_MCU_Write_Register(0x0080,0x0000); ???? LCD_MCU_Write_Register(0x0081,0x0000); ???? LCD_MCU_Write_Register(0x0082,0x0000); ???? LCD_MCU_Write_Register(0x0083,0x0000); ???? LCD_MCU_Write_Register(0x0084,0x0000); ???? LCD_MCU_Write_Register(0x0085,0x0000); ????? ???? LCD_MCU_Write_Register(0x0090,0x0010);? ???? LCD_MCU_Write_Register(0x0092,0x0600);?????????? ???? LCD_MCU_Write_Register(0x0093,0x0003);?????? ???? LCD_MCU_Write_Register(0x0095,0x0110); ???? LCD_MCU_Write_Register(0x0097,0x0000); ???? LCD_MCU_Write_Register(0x0098,0x0000); ???? ????? ????? ???? LCD_MCU_Write_Register(0x0007,0x0133); |
五.S3C6410 I80命令的發送
I80就是由命令和數據都是通過MCU接口發送到LCM進行解釋。命令的含意取決于具體的LCM,不一定相同。S3C6410只是實現發送機制
??一個I80命令/數據由多個寄存器來設置, ?? ?命令值本身,由LDI_CMDx來設定,x取值是 0 - 11(即一次性最多發送12個命令) ?? ?命令的模式,即這一次發送中哪一個命令有效/以及采用哪一個模式,它由LDI_CMDCON0對應位來生效,命令發送有兩種模式,一種單獨手工發送,一種自動成批發送 ?? ?命令的類型,即每一個發送是命令還是數據,由LDI_CMDCON1來配置 ??? I80IFCONB0 /1來設置命令的總體配置
,包括自動命令的幀數,或者普通命令的開始
以下是由手工命令實現的寫命令和數據函數
?
| #define?LCD_MCU_START_WRITE()?rI80IFCONB0?|=(1<<9) ? ?void?LCD_MCU_Write_Cmd(unsigned?short?cmd) { ??????rLDI_CMD0?=?cmd; ?????? ??????//等Normal command 變為0 ??????while(!(?(rI80IFCONB0&?(1<<9))?==?0)); ???? ????rLDI_CMDCON0?=?(rLDI_CMDCON0?&?(0x0))?|((0x01)<<0);?//01 : Normal Command Enable ????rLDI_CMDCON1?=?(rLDI_CMDCON1?&?(0x0))?|((0x0)<<0);????//Command 0 RS control,送命令 ???? ????LCD_MCU_START_WRITE(); ???? ???Delay(10); } void?LCD_MCU_Write_Data(unsigned?short?data) { ??rLDI_CMD0?=?data; ?????? ??????//等Normal command 變為0 ??????while(!(?(rI80IFCONB0&?(1<<9))?==?0)); ???? ????rLDI_CMDCON0?=?(rLDI_CMDCON0?&?(0x0))?|((0x01)<<0);?//01 : Normal Command Enable ????rLDI_CMDCON1?=?(rLDI_CMDCON1?&?(0x0))?|((0x1)<<0);????//Command 0 RS control ,送數據 ???? ????LCD_MCU_START_WRITE(); ????Delay(10); } |
七.顯存數據組織 采用16bpp(565)的形式在顯存中組織.處理流程與RGB 16bpp幾乎完全一樣,采用short來發送點數據 它會自動生成MCU命令來傳輸. 組織好用TRIGCON來觸發顯示.
rTRIGCON |= (1<<1)|(1 << 0); 然后用VIDCON0中打開輸出顯示
rVIDCON0 |= (1 << 1) | ( 1 << 0);?//.Display On: ENVID & ENVID_F set to 1
總結
以上是生活随笔為你收集整理的S3C6410驱动I80接口LCD的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。