uCGUI 驅動LCD提速 STM32F主芯


 

在這里首先感謝wzt的文章《ucgui液晶顯示深度優化篇》寫的很詳細,運行很高效。

http://www.docin.com/p-453546222.html

         在這里我提出另一種方法,在完全不破壞原有的uCGUI接口功能上進行強力提速。當然速度方面要弱於wzt的速度,當然優點就在於不破壞所有接口功能,保留下了uCGUI的所有功能。例如兩個圖片交叉異或顯示。

好了,下面開始改進。

         這里先提一下我用的LCD是3.2寸SSD1289屏,神舟三號開發板。 這里不管用什么屏,只要屏寫像素點后如圖所示移動就可以了。 從這里大家應該也看出來了, 我主要用到的方法就是在寫連續像素時省去每次設置坐標點的問題。這就是我下面文章思想的基礎了。

我用的是LCDTemplate.c接口文件。直接在其上進行改進。

在文件最上方添加以下幾個基本函數:

 1 typedef struct
 2 {
 3   vu16 LCD_REG;
 4   vu16 LCD_RAM;
 5 } LCD_TypeDef;
 6        
 7 #define LCD_BASE    ((u32)(0x60000000 | 0x0C000000))
 8 static volatile LCD_TypeDef *LCD = ((volatile LCD_TypeDef *) LCD_BASE);
 9 
10 /*********************************************************************
11 *
12 *       設定坐標
13 */
14 
15 __forceinline void LCD_SetCursor(U16 x, U16 y)
16 {
17     int xPhys;
18     int yPhys;
19     /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
20 #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
21       xPhys = LOG2PHYS_X(x, y);
22       yPhys = LOG2PHYS_Y(x, y);
23 #else
24       xPhys = x;
25       yPhys = y;
26 #endif
27 
28     LCD->LCD_REG = 0x004F;
29     LCD->LCD_RAM = 319 - xPhys;
30     LCD->LCD_REG = 0x004E;
31     LCD->LCD_RAM = yPhys;    
32 }
33 
34 /*********************************************************************
35 *
36 *       當前坐標讀一個像素
37 */
38 __forceinline U16 LCD_GetPoint()
39 {
40     LCD->LCD_REG = 0x22;
41     LCD->LCD_RAM > 0;       //等待數據穩定
42     return LCD->LCD_RAM;
43 }
44 
45 /*********************************************************************
46 *
47 *       當前坐標寫一個像素
48 */
49 
50 __forceinline void LCD_SetPoint(U16 point)
51 {
52     LCD->LCD_REG = 0x22;
53     LCD->LCD_RAM = point;
54 }
55 
56 /*********************************************************************
57 *
58 *       當前坐標開始畫一條水平線
59 *       xEnd:結束坐標
60 */
61 __forceinline void LCD_DrawHLineExt(int x, int xEnd, U16 point)
62 {
63     LCD->LCD_REG = 0x22;
64     while (x++ <= xEnd)
65         LCD->LCD_RAM = point;
66 }

 

這些基本函數 要根據各自的lcd屏驅動所定的。

 

在原先的移植上 做如下修改:

 1 原函數
 2 void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
 3   int xPhys = 0;
 4   int yPhys = 0; 
 5   GUI_USE_PARA(x);
 6   GUI_USE_PARA(y);
 7   GUI_USE_PARA(PixelIndex);
 8   /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
 9   #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
10     xPhys = LOG2PHYS_X(x, y);
11     yPhys = LOG2PHYS_Y(x, y);
12   #else
13     xPhys = x;
14     yPhys = y;
15   #endif
16   /* Write into hardware ... Adapt to your system */
17   {
18     ili9320_SetPoint(xPhys, yPhys, PixelIndex);/* ... */
19   }
20 }
21 unsigned int LCD_L0_GetPixelIndex(int x, int y) {
22   int xPhys = 0;
23   int yPhys = 0;
24   LCD_PIXELINDEX PixelIndex;
25 
26   GUI_USE_PARA(x);
27   GUI_USE_PARA(y);
28   /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
29   #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
30     xPhys = LOG2PHYS_X(x, y);
31     yPhys = LOG2PHYS_Y(x, y);
32   #else
33     xPhys = x;
34     yPhys = y;
35   #endif
36   /* Read from hardware ... Adapt to your system */
37   {
38     PixelIndex = ili9320_GetPoint(xPhys, yPhys);/* ... */
39   }
40   return PixelIndex;
41 }
42 
43 
44 
45 修改后
46 void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
47   GUI_USE_PARA(x);
48   GUI_USE_PARA(y);
49   GUI_USE_PARA(PixelIndex);
50 
51   LCD_SetCursor(x, y);
52   LCD_SetPoint(PixelIndex);
53 }
54 unsigned int LCD_L0_GetPixelIndex(int x, int y) {
55   GUI_USE_PARA(x);
56   GUI_USE_PARA(y);
57 
58   LCD_SetCursor(x, y);
59   return LCD_GetPoint();
60 }
 1 原文件
 2 void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
 3   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
 4     for (; x0 <= x1; x0++) {
 5       LCD_L0_XorPixel(x0, y);
 6     }
 7   } else {
 8     for (; x0 <= x1; x0++) {
 9       LCD_L0_SetPixelIndex(x0, y, LCD_COLORINDEX);
10     }
11   }
12 }
13 
14 
15 
16 修改后
17 void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
18   if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
19       while(x0++ <= x1)
20         LCD_L0_XorPixel(x0, y);
21   } else {
22     LCD_SetCursor(x0,  y);
23     LCD_DrawHLineExt(x0, x1, LCD_COLORINDEX);
24   }
25 }

 

細節觀察,這個函數只是把寫坐標分離出來了。

關鍵的修改,大部分刷屏程序都用到LCD_L0_DrawHLine函數,所以優化他對你的程序提速起了決定性的改變。

 

原理很簡單,只要畫水平線時,每寫一個像素,坐標會自動后移一位。所以沒必要每次都指定坐標,把設置坐標的時間給節約出來。

最后就是畫圖函數了,我的LCD是16位的,所以我只修改了DrawBitLine16BPP一個函數,如果你的是低於16位的,同理進行修改。

參考如下

 1 原函數
 2 static void  DrawBitLine16BPP(int x, int y, U16 const GUI_UNI_PTR * p, int xsize, const LCD_PIXELINDEX * pTrans) {
 3   LCD_PIXELINDEX pixel;
 4   if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) == 0) {
 5     if (pTrans) {
 6       for (; xsize > 0; xsize--, x++, p++) {
 7         pixel = *p;
 8         LCD_L0_SetPixelIndex(x, y, *(pTrans + pixel));
 9       }
10     } else {
11       for (;xsize > 0; xsize--, x++, p++) {
12         LCD_L0_SetPixelIndex(x, y, *p);
13       }
14     }
15   } else {
16     if (pTrans) {
17       for (; xsize > 0; xsize--, x++, p++) {
18         pixel = *p;
19         if (pixel) {
20           LCD_L0_SetPixelIndex(x, y, *(pTrans + pixel));
21         }
22       }
23     } else {
24       for (; xsize > 0; xsize--, x++, p++) {
25         pixel = *p;
26         if (pixel) {
27           LCD_L0_SetPixelIndex(x, y, pixel);
28         }
29       }
30     }
31   }
32 }
33 
34 
35 修改后如下
36 static void  DrawBitLine16BPP(int x, int y, U16 const GUI_UNI_PTR * p, int xsize, const LCD_PIXELINDEX * pTrans) {
37   LCD_PIXELINDEX pixel;
38   
39   LCD_SetCursor(x, y);
40   if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) == 0) {
41     if (pTrans) {
42       for (; xsize > 0; xsize--, x++, p++) {
43         pixel = *p;
44         LCD_SetPoint(*(pTrans + pixel));
45       }
46     } else {
47       for (;xsize > 0; xsize--, x++, p++) {
48         LCD_SetPoint(*p);
49       }
50     }
51   } else {
52     if (pTrans) {
53       for (; xsize > 0; xsize--, x++, p++) {
54         pixel = *p;
55         if (pixel) {
56           LCD_SetPoint(*(pTrans + pixel));
57         }
58       }
59     } else {
60       for (; xsize > 0; xsize--, x++, p++) {
61         pixel = *p;
62         if (pixel) {
63           LCD_SetPoint(pixel);
64         }
65       }
66     }
67   }
68 }

好了,修改完了,可以進行測試了。

 

這里附上我的測試工程:

http://pan.baidu.com/share/link?shareid=63325&uk=118334538

視頻預覽。

http://www.tudou.com/programs/view/sQexoNIhNR0/#


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM