4線SPI彩屏局部刷屏偏移解決
——原來我早已經在成功的旁邊了
最近在研究用低速、低RAM的單片機來驅動小LCD或TFT彩屏實現動畫效果
首先我用一個16MHz晶振的m0內核的8位單片機nRF51822嘗試驅動一個1.77寸的4線SPI屏(128X160),
發現,刷一屏大約要0.8s左右的時間,
具體收錄在《1、一個簡單的nRF51822驅動的天馬4線SPI-1.77寸LCD彩屏DEMO》中
覺得,如果用72MHz的STM32也許效果會好很多
於是在stm32上做了個類似的版本,
具體收錄在《一個簡單的stm32vet6驅動的天馬4線SPI-1.77寸LCD彩屏DEMO》中
發現刷一屏0.2s左右,
效果是有的,但是還不能達到支持播放流暢動畫的效果!
后來,又用stm32驅動一個2.4寸240X320的8位並口tft屏
具體收錄在《一個簡單的stm32vet6驅動2.4寸240X320的8位並口tft屏DEMO》中
這個尺寸比之前的1.77要大4倍,
所以即使采用8位並口速度還是沒太大變化!
再后來,偶然發現采用單片機自帶的硬件SPI速度回快很多(3-8倍)
這主要是因為硬件SPI把下面采用軟件模擬的過程中不必要的移位、復制、電平翻轉采用硬件給做了~(猜測)
1 void SendDataSPI(unsigned char dat) 2 { 3 unsigned char i; 4 for(i = 0; i < 8; i++) 5 { 6 if( (dat & 0x80) != 0 ) SDA_SET; 7 else SDA_CLEAR; 8 9 dat <<= 1; 10 11 SCL_CLEAR; 12 SCL_SET; 13 } 14 }
盡管如此!還是不能實現大塊大塊圖片的動畫刷新效果~
於是靈機一動,也許采用16位並口+同時數據傳輸采用硬件刷屏速度會飛起來!
呵呵,其實是早就知道這個方法,也是最后的殺手鐧了
如果是在不行DSP、FPGA得搬出來了~
其實上面這個想法有一個很霸氣(拗口)的稱呼——FSMC(Flexible Static Memory Controller,可變靜態存儲控制器)
也因此,我買了個土豪金屏幕——
只看該屏幕的介紹就知道人家不簡單——(速度震四方!!!)
哈哈,扯遠了!(開始說本節內容了哈~)
其實本節的重點不是展示這個速震四方的土豪屏,
而是一個突發bug的出現導致我不得不放下手中的土豪屏,專心搞BUG
BUG是這樣的——
我拿到一個4線spi的220X176的屏幕,想寫個驅動
本來應該是分分鍾的事,可是遇到了一個坑了幾天的問題:
拿到該屏幕及其資料如下:其中GC9201為其驅動IC,QTB2D0052和60是上面屏幕的規格書,只是外觀大小稍有不同,壓縮文件是一個包含簡單demo的工程
http://pan.baidu.com/s/1eQRuP4u
① 在QT---52中找到對應引腳並設置好:
② 參考壓縮文件的驅動,在驅動文件中實現了刷屏、繪制條帶、顯示幀、繪制漸變條帶、繪制黑白格子、在屏幕中間顯示一個黑色、繪制一點、繪制一條線、繪制一個網等LCD屏幕驅動函數~
1 int main(void) 2 { 3 int x,y; 4 GPIO_Init(); 5 LCD_Init(); 6 7 // DrawGird(RED); 8 9 while(1<2) 10 { 11 DispColor(GREEN);//刷屏 12 DispBand();//顯示條帶 13 DispFrame();//顯示窗口 14 DispScaleVer();//漸變顏色 15 DispScaleVer_Red();//紅色漸變 16 DispSnow();//黑白格子 17 DispBlock();//在中間顯示一個黑色塊,但是是全屏刷新 18 19 for(x=0,y=0;x<149;x++,y+=2) 20 { 21 PutPixel(x,y,BLUE); 22 } 23 24 DrawLine(20,120,5,6,RED); 25 DrawGird(RED); 26 } 27 }
當時封裝驅動在:http://pan.baidu.com/s/1bnX69Mf
③ 照理說參照廠家DEMO應該一氣呵成的,可最坑爹的問題還就在不可能出現問題的地方【【【神坑】】】
當順利測試完DispBlock()后,PutPixel(x,y,BLUE)函數總是不能把相應的點繪制對,然后我又試了DrawLine、DrawGrid,都出現了很大的問題
:::問題-就是整屏刷新可以成功,位置也對;局部刷新要么偏移,要么導致自身和之后的刷屏錯誤(具體表現為下一次接着上一次刷)
踩坑的-ALL PROCESS:其實首先發現這個原因之前做了很多工作——本來是直接分分鍾寫個驅動整合到總工程中進行從flash讀圖片並刷新在屏幕中央的,結果總是出現偏移!於是
1、仔細拿着廠家給的DEMO核對,發現並沒有區別,DBUG失敗
2、然后又逐條翻譯LCD驅動中的writecom命令,並沒有發現什么異常
3、重新看LCD驅動IC文檔,千辛萬苦發現命令20h和21h似乎對偏移能起作用
發現這兩個命令和AC有關,屏幕之所以出現偏移可能是在writeblock中只指定了視窗,卻沒有修改AC值!
又發現上表中有G1~G220,由於對數據比較敏感,覺得這兩個命令肯定是控制Y方向的AC的,
又參考38、39對Y方向視窗的設置方式,
於是順手在blockwrite中加了兩句:
1 void BlockWrite(unsigned int Xstart,unsigned int Xend,unsigned int Ystart,unsigned int Yend) 2 { 3 //ILI9163C 4 WriteComm(0x0037); 5 WriteData(Xstart); 6 7 WriteComm(0x0036); 8 WriteData(Xend); 9 10 WriteComm(0x0039); 11 WriteData(Ystart); 12 13 WriteComm(0x0038); 14 WriteData(Yend); 15 16 WriteComm(0x0021); 17 WriteData(Ystart); 18 19 WriteComm(0x0020); 20 WriteData(Yend); 21 22 WriteComm(0x0022); 23 }
還真有效果!!!
當時非常激動~~~~
但是我當時用的是drawrectange測試的,刷的是純色
集成到總工程開始刷圖片問題又來了~
——雖然Y方向的AC搞定了,但是X方向存在偏移,最終導致整個圖片的平移
4、再次翻幾遍IC的說明,將目標鎖定在初始化部分可能存在問題!
直到把該注釋的初始化全部注釋掉(只剩兩個了),雖然發現某些命令的功效但是還是沒有解決根本問題
5、嘗試采用計算偏移量,預填充GRAM來抵消偏移
發現偏移規律性不明顯,總是補不完全~
6、今天下午實在不能忍(我斷定是屏幕廠家給了我一次品!)
於是,一封休書找到了屏幕幕后黑手——屏幕驅動IC芯片廠技術人員:
后來,這位技術把我拉到一個討論組里面,轉述內容省略....然后出來個大牛~
看到最后一句20 stax時瞬間豁然開朗~心中有無數草泥馬在奔騰~
《D-BUG詩》
曾經我離成功只差一步之遙,
繞了一大圈,
回到原點~
原來20、21命令一條是指明X方向的AC的值,一條指明Y方向AC的值!
當時鑽進死胡同了~
硬把20、21和Y方向的start和end綁定,
卻苦苦尋找X方向的start和end該怎么放!
於是乎,
明白了為什么規律老是不明顯的X方向偏移,
其實就是command-20將Yend當做了Xstart,
導致了未解的偏移~
有時候,
你與你想要的只差一毫,
一時大意、一時疏忽、一時自得,
讓你用千百倍懂得!
世界上本來沒有坑,想的多了,也就有了坑!
BUG廢除,世界又恢復了平靜~
測試工程源碼(一個移植demo,一個居中繪圖):http://pan.baidu.com/s/1c1vlgPy
注:非常感謝該IC技術團隊的熱情幫忙~
@beautifulzzzz
2015-12-7 持續更新中~