打印
[应用相关]

uCGUI 驱动LCD提速 STM32F主芯

[复制链接]
397|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
internally|  楼主 | 2019-6-18 09:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在这里首先感谢wzt的**《ucgui液晶显示深度优化篇》写的很详细,运行很高效。
http://www.docin.com/p-453546222.html
         在这里我提出另一种方法,在完全不破坏原有的uCGUI接口功能上进行强力提速。当然速度方面要弱于wzt的速度,当然优点就在于不破坏所有接口功能,保留下了uCGUI的所有功能。例如两个图片交叉异或显示。
好了,下面开始改进。
         这里先提一下我用的LCD是3.2寸SSD1289屏,神舟三号开发板。 这里不管用什么屏,只要屏写像素点后如图所示移动就可以了。 从这里大家应该也看出来了, 我主要用到的方法就是在写连续像素时省去每次设置坐标点的问题。这就是我下面**思想的基础了。
我用的是LCDTemplate.c接口文件。直接在其上进行改进。
在文件最上方添加以下几个基本函数:
typedef struct
{
  vu16 LCD_REG;
  vu16 LCD_RAM;
} LCD_TypeDef;
      
#define LCD_BASE    ((u32)(0x60000000 | 0x0C000000))
static volatile LCD_TypeDef *LCD = ((volatile LCD_TypeDef *) LCD_BASE);

/*********************************************************************
*
*       设定坐标
*/

__forceinline void LCD_SetCursor(U16 x, U16 y)
{
    int xPhys;
    int yPhys;
    /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
#if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
      xPhys = LOG2PHYS_X(x, y);
      yPhys = LOG2PHYS_Y(x, y);
#else
      xPhys = x;
      yPhys = y;
#endif

    LCD->LCD_REG = 0x004F;
    LCD->LCD_RAM = 319 - xPhys;
    LCD->LCD_REG = 0x004E;
    LCD->LCD_RAM = yPhys;   
}

/*********************************************************************
*
*       当前坐标读一个像素
*/
__forceinline U16 LCD_GetPoint()
{
    LCD->LCD_REG = 0x22;
    LCD->LCD_RAM > 0;       //等待数据稳定
    return LCD->LCD_RAM;
}

/*********************************************************************
*
*       当前坐标写一个像素
*/

__forceinline void LCD_SetPoint(U16 point)
{
    LCD->LCD_REG = 0x22;
    LCD->LCD_RAM = point;
}

/*********************************************************************
*
*       当前坐标开始画一条水平线
*       xEnd:结束坐标
*/
__forceinline void LCD_DrawHLineExt(int x, int xEnd, U16 point)
{
    LCD->LCD_REG = 0x22;
    while (x++ <= xEnd)
        LCD->LCD_RAM = point;
}
这些基本函数 要根据各自的lcd屏驱动所定的。

使用特权

评论回复
沙发
internally|  楼主 | 2019-6-18 09:41 | 只看该作者
在原先的移植上 做如下修改:
原函数
void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
  int xPhys = 0;
  int yPhys = 0;
  GUI_USE_PARA(x);
  GUI_USE_PARA(y);
  GUI_USE_PARA(PixelIndex);
  /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
  #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
    xPhys = LOG2PHYS_X(x, y);
    yPhys = LOG2PHYS_Y(x, y);
  #else
    xPhys = x;
    yPhys = y;
  #endif
  /* Write into hardware ... Adapt to your system */
  {
    ili9320_SetPoint(xPhys, yPhys, PixelIndex);/* ... */
  }
}
unsigned int LCD_L0_GetPixelIndex(int x, int y) {
  int xPhys = 0;
  int yPhys = 0;
  LCD_PIXELINDEX PixelIndex;

  GUI_USE_PARA(x);
  GUI_USE_PARA(y);
  /* Convert logical into physical coordinates (Dep. on LCDConf.h) */
  #if LCD_SWAP_XY | LCD_MIRROR_X| LCD_MIRROR_Y
    xPhys = LOG2PHYS_X(x, y);
    yPhys = LOG2PHYS_Y(x, y);
  #else
    xPhys = x;
    yPhys = y;
  #endif
  /* Read from hardware ... Adapt to your system */
  {
    PixelIndex = ili9320_GetPoint(xPhys, yPhys);/* ... */
  }
  return PixelIndex;
}



修改后
void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {
  GUI_USE_PARA(x);
  GUI_USE_PARA(y);
  GUI_USE_PARA(PixelIndex);

  LCD_SetCursor(x, y);
  LCD_SetPoint(PixelIndex);
}
unsigned int LCD_L0_GetPixelIndex(int x, int y) {
  GUI_USE_PARA(x);
  GUI_USE_PARA(y);

  LCD_SetCursor(x, y);
  return LCD_GetPoint();
}

原文件
void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
    for (; x0 <= x1; x0++) {
      LCD_L0_XorPixel(x0, y);
    }
  } else {
    for (; x0 <= x1; x0++) {
      LCD_L0_SetPixelIndex(x0, y, LCD_COLORINDEX);
    }
  }
}



修改后
void LCD_L0_DrawHLine  (int x0, int y,  int x1) {
  if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR) {
      while(x0++ <= x1)
        LCD_L0_XorPixel(x0, y);
  } else {
    LCD_SetCursor(x0,  y);
    LCD_DrawHLineExt(x0, x1, LCD_COLORINDEX);
  }
}


细节观察,这个函数只是把写坐标分离出来了。

关键的修改,大部分刷屏程序都用到LCD_L0_DrawHLine函数,所以优化他对你的程序提速起了决定性的改变。

使用特权

评论回复
板凳
internally|  楼主 | 2019-6-18 09:42 | 只看该作者
原理很简单,只要画水平线时,每写一个像素,坐标会自动后移一位。所以没必要每次都指定坐标,把设置坐标的时间给节约出来。

最后就是画图函数了,我的LCD是16位的,所以我只修改了DrawBitLine16BPP一个函数,如果你的是低于16位的,同理进行修改。

参考如下
原函数
static void  DrawBitLine16BPP(int x, int y, U16 const GUI_UNI_PTR * p, int xsize, const LCD_PIXELINDEX * pTrans) {
  LCD_PIXELINDEX pixel;
  if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) == 0) {
    if (pTrans) {
      for (; xsize > 0; xsize--, x++, p++) {
        pixel = *p;
        LCD_L0_SetPixelIndex(x, y, *(pTrans + pixel));
      }
    } else {
      for (;xsize > 0; xsize--, x++, p++) {
        LCD_L0_SetPixelIndex(x, y, *p);
      }
    }
  } else {
    if (pTrans) {
      for (; xsize > 0; xsize--, x++, p++) {
        pixel = *p;
        if (pixel) {
          LCD_L0_SetPixelIndex(x, y, *(pTrans + pixel));
        }
      }
    } else {
      for (; xsize > 0; xsize--, x++, p++) {
        pixel = *p;
        if (pixel) {
          LCD_L0_SetPixelIndex(x, y, pixel);
        }
      }
    }
  }
}


修改后如下
static void  DrawBitLine16BPP(int x, int y, U16 const GUI_UNI_PTR * p, int xsize, const LCD_PIXELINDEX * pTrans) {
  LCD_PIXELINDEX pixel;
  
  LCD_SetCursor(x, y);
  if ((GUI_Context.DrawMode & LCD_DRAWMODE_TRANS) == 0) {
    if (pTrans) {
      for (; xsize > 0; xsize--, x++, p++) {
        pixel = *p;
        LCD_SetPoint(*(pTrans + pixel));
      }
    } else {
      for (;xsize > 0; xsize--, x++, p++) {
        LCD_SetPoint(*p);
      }
    }
  } else {
    if (pTrans) {
      for (; xsize > 0; xsize--, x++, p++) {
        pixel = *p;
        if (pixel) {
          LCD_SetPoint(*(pTrans + pixel));
        }
      }
    } else {
      for (; xsize > 0; xsize--, x++, p++) {
        pixel = *p;
        if (pixel) {
          LCD_SetPoint(pixel);
        }
      }
    }
  }
}

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

使用特权

评论回复
地板
internally|  楼主 | 2019-6-18 09:42 | 只看该作者
这里附上我的测试工程:

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

视频预览。

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

使用特权

评论回复
5
xiaoqizi| | 2019-7-8 09:32 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
6
观海| | 2019-7-8 10:51 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
7
guanjiaer| | 2019-7-8 10:58 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
8
heimaojingzhang| | 2019-7-8 11:06 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

315

帖子

0

粉丝