LCM之Fmark功能 && LCD控制器同LCD驅動器的差別 && 幀率與重新整理率的關係 && OLED背光
最近除錯R61509V這顆LCM驅動晶片時,出現在純色測試畫面下畫面重新整理有殘留(tearing effect,即TE)的問題。根本原因是主控寫影象資料的速度與LCM刷屏的速度不一致造成的,具體是刷屏速度要快於主控寫速度。好在很多LCM驅動晶片都有一個Fmark腳,用來與主控同步,當Fmark發出一個訊號給主控時,主控才開始寫一幀資料,這樣就可以保證兩邊同步。講述前首先對幾個概念描述:
(1)刷屏速度
刷屏率是指LCM重新整理的速度,這個值一般在LCM的初始化CODE中會設定好。對於瑞薩的R61509V這顆LCD驅動,設定0x0010暫存器就是設定刷屏速度。根據公式:幀率=678KHZ/{(RTN)*DIV*(432+8+8)} ,其中678K是LCM內部的時鐘源,RTN是每行的時鐘數,DIV是分頻係數,(432+8+8)則是行畫素。測得的結果是:
0X011F 20HZ,最小頻率.
0X011A 29HZ
0X0115 36HZ
0X0110 52HZ
0X001C 60HZ
0X0018 70HZ
0X0014 80HZ
刷屏率太低會導致出現flicker現象,所以一般要設定在60HZ以上。
(2)主控寫速度WR跟片選CS
這兩個PIN腳對每個DBI的LCM都具備,兩者的工作頻率是一致的。主控每次寫一幀資料時,會有一個片選訊號,同時對應一個WR的寫有效訊號。主控的寫頻率的變化是由工作狀態決定的,比如攝像時,拍攝動態物體的顯示寫速度就快於拍攝靜態物體的顯示寫速度。
如果螢幕的畫面沒有更新,就會70ms update一次lcd,如果畫面有動,就是最多33ms刷一次屏。意思就是CS頻率只能限定在1/70到1/30,14.28HZ至33.33HZ之間。最高頻率已經快於PAL或者NTSC的幀頻,可以保證攝像頭工作或者播放視訊時不會出現丟幀現象。
(3)Fmark功能
要使能fmark,首先要保證主控的fmark腳與LCM的fmark腳是正確連線的;其次要在LCM初始化中使能屏的fmark功能,保證LCM週期性發出訊號給主控,同時使能主控的fmark功能,保證主控收到一個fmark訊號才寫一幀資料。
LCM的fmark有兩個引數可以配置:一是刷多少次屏發出一個fmark訊號,比如不一定要每次刷屏都發fmark訊號,可以刷幾次屏發一次fmark訊號;二是fmark的位置引數,可以讓fmark遲滯幾條線輸出,目的是讓主控晚點寫資料到GRAM,避免TE。
舉例:存在這樣的情況,就是IC在從GRAM讀完最後一行就輸出te訊號,此時BB開始寫GRAM。但可能還要有一兩條line的時間,IC才開始從GRAM的第一行讀資料刷下二楨,而寫GRAM的速度要慢於IC讀GRAM的速度,此時可能還沒有開始寫。導致讀GRAM超過寫GRAM,所以會在上方產生tearing。要避免TE輸出太早,導致寫GRAM先開始,所以要加延遲,保證讀老舊資料開始後,寫GRAM才開始。
(4)fmark週期與CS週期
出現TE現象的根本原因是兩邊速度不一致,具體是LCM的重新整理速度要快於主控送資料的速度,兩者的速度要符合一定的範圍才行。只要保證CS的週期在兩個TE週期之間即可,也就是CS的寫頻率不能低於TE讀頻率的二分之一,Tearing出現的根本條件是讀寫有交叉。通常都是寫Gram速度(WR)慢於lcd刷屏速度(TE),只要刷屏的位置不超過寫Gram位置就不會有切屏現象。
舉個例項:比如CS差不多就比兩個TE週期小一點,要刷兩楨資料,首先第一楨刷屏開始刷屏了,表示讀GRAM開始,它的速度比較快,它讀的是老舊資料;緊接著主控開始寫GRAM,大概寫到GRAM的快一半時,這時候已經刷完一楨,然後開始刷第二楨,即又從GRAM的最上方開始讀並刷屏,此時讀出來的才是剛寫入的新資料,在寫完GRAM之前,讀的步驟永遠跟不上寫的步驟,就不會出現tearing。
如果CS比兩個TE週期大,假設相當於三個TE週期,那麼只有在第三個TE讀週期時,顯示的資料才是寫好的GRAM的資料;第一個TE讀的是老舊的資料,第二個TE週期由於GRAM還沒有寫完,但讀步驟趕上寫GRAM步驟了,導致顯式一部分是舊的一部分是新的,所以出現TE。此即本質。
若TE已經成功開啟,依然有Teering現象(攝像頭預覽或者播放視訊時尤其明顯),可從如下方面思考分析。
1)是否使用了豎屏橫用,導致對GRAM的讀寫方向不一致,一般會出現斜線切屏現象。
2)是否clock速度過低,FPS低於LCM自重新整理率的1/2?
3)是否clock速率過快,超過LCM的自重新整理率,導致寫GRAM時可能從後面趕上讀,導致Teering發生。
(5) TE型別
TE顯示使能時,必須保證CPU的LCD TE使能和LCM驅動的TE功能都開啟。LCM的TM使能有兩種:VSYSC,VSYNC&HSYNC。圖示如下:
=================================================================================================
首先,LCD控制器同LCD驅動器是有著本質區別的。簡單來說LCD控制器在嵌入式系統中的功能如同顯示卡在計算機中所起到的作用。LCD控制器負責把視訊記憶體(可能是記憶體中的指定域)中的LCD圖形資料傳輸到LCD驅動器(LCD driver)上,併產生必須的LCD控制訊號,從而控制和完成圖形的顯示,翻轉,疊加,縮放等一系列複雜的圖形顯示功能。LCD驅動器則只負責把CPU傳送的影象資料在LCD顯示出來,不會對影象做任何的處理。獨立顯示卡,就是個GPU模組加自己相應的外設,具備獨立視訊記憶體(RAM)。
整合顯示卡,是GPU與CPU共用記憶體。
=================================================================================================
幀數(幀率),就是畫面改變的速度,只要顯示卡夠強,幀數就能很高,只要幀數高畫面就流暢。理論上,每一幀都是不同的畫面。60fps就是每秒鐘顯示卡生成60張畫面圖片。
重新整理率,顧名思義,就是顯示卡將顯示訊號輸出重新整理的速度。60赫茲(hertz)就是每秒鐘顯示卡向顯示器輸出60次訊號。
假設幀數是重新整理率的1/2,那麼意思就是顯示卡每兩次向顯示器輸出的畫面是用一幅畫面。相反,如果幀數是重新整理率的2倍,那麼畫面每改變兩次,其中只有1次是被顯示卡傳送並在顯示器上顯示的。 所以高於重新整理率的幀數都是無效幀數,對畫面效果沒有任何提升,反而可能導致畫面異常。
=================================================================================================
漸漸興起的OLED屏,都是沒有背光概念的,用屏自身的命令來控制背光。修改方法參見FAQ,需要說明的一個地方:
static struct LCM_setting_table lcm_backlight_level_setting[] = {
{0x51, 1, {0xFF}}, //0xFF最終會被覆寫
{0x53, 1, {0x20}},
{REGFLAG_END_OF_TABLE,99, {}}
};
static void lcm_setbacklight(unsigned int level)
{
unsigned int default_level = 145; //名為預設,實際是最低亮度
unsigned int mapped_level = 0;
if(level > 255)
level = 255;
if(level >0)
mapped_level = default_level+(level)*(255-default_level)/(255); //等份化
else
mapped_level=0;
// Refresh value of backlight level.
lcm_backlight_level_setting[0].para_list[0] = mapped_level; //覆蓋結構體構成的陣列的,第一個陣列元素的para_list陣列的第一個值
LCM_PRINT(" lcm_setbacklight setting level is %d \r\n", level);
push_table(lcm_backlight_level_setting, sizeof(lcm_backlight_level_setting) / sizeof(struct LCM_setting_table), 1);
}