博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uCGUI 驱动LCD提速 STM32F主芯
阅读量:5061 次
发布时间:2019-06-12

本文共 6042 字,大约阅读时间需要 20 分钟。

 

在这里首先感谢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_Y21       xPhys = LOG2PHYS_X(x, y);22       yPhys = LOG2PHYS_Y(x, y);23 #else24       xPhys = x;25       yPhys = y;26 #endif27 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_Y10     xPhys = LOG2PHYS_X(x, y);11     yPhys = LOG2PHYS_Y(x, y);12   #else13     xPhys = x;14     yPhys = y;15   #endif16   /* 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_Y30     xPhys = LOG2PHYS_X(x, y);31     yPhys = LOG2PHYS_Y(x, y);32   #else33     xPhys = x;34     yPhys = y;35   #endif36   /* 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 }

好了,修改完了,可以进行测试了。

 

这里附上我的测试工程:

视频预览。

#

转载于:https://www.cnblogs.com/hiker-blogs/archive/2012/09/28/2706507.html

你可能感兴趣的文章
跨平台开发 -- C# 使用 C/C++ 生成的动态链接库
查看>>
C# BS消息推送 SignalR介绍(一)
查看>>
WPF星空效果
查看>>
WPF Layout 系统概述——Arrange
查看>>
PIGOSS
查看>>
几款Http小服务器
查看>>
iOS 数组排序
查看>>
第三节
查看>>
PHP结合MYSQL记录结果分页呈现(比较实用)
查看>>
Mysql支持的数据类型
查看>>
openSuse beginner
查看>>
Codeforces 620E(线段树+dfs序+状态压缩)
查看>>
Windows7中双击py文件运行程序
查看>>
Market entry case
查看>>
bzoj1230 开关灯 线段树
查看>>
LinearLayout
查看>>
学习python:day1
查看>>
css3动画属性
查看>>
第九次团队作业-测试报告与用户使用手册
查看>>
Mongodb 基本命令
查看>>