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/#

posted @ 2012-09-28 01:47  Hiker天下  阅读(6483)  评论(7编辑  收藏  举报