分享

如何让ucgui支持24位色(24bpp)

 戴维图书馆 2012-10-29

我打算在UC/OS-II上直接移植一个开源的GUI界面。所以我从网上找了一些GUI的开源代码,主要看了看飞漫软件的MiniGUI和Micrium公司的uC/GUI。


飞漫软件的MiniGUI可免费下载的版本是1.3.3,可是不支持UC/OS-II,网上的介绍中比较适合移植到LINUX。飞漫软件已经发行了可以在UC/OS-II上运行的版本,但已经是商业版本了,不是我可以随便下载的了。


uC/GUI比较适合UC/OS-II,正是我希望的。我将它移植到了UC/OS-II中,发现目前的版本3.32a最大只支持16bpp,不支持24bpp。我将它改成了24bpp模式,就当作是熟悉一下uC/GUI了。


1         UC/GUI介绍


uC/GUI是Micrium公司开发的通用的嵌入式用户图形界面软件。它给任何使用图形LCD的应用程序提供独立于处理器和LCD控制器之外的有效的图形用户接口。可以应用于单一任务环境,也可以应用于多任务环境中。uC/GUI能够应用于任何LCD控制器和CPU的任何尺寸的物理显示或者模拟显示中。


   uC/GUI的特点如下:


 ◆ 适用于任何8位/16位/32位CPU,可允许于支持ANSI C的任何编译器


 ◆ 适用于任何控制器驱动任何LCD(单色,灰度,或者彩色)


 ◆ 通过配置宏,可支持任何接口


 ◆ 可配置显示尺寸


◆ 可在LCD的任何一点上显示字符和画位图


◆ 对于显示尺寸和速度提供优化进程,编译时间依赖于采用的优化进程


◆  支持虚拟显示,虚拟显示的尺寸比实际显示大。


更对UC/GUI的说明和资料请登陆www. 。


2         UC/GUI需要进行的更改


www.上可以下载到UC/GUI的用户手册,如果仅仅是将UC/GUI移植到S3C2410上,可以参照第20-23章,这里就不再详细说明。


如果是仅仅将UC/GUI移植到UC/OS-II上,可以参照第11章。


因为目前能够获得的UC/GUI源码仅能够支持1、2、4、8、16bpp。我简单介绍如何支持24bpp模式,可以用于在8.6英寸TFT-LCD上显示更多色彩。


     需要修改的地方包括:


1)CONFIG目录下文件:主要是LCDCONF.h、GUICONF.H


2)LCDDRIVER目录下文件,LCD_S3C2410.C


3)CORE目录下文件:包括GUI.H、GUITYPE.H、LCD.H、 LCD_CONFDEFAULTS.H、LCD_PRIVATE.H、GUIALLOC.C、 LCD_L0_GENERIC.C。


4)MEMDEV目录下文件: GUIDEV.C。


根据我的修改,目前使用本文后面的UCGUI_test()测试一切正常。


目前还没有进行WM和AA的测试,本文仅仅提供一下修改的思路。以后随着移植进一步完善,可能会有后续修改,请留意。


3         配置头文件


3.1     LCDCONF.H


修改BPP宏:


#define LCD_BITSPERPIXEL        (24)


重新定义内存读写宏,使之符合U32格式:


#define LCD_READ_MEM(Off)            *((U32*)         (gActiveFrameBuffer+((U32)(Off))))


#define LCD_WRITE_MEM(Off,data)      *((U32*)         (gActiveFrameBuffer+((U32)(Off))))=data


3.2     GUICONF.H


将默认字体改为GUI_Font8x16,这是因为我觉得这种字体看起来比较大,适合我手头的屏幕。为了节约空间,我仅仅使用了三种字体,其他FONT都没有编译。


增大GUI_ALLOC_SIZE的值,因为屏幕较大,而且使用了24bpp模式。视你需要的最大尺寸设置。


目前,我把MEMDEV、OS、TOUCH、UNICODE、WM支持都打开了,但是除了MEMDEV都没有测试过,下一步会逐个测试。我觉得AA没有必要,所以也没有打开。


4         S3C2410驱动更改


修改LCD_S3C2410.C,在绘制位图的函数LCD_L0_DrawBitmap中,增加LCD_BITSPERPIXEL>16的switch-case条件,使用函数DrawBitLine24BPP。


    #if (LCD_BITSPERPIXEL > 16)


      case 24:


        DrawBitLine24BPP(x0, i + y0, (const U32 *)pData, xsize, pTrans);


            //注意pData的类型已经改为U32。


        break;


    #endif   


增加24bpp的画线函数,如下:


#if (LCD_BITSPERPIXEL > 16)


static void  DrawBitLine24BPP(int x, int y, U32 const * p, int xsize, const LCD_PIXELINDEX * pTrans)


{


… …//函数体与DrawBitLine16BPP相同。


}


两个点操作函数,LCD_L0_GetPixelIndex()和LCD_L0_SetPixelIndex()可以不用修改,因为在下面的步骤中LCD_PIXELINDEX的定义已经更改为U32了。


5         UC/GUI内核修改


5.1     GUI.H


修改LCD_COLORINDEX_UNION的UNION定义,否则COLOR和BKCOLOR永远只能够使用16bpp。


typedef union {


  U8  aColorIndex8[2];


  U16 aColorIndex16[2];


  U32 aColorIndex32[2]; //增加这一句。


} LCD_COLORINDEX_UNION;


5.2     GUITYPE.H


将GUI_HANDLE、GUI_HWIN、GUI_HMEM定义为I32。


#define GUI_HANDLE int


#define GUI_HWIN            I32P


#define     GUI_HMEM I32P


5.3     LCD.H


重新定义LCD_COLOR。


typedef U32 LCD_COLOR;


5.4     LCD_CONFDEFAULTS.H


重新定义LCD_BITSPERPIXEL。


#if LCD_BITSPERPIXEL <=8


  #define LCD_PIXELINDEX U8


#elif LCD_BITSPERPIXEL <=16


  #define LCD_PIXELINDEX U16


#else


  #define LCD_PIXELINDEX U32 //增加这一句


#endif


5.5     LCD_PRIVATE.H


重新定义LCD_BKCOLORINDEX、LCD_COLORINDEX、LCD_ACOLORINDEX。


#if LCD_BITSPERPIXEL <=8


  #define LCD_BKCOLORINDEX GUI_Context.LCD.aColorIndex8[0]


  #define LCD_COLORINDEX   GUI_Context.LCD.aColorIndex8[1]


  #define LCD_ACOLORINDEX  GUI_Context.LCD.aColorIndex8


#elif LCD_BITSPERPIXEL <=16


  #define LCD_BKCOLORINDEX GUI_Context.LCD.aColorIndex16[0]


  #define LCD_COLORINDEX   GUI_Context.LCD.aColorIndex16[1]


  #define LCD_ACOLORINDEX  GUI_Context.LCD.aColorIndex16


#else //增加一下几句


  #define LCD_BKCOLORINDEX GUI_Context.LCD.aColorIndex32[0]


  #define LCD_COLORINDEX   GUI_Context.LCD.aColorIndex32[1]


  #define LCD_ACOLORINDEX  GUI_Context.LCD.aColorIndex32


#endif


5.6     GUIALLOC.C


将GUI_BLOCK_ALIGN改为4个字节对齐。


#define GUI_BLOCK_ALIGN 4


5.7     LCD_L0_GENERIC.C


重新编写COLOR2INDEX()和INDEX2COLOR()。


  #define COLOR2INDEX(Color) ReverseRGB(Color)


   #define INDEX2COLOR(Index) ReverseRGB(Index)


其中,


LCD_COLOR ReverseRGB(LCD_COLOR Color)


{


   U32 r, g, b;


          r = (Color)  &0xff;


          g = (Color>>8) &0xff;


          b = (Color>>16) &0xff;       


   return b+(g<<8)+(r<<16);


}


ReverseRGB()的目的是将UC/GUI默认的BGR色彩改为RGB色彩。


6         MEMDEV的修改


6.1     GUIDEV.C


修改_DrawBitmap函数,增加BitsPerPixel==24的if语句,


  #if LCD_BITSPERPIXEL >16


    if (BitsPerPixel==24) {


      for (i=0; i<ysize; i++) {


        DrawBitLine24BPP_DDB(pUsage, x0, i+y0, (U32*)pData, xsize);


        pData += BytesPerLine;


      }


      return;


    }


  #endif


       其中DrawBitLine24BPP_DDB为,


#if LCD_BITSPERPIXEL >16


static void  DrawBitLine24BPP_DDB(GUI_USAGE* pUsage, int x, int y, const U32 *pSrc, int xsize) {


  LCD_PIXELINDEX* pDest;


  pDest = GUI_MEMDEV_XY2PTR(x,y);


  switch (GUI_Context.DrawMode & (LCD_DRAWMODE_TRANS|LCD_DRAWMODE_XOR)) {


  case 0:    /* Write mode */


    memcpy(pDest, pSrc, xsize*4);


    break;


  case LCD_DRAWMODE_TRANS:


    do {


      if (*pSrc) {


        *pDest = *pSrc;


        GUI_USAGE_AddPixel(pUsage, x,y);


      }


      x++;


      pDest++;


      pSrc++;


    } while (--xsize);


    break;


  }


}


#endif


GUI_MEMDEV_CreateEx中增加,


  #if LCD_BITSPERPIXEL <= 8


    int BytesPerLine = (( 8*xsize+15)>>4)<<1;  /* Reserve 8 bits for pixels */


  #elif LCD_BITSPERPIXEL <= 16


    int BytesPerLine = ((16*xsize+15)>>4)<<1;  /* Reserve 16 bits for pixels */


  #else //增加这一句


    int BytesPerLine = ((32*xsize+15)>>4)<<1;  /* Reserve 24 bits for pixels */


  #endif


同时修改,


#if LCD_BITSPERPIXEL <=8


  #define BITSPERPIXEL 8


#elif LCD_BITSPERPIXEL <=16


  #define BITSPERPIXEL 16


#else //增加这一句


  #define BITSPERPIXEL 24


#endif


7         测试


修改后Metromerks CodeWarrior project目录结构如下:


 


修改完成后使用UCGUI_test()函数测试,在每个delay()时设置断点,可以看显示是否正确。下面的有些语句是从《UC/GUI用户手册》中摘来的。


void UCGUI_test(void)


{


   U32 i,j;


   GUI_MEMDEV_Handle hMem;  


  


GUI_Init();


   //测试数字显示函数


   GUI_MEMDEV_Select(0);


   GUI_SetBkColor(GUI_BLACK);


   GUI_SetColor(GUI_WHITE);


   GUI_Clear();


   GUI_DispDecAt(123456, 100, 50, 9);


   GUI_DispDecAt(123456, 100, 70, 4);


   GUI_DispDecAt(-123456, 100, 90, 9);


   GUI_GotoXY(100,110);


   GUI_DispFloat(12345.6, 9);


   GUI_GotoXY(100,130);


   GUI_DispFloat(12345.6, 4);


   GUI_GotoXY(100,150);


   GUI_DispFloat(-12345.6, 9);


   GUI_GotoXY(100,170);


   GUI_DispString(GUI_GetVersionString());


   delay(600000);


  


   //测试文本显示函数


   GUI_SetBkColor(GUI_BLUE);


   GUI_Clear();


   GUI_SetPenSize(10);


   GUI_SetColor(GUI_RED);


   GUI_DrawLine(80,10,240,90);


   GUI_DrawLine(80,90,240,10);


   GUI_SetBkColor(GUI_BLACK);


   GUI_SetColor(GUI_WHITE);


   GUI_SetTextMode(GUI_TM_NORMAL);


   GUI_DispStringHCenterAt("GUI_TM_NORMAL", 160, 10);


   GUI_SetTextMode(GUI_TM_REV);


   GUI_DispStringHCenterAt("GUI_TM_REV", 160, 26);


   GUI_SetTextMode(GUI_TM_TRANS);


   GUI_DispStringHCenterAt("GUI_TM_TRANS", 160, 42);


   GUI_SetTextMode(GUI_TM_XOR);


   GUI_DispStringHCenterAt("GUI_TM_XOR", 160, 58);


   GUI_SetTextMode(GUI_TM_TRANS|GUI_TM_REV);


   GUI_DispStringHCenterAt("GUI_TM_TRANS|GUI_TM_REV", 160, 74);        


   delay(600000);


  


   //测试2-D绘图函数


   GUI_SetColor(GUI_YELLOW);


   GUI_SetBkColor(GUI_GRAY);


   GUI_Clear();


   GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);


   GUI_FillCircle(120, 64, 40);


   GUI_SetDrawMode(GUI_DRAWMODE_XOR);


   GUI_FillCircle(140, 84, 40);


   GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);


   GUI_FillRect(100, 100, 200, 200);


   GUI_InvertRect(120, 120, 180, 180);


   for(i=0;i<10;i++)


            GUI_DrawCircle(200, 200, 20*i);


   GUI_DrawBitmap(&bmsample8bpp, 200, 200);


   GUI_DrawBitmap(&bmsampleGray, 400, 200);


   delay(600000);


  


   //MEMDEV绘图设备测试,包括数字、文本、2-D绘图。


   GUI_SetColor(GUI_YELLOW);


   GUI_SetBkColor(GUI_GRAY);


   GUI_SetTextMode(GUI_TM_NORMAL);


   GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);


   GUI_Clear();


   hMem="GUI"_MEMDEV_Create(0,0,200,200);


   GUI_MEMDEV_Select(hMem);


  


   GUI_DrawBitmap(&bmsample8bpp, 0, 0);


   GUI_DispStringAt("GUI_TM_NORMAL", 0, 100);


   GUI_MEMDEV_CopyToLCD(hMem);


   delay(600000);


   GUI_Clear();


  


   GUI_GotoXY(10,10);


   GUI_DispFloat(-12345.6, 9);


   GUI_DrawLine(0,0,100,100);


   GUI_DrawLine(0,100,100,0);


   GUI_MEMDEV_CopyToLCD(hMem);


   delay(600000);


   GUI_Clear();


  


   GUI_SetPenSize(2);


   GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);


   GUI_FillCircle(50, 50, 20);


   GUI_SetDrawMode(GUI_DRAWMODE_XOR);


   GUI_FillCircle(70, 50, 20);


   GUI_SetDrawMode(GUI_DRAWMODE_NORMAL);


   for(i=0;i<10;i++)


            GUI_DrawCircle(50, 50, 5*i);


   GUI_MEMDEV_CopyToLCD(hMem);


   delay(600000);


  


   GUI_MEMDEV_Select(0);


   GUI_MEMDEV_Delete(hMem);


   GUI_Clear();


}


8         结论


进行UC/GUI移植前,必须保证LCD的初始化已经正确,可以自己编写几个底层函数,画点的、画线的、写文本、画图片的等。只有确保自己对S3C2410的LCD部分真正熟悉并掌握了,再移植UC/GUI才有把握。


将UC/GUI更改为24bpp,主要修改跟LCD_BITSPERPIXEL、LCD_COLOR定义有关的部分。如果移植过程中出现问题,可以单步跟踪进去,看是什么变量导致输出不正确。


我也没有将UC/GUI的源文件看一遍,基本上是使用仿真跟踪的方法确定哪部分需要修改。所以没有用到的部分,比如AA、WM可能还需要进一步修改,这点请按照以上步骤修改的朋友注意。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约