jifu 的个人资料jifu的共享空间日志列表留言簿更多 ![]() | 帮助 |
|
|
6月23日 ucGUI基于samsung 44B0的移植小结本人在过去一段时间,由于工作缘故接触ucGUI一段时间,参考了网上的资料将ucGUI移植到44B0的目标板上。先转贴本人参考的一份资料,该份资料可以在网上搜索到: 前面我推荐了一篇网上很好的移植资料,下面是我的一些移植小结: 在这篇文章中介绍的是将gui移植到16级灰度的LCD上。我们现在移植的是256色的8位STN屏。下面是该款STN屏的接口图: 44b0 LFUBK9111A PC4 ----D7 PC5 ----D6 PC6 ----D5 PC7 ----D4 PD3 ----D3 PD2 ----D2 PD1 ----D1 PD0 ----D0 PD4 ----CL2 PD5 ----CL1 PD7 ----FLM DISP ---/DP(或接+5V) GND ----GND VDD50 --VDD(+5V) VEE -----外接+25V V0 ------VEE与GND接20K微调电阻,V0接中间脚。 4.2 LCD初始化 由于移植的LCD不一样,我们必须对文档中介绍的方法进行必要修改,下面就是我在 移植过程中觉得需要注意的地方: 1. 由于LCD的不同,文档中的44B0的初始化必须修改,下面是我在程序中用到的初 始化程序: void LcdInitlib(int depth) { rPCONC=rPCONC&~(0xff<<8)|(0xff<<8); //GPC[4:7] => VD[7:4] rLCDCON1= (0)| (2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COLOR<<12); // disable,8B_SNGL_SCAN,WDLY=8clk,WLH=8clk, rLCDCON2=(LINEVAL)|(HOZVAL_COLOR<<10)|(10<<21); //LINEBLANK=10 (without any calculation) rLCDSADDR1= (0x3<<27) | ( ((U32)frameBuffer256>>22)<<21 ) | M5D((U32)frameBuffer256>>1); // 256-color, LCDBANK, LCDBASEU rLCDSADDR2= M5D((((U32)frameBuffer256+(SCR_XSIZE*LCD_YSIZE))>>1)) | (MVAL<<21) | (1 << 29); rLCDSADDR3= (LCD_XSIZE/2) | ( ((SCR_XSIZE-LCD_XSIZE)/2)<<9 ); //The following value has to be changed for better display. rREDLUT =0xfdb96420; rGREENLUT=0xfdb96420; rBLUELUT =0xfb40; rDITHMODE=0x0; rDP1_2 =0xa5a5; rDP4_7 =0xba5da65; rDP3_5 =0xa5a5f; rDP2_3 =0xd6b; rDP5_7 =0xeb7b5ed; rDP3_4 =0x7dbe; rDP4_5 =0x7ebdf; rDP6_7 =0x7fdfbfe; rLCDCON1= (0)| (1)|(2<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_COLOR<<12); // enable,8B_SNGL_SCAN,WDLY=8clk,WLH=8clk, } } 其中frameBuffer256是显存数组。 4.3 ucgui移植 在 lcdconf.h我们对读写显存数组的宏定义进行修改 #define LCD_READ_MEM(Off) frameBuffer256[Off] #define LCD_WRITE_MEM(Off,data) frameBuffer256[Off] = data 注意不要将这两个宏定义定义成GUI原来的形式: #define LCD_READ_MEM(Off) *((U16*) (frameBuffer+(((U32)(Off))<<1))) #define LCD_WRITE_MEM(Off,data) *((U16*) (frameBuffer +(((U32)(Off))<<1)))=data 定义显存数组的时候一定要注意数据类型,还有还需要注意的是定义数组是一维数组: unsigned short int frameBuffer256[320*240/2]; 还有关于颜色显示方面,在文档上没有提及,因为44B0的RGB数据的存储模式是332模式,所以在头文件中我们还必须定义以下宏: #define LCD_FIXEDPALETTE 332 #define LCD_SWAP_RB 1 在config.h我们的定义的宏定义和文档中的一致。 #define GUI_OS (0) /* Compile with multitasking support */ #define GUI_SUPPORT_TOUCH (0) /* Support a touch screen (req. win-manager) */ #define GUI_SUPPORT_UNICODE (1) /* Support mixed ASCII/UNICODE strings */ #define GUI_DEFAULT_FONT &GUI_Font6x8 #define GUI_ALLOC_SIZE 12500 /* Size of dynamic memory ... For WM and memory devices*/ /********************************************************************* * * Configuration of available packages */ #define GUI_WINSUPPORT 0 /* Window manager package available */ #define GUI_SUPPORT_MEMDEV 1 /* Memory devices available */ #define GUI_SUPPORT_AA 1 /* Anti aliasing available */ 下面是我整个工程文件的目录结构: 在HardWare文件下,HardwareMain.c主要是硬件初始化,在这里函数会调用LCDLIB.C文件中的LCD初始化函数。就是上面介绍的到的void LcdInitlib(int depth),其中44binit.s、44BLIB.c、44BLIB_A.s是44B0的启动代码文件。其余文件是测试时使用,可以不包含。 还有在ConverColor文件下,我们只包含文件LCDPM332。C文件就可以了,因为我们只用到332模式的色彩模式。其余文件下的文件也可以精简,但是初步移植时,不建议精简。待日后实际应用时,我们可以逐步精简我们没有用到的功能文件。 原帖地址:http://hi.baidu.com/mikenoodle/blog/item/6d2f08b31bf1a1a1d8335a3e.html 6月22日 在uC/GUI中实现汉字显示以人为本的系统开发观念不断深入人心,GUI做为典型的人机交互接口,在系统开发工程中具有不可动摇的地位。易用的操作界面已成为衡量产品开发成功的重要因素。据统计,系统工程师要花去近三分之一的时间用于GUI系统的开发。完善的GUI开发系统,把设计人员从繁重的低层图形界面设计中解放出来,使其有更多的时间用于系统性能的提高。这极大的缩短了开发周期,使产品在激烈的市场竞争中抢占先机。 uC/GUI是Micrium公司专门针对嵌入式系统开发的一款通用图形界面开发系统。它提供高效的图形LCD管理,可以嵌于单任务和多任务嵌入式系统中。在小模式(small system)下,只需要100 B的RAM+500 B的STACK(RAM)+10~25 KB的ROM,全部代码用C语言完成,具有良好的可移植性,适用于各种CPU。 μC/GUI在MSGl9264液晶上的移植
μC/GUI是美国Micrium公司出品的一款针对嵌入式系统的优秀图形软件。与μC/OS一样,μC/GUI具有源码公开、可移植、可裁减、稳定性和可*性高的特点[1]。采用μC/GUI,开发人员可以很方便地在液晶上显示文本、曲线、图形以及各种窗口对象如按钮、编辑框、滑动条等,可完全产生类似于Windows的显示效果。另外,μC/GUI提供了在VC下的仿真库,这使得用户完全可以在Windows下仿真μC/GUI的各种效果。 采用μC/GUI,可以大大降低嵌入式系统中显示设计的难度,但μC/GUI的使用需针对不同的液晶编写相应的驱动程序才能实现。本文通过移植μC/GUI到MSGl9264液晶的过程,介绍了μC/GUI移植的原理以及移植中应注意的事项。 1 开发工具和运行环境 为了实现μC/GUI的移植,选用MSP430F149。MSP430F149是一款16位超低功耗单片机,具有强大的处理能力(RISC结构、125ns的指令周期)和丰富的片内外设(如硬件乘法器、ADC、定时器、看门狗等)。 它内部具有2KB的RAM和60KB的FLASH,能基本满足μC/GUI运行的需要[2]。 软件开发环境采用IAR公司的集成开发环境IAR EW430 2.10A。相对于较早的EW430 1.26A版本,2.10版本在各个方面有了较大改进,尤其是项目管理和调试上有了较大的改动,这使得移植μC/GUI更加方便。 μc/GUI针对不同的液晶控制器提供了多种驱动程序,如KS0713、SEDl335、T6963等控制器都有对应的液晶驱动程序。但在很多情况下,用户采用的液晶,μC/GUI并没有提供其对应的驱动程序,需自己着手编写特定液晶的驱动程序。 2.1 液晶显示器工作原理 为了能编写正确的液晶驱动程序,了解相应液晶的显示原理非常重要。本文采用的MSGl9264液晶为192x64点阵单色液晶,其中包含一个行驱动器KS0107B和三个列驱动器KS0108B,每个列驱动器KS0108B对应一块64x64的液晶[3]。 MSGl9264液晶的控制线为R/W、RS、CSA、CSB和LCDEN,数据线为D0~D7。RS用于指示当前的操作是数据还是寄存器,R/W用于表明当前是读还是写,CSA、CSB用于选择相应的列驱动器(其选择关系可见图1)。RS和R/W的功能可见表1,液晶显示器的读写时序见图2。 MSGl9264模块一共提供7种指令(由RW、RS及数据总线的电子决定),用于对该模块状态及显示进行控制。这7种指令包括显示开关控制、设起始行、设起始列、设页地址、读状态、读/写显示内容。通过这些指令的组合,可以控制液晶显示各种图形。 μC/GUI的软件体系结构如图3所示。μC/GUI函数库为用户程序提供GUI接口,包含的函数有文本、数值、二维图形、输入设备以及各种窗口对象。其中,输入设备可以是键盘、鼠标或触摸屏;二维图形包括图片、直线、多边形、园、椭圆、圆弧等;窗口对象包括按钮、编辑框、进度条、复选框等。μC/GUI函数库可以通过GUIConf.h文件进行配置,配置的内容包括是否采用内存设备,是否采用窗口管理器,是否支持操作系统、触摸屏,以及配置动态内存的大小等。 在LCDConf.h文件中定义了与硬件有关的各种属性,如液晶的大小、颜色以及与液晶的接口函数。而LCD驱动文件则负责把μC/GUI的各种函数解释成LCDConf.h文件中定义的液晶接口函数,这个文件与具体的硬件连接无关。 μC/GUI与LCD的硬件接口通过驱动文件把硬件接口函数转化为LCDConf.h中定义的LCD读写函数。 2.3 移植过程 2.3.1 修改LCDConf.h LCDConf.h定义了LCD的大小、颜色,对应的LCD控制器以及与硬件连接有关的LCD读写函数。按照μC/GUI的规定,底层的读写LCD函数包括LCD_WRITE_A1()(即写LCD命令)、LCD_WRITE_A0()(写LCD数据)、LCD_READ_A0()(读LCD状态)、LCD_READ_A1()(读LCD数据)。这些函数的实现与底层硬件有关,必须根据硬件连接的具体情况编写这些函数。 LCD_WRITE A1()函数的具体实现如下: #define LCD_WRITE_A1(Byte) //定义写LCD控制命令函数 { //参数Byte为要写入液晶的数据。 P40UT:Byte; //把数据放到LCD的数据线上 _NOP(); //空指令,确保能可*地写入 P1OUT&=0xef; //LCDRS=0,表示写命令 P10UTI=Ox20; //LCDEN=1 _NOP(); //空指令 P1OUT&=0xcf; //LCDEN=0,把数据写入LCD 显示RAM _NOP(); } 2.3.2 编写LCD驱动文件 图3中的μC/GUI硬件接口函数主要由表2所示函数构成。 通过分析LCDSLin文件可以发现,液晶驱动程序的核心是画点函数,大部分硬件接口函数都可由画点函数实现。因此,改造画点函数及其调用函数成为移植的重点问题。 画点函数的要求是改变液晶上任意点的颜色而不影响其他点的颜色。考虑到单片机MSP430F149的输入电压不能超过3.6V,笔者没有采取读液晶显示器内部显示RAM的方法,而是在MSP430F149的RAM中定义一个数组存储LCD显示的数据。此数组可定义为unsigned char Cache[((LCD_YSIZE+7)>>3)xLCD_XSIZE]。LCD_XSIZE、LCD_YSIZE表示液晶的大小,在LCDConf.h文件中定义。考虑到液晶的长度可能不是8的整倍数,可定义数组大小为(LCD_YSIZE+7)>>3)xLCD_XSIZE。 在定义了Cache的基础上,画点函数可如下实现: static void_SetPixel(int x,int y,LCD_PIXELINDEX c) { //画点函数 U8 Mask=1<<(y&7); //屏蔽字 int Adr=XY20FF(x,y); //由x,y的绝对位置得到 Cache中的相对位置 //XY20FF(x,y)可被定义为((y>>3)+x×((64+7)>>3)) U8 CacheByte=Cache[Adrl; //获得显示RAM的数值 if(c) //根据颜色修改显示RAM的值 CacheBytel=Mask; //对应位“置1” else CacheByte&=~Mask; //对应位清零 LCD_WRITE(Adr,CacheByte); //把CacheByte写入液晶显存并更改 Cache[Adr]的值为CacheByte } 函数的参数x,y代表要画点的位置(x为横坐标,y为纵坐标),参数c代表要画点的颜色。在函数内部,U8为μC/GUI提供的数据格式(相当于unsigned char),Mask为屏蔽字,Adr为x,y对应显示Cache的地址。 以把液晶的(5,5)处点亮为例,此时x=5,y=5,c=1,可计算出Mask=00100000,Adr=40(表示在Cache[40]处存有(5,5)点的颜色值)。由于c=1,所以应把Cache[40]中对应位“置1”,这是通过CacheByte的值“或”上Mask的值00100000实现的。最后通过调用LCD_WRITE函数把得到的新CacheByte值写入液晶对应的地址即可点亮该点。类似地,若要使某点不亮(c=0),则应该把对应位“清零”,这可以通过CacheByte&=~Mask这条命令实现。 画点函数中调用的LCD_Write函数可如下实现: static void LCD_Write(int Adr,U8 Byte){ if(CacheIAdrl!=Byte){ //若写入值与原值不符则 把写入值保存到显示RAM中 Cache[Adr]=Byte; if(LCD_Adr!=Adr){ LCD_SETADR(Adr); //设置液晶的起始行、起始列和CSA、CSB } LCD_WRITEl(Bytc); }} 由于此液晶由三块64x64的液晶组成,LCD_SETADR函数除了设置液晶的起始行、起始列外还应根据Adr的值设置CSA和CSB的值,才能写到对应的液晶屏上。此外,在LCD_WRITEl()函数中通过调用LCDConf.h文件中的LCD_WRITE_A1()和LCD_WRITE_A0()实现液晶显示。 除了_SetPixel()函数,基本函数还包括_GetPixel()函数和XorPixel()函数。_GetPixel()函数可以返回指定点的颜色信息,XorPixel()则可以对指定点颜色取反,实现“反白”的效果。由于这两个函数较简单,这里不再给出具体代码。 以函数_SetPixel()、_GetPixel()和XorPixel()为基础,结合MSGl9264液晶的7种指令就可以实现表1所给的硬件接口函数,以此构成了LCD驱动文件。 RS 功 能 0 0 1 1 3 讨论 为了能使用μC/GUI,必须调用GUI_Init()初始化。与硬件有关的初始化如CPU时钟频率的选择等既可以放在GUI_Init()中,也可以单独编写一个函数初始化。 函数名称 LCD_L0_InIt() LCD_L0_ReInIt() LCD_L0_OFF LCD_L0_ON LCD_L0_DrawBitmap() LCD_L0_DrawPixel() LCD_L0_DrwaVline() LCD_L0_DrwaVline() LCD_L0_FillRect() LCD_L0_XorPixel() 调试时应从基本的显示字符串开始,逐渐增加显示的功能和复杂度。 由于笔者采用单色液晶, 在LCDConf.h中定义LCD_FIXEDPALETFE为1;若为彩色液晶,应根据液晶支持的颜色设置LCD_FIXEDPALETYE,具体可参考手册。 若使用窗口对象,则在GUI_Conf.h中定义GUI—WINSUPPORT为1。 在GUIConf.h中定义GUI_ALLOC_SIZE为动态内存的大小,应根据需要合理选择。窗口对象(如按钮)的创建需要申请内存,若申请不到内存则无法创建,相应地创建函数值为0。可由此判断GUI_ALLOC_SIZE已经不能满足需要,一方面可以考虑增加GUI_ALLOC_SIZE(受制于芯片内存的大小);另一方面也可以删除不用的窗口对象,释放内存,再创建新的窗口对象。 采用内存设备能有效克服闪烁现象,获得更快的显示速度,但它需要额外的内存。由于MSP430F149内存较小,笔者没有采用内存设备。 可以设置窗口对象的默认字体及颜色以获得更好的显示效果。在单色液晶中,简单地改变背景颜色和字体颜色即可获得反显效果。 可以通过μC/GUI提供的软件(位图转换器和字体转换器)转换需要的图像或字体为μC/GUI格式。 由于定义的Cache占用了大量的RAM,若从液晶读回显存的值则可以省去Cache占用的RAM,但同时也会降低系统运行的速度。 在LCDConf.h文件中定义了与硬件连接有关的LCD读写函数,在液晶驱动文件中调用这些LCD读写函数。这样做的好处是使驱动文件与硬件无关,一旦一种液晶的驱动编写完毕可以很方便地移植到各种系统中而只需更改LCDConf.h即可。 上面那个转贴已经很详细的说明了UCGUI的移值过程,把UCGUI的移值所要做的工作全部都从头到尾,从深到浅讲了一遍,并且让读者知道了UCGUI的驱动的机制,把其对上的接口讲了, 而且对下LCD硬件的接口也讲了, 我想多数人看了就会明白UCGUI的驱动应该如何写了. 以后大家写简单总线型的驱动, 在UCGUI中必须完成的接口如下: [通常情况下并不是所有结口都要实现, 但是有一个是必须实现的, 就是向LCD写数据及写命令这两个接口] void LCD_X_Write00(char c);//传命令, 必须实现... 读的接口不一定要实现, 有的硬件控制器不支持从LCD读回数据, 此时一般会用到数据缓冲, 将写到LCD的数据缓存起来. 所有的驱动函数, 最终的数据都是通过如下接口写入LCD或是从LCD读取的. 这里我再进一步的将与LCD硬件部分相关的再补充几点: 1.数据/指令到LCD控制器的传送. 2.传送数据前如何设定前列地址. 3.初始化工作. 另外, 还提供了有关这种LCD屏幕的两个应用说明资料如下: http://www.ucgui.com/ucgui/LM19264A-AppNote-V0.1.pdf http://www.ucgui.com/ucgui/LM19264D-AppNote-V0.1.pdf 以及LCD屏的说明资料: http://www.ucgui.com/ucgui/LM19264BBC-Manual-Rev0.1.pdf 以及此种LCD模块的驱动,仅供参考: http://www.ucgui.com/ucgui/lcd19264.rar 一.液晶显示屏的区域 二.命令集 三.硬件连接图 四.驱动截图 原帖地址:http://www.ucgui.com/bbs/dispbbs.asp?boardID=1&ID=1307&page=1 |
|
|