ucGUI移植笔记
- 格式:doc
- 大小:191.50 KB
- 文档页数:5
ucGUI移植详细设计及总结序本文档阐述了将ucGUI移植到IM12上的过程。
ucGUI版本为3.9,移植到IM12上,触摸屏及按键能够正常使用。
在ucGUI源码包的基础上,添加了一些接口函数以适应IM12,在使用时应该根据情况使用这些接口,这些新增加的函数的接口将在后面章节中详细讲述。
此外,适应IM12的ucGUI在Wind River Workbench 3.0环境下被编译成两个静态库文件libNoWindow.a和libWindow.a,编译程序时应该连接这两个库。
文档篇章安排如下:第一章,ucGUI源码包简介。
主要介绍了所使用的ucGUI图形库中各文件夹的内容及功能,并对IM12中与ucGUI移植相关的部分,包括触摸屏、LCD、按键板等进行了简单的介绍。
第二章,图形库移植。
阐述如何对ucGUI进行配置、编译,以在IM12的LCD上显示图形,此部分还未实现触摸屏及按键功能,只是纯粹的显示而已第三章,触摸屏移植。
第四章,按键移植。
第五章,带触摸屏及按键功能的ucGUI应用程序模板。
第一章ucGUI源码包简介ucGUI要移植到im12上,实际上就是根据im12的情况修改ucGUI中的一些配置项,或增加、删减一些程序以适应im12,同时要保持ucGUI的特性。
要做好移植工作,需对ucGUI 及IM12相关部分有足够的了解。
1.1ucGUI简介移植所采用的ucGUI版本为3.9,主要包含的文件夹如图1所示图1 ucGUI源码结构图各文件夹的主要内容如下:Config ----------- 配置文件GUI ----------- 源代码GUI_X ---------- 操作系统接口函数定义文件GUI 源代码文件:1)AntiAlias: 抗锯齿显示效果支持。
2)ConvertColor: 彩色显示的色彩转换支持。
3)ConvertMono: (b/w)和灰度显示的色彩转换支持。
4)Core: 核心文件,提供了GUI基本的功能。
移植UCGUI只需要修改3个文件:GUIConf.h,LCDConf.h,LCDDummy.c,并从源代码的Sample/GUI_X文件夹下复制GUI_X.c文件到工程的GUILib/Config目录下1、GUIConf.h刚开始移植的时候是没有RTOS的,LCD也不是触摸屏,所以GUI_OS和GUI_SUPPORT_TOUCH都定义为0,其他宏不需要修改2、LCDConf.hLCD_XSIZE、LCD_YSIZE和LCD_BITSPERPIXEL根据开发板LCD的配置定义,我用的屏的分辨率是480*272的,16位RGB;LCD_CONTROLLER必须定义成-1,表示使用自己定义的LCD驱动,这个LCD驱动是通过修改LCDDummy.c模板来实现的,因为LCDDummy.c中开始部分要判断宏LCD_CONTROLLER是否等于-1,如果不等于-1,LCDDummy.c中的内容不会被编译,当然LCD_CONTROLLER也可以定义成其他植,但和LCDDummy.c中一定要对应起来,而且不能等于UCGUI自带的LCD驱动号LCD_ON和LCD_OFF一定要定义,因为LCDDummy.c中的LCD_On()和LCD_Off()函数先判断相应的宏是否被定义,如果没定义则不会执行函数体中的内容UCGUI的初始化过程中的LCD部分是通过GUI_Init()(GUICore.c)->LCD_Init()(LCD.c)->LCD_L0_Init()(LCD_Dummy.c)实现的,因为LCDDummy.c中的LCD初始化函数LCD_L0_Init()调用LCD_INIT_CONTROLLER()宏来调用自定义的LCD初始化函数,所以要将宏LCD_INIT_CONTROLLER()定义成自定义的LCD 初始化函数GLCD_Init()。
也可以在不用修改LCD_INIT_CONTROLLER()宏,而是在LCD_L0_Init()直接调用GLCD_Init()3、LCDDummy.cLCDDummy.c文件中需要修改的函数有:1)、void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex)2)、void LCD_L0_GetPixelIndex(int x, int y)3)、void LCD_On(void)4)、void LCD_Off(void)5)、int LCD_L0_Init(void)修改如下:其中395行的SetPixelIndex函数,422行的GetPixelIndex函数,536行的GLCD_On函数,542行GLCD_Off函数都是自己在LCD驱动文件中定义的函数,LCD_INIT_CONTROLLER()也被定义成LCD驱动文件中的LCD初始化函数4、LCD驱动文件1)、头文件drv_glcd.h:#include "lpc_types.h"#include "sdram_mt48lc2m32lfb5.h"#ifndef __GLCD_DRV_H#define __GLCD_DRV_H#define C_GLCD_PIX_CLK 9000000#define C_GLCD_REFRESH_FREQ (50HZ)#define C_GLCD_H_SIZE 480#define C_GLCD_H_PULSE 41#define C_GLCD_H_FRONT_PORCH 2#define C_GLCD_H_BACK_PORCH 2#define C_GLCD_V_SIZE 272#define C_GLCD_V_PULSE 10#define C_GLCD_V_FRONT_PORCH 2#define C_GLCD_V_BACK_PORCH 2#define LCD_RED 0xf800 /* red color */#define LCD_GREEN 0x07e0 /* green color */#define LCD_BLUE 0x001f /* blue color */#define LCD_BLACK 0x0000 /* black color */#define LCD_WHITE 0xffff /* white color */#define C_GLCD_PWR_ENA_DIS_DL Y 10000#define C_GLCD_ENA_DIS_DL Y 10000extern uint16_t LCD_Frame_Buffer[C_GLCD_H_SIZE * C_GLCD_V_SIZE];void GLCD_Init(void);void GLCD_Ctrl(BOOLEAN bEna);void SetPixelIndex(int x, int y, int PixelIndex);uint16_t GetPixelIndex(int x, int y);void GLCD_On(void);void GLCD_Off(void);#endif // __GLCD_DRV_H2)、drv_glcd.c文件#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "board.h"#include "sdram_mt48lc2m32lfb5.h"#include "drv_glcd.h"#include "lpc177x_8x_clkpwr.h"#include "lpc177x_8x_pinsel.h"uint16_t LCD_Frame_Buffer[C_GLCD_H_SIZE * C_GLCD_V_SIZE];/************************************************************************** Function Name: GLCD_Init* Parameters: const uint32_t *pPain, const uint32_t * pPallete** Return: none** Description: GLCD controller init**************************************************************************/ void GLCD_Init(void){uint32_t i;//uint32_t *pDst = (uint32_t *)LCD_Frame_Buffer;//uint32_t p0,p1,p2,p3;/*Back light enable*///Turn on LCD clockCLKPWR_ConfigPPWR(CLKPWR_PCONP_PCLCD, ENABLE);// Disable cursorLPC_LCD->CRSR_CTRL &=~(1<<0);// disable GLCD controllerLPC_LCD->CTRL = 0;// 16 bppLPC_LCD->CTRL &= ~(0x07 <<1);LPC_LCD->CTRL |=(6<<1);// TFT panelLPC_LCD->CTRL |= (1<<5);// single panelLPC_LCD->CTRL &= ~(1<<7);// notmal output// LPC_LCD->CTRL &= ~(1<<8);LPC_LCD->CTRL |= (1<<8);// little endian byte orderLPC_LCD->CTRL &= ~(1<<9);// little endian pix orderLPC_LCD->CTRL &= ~(1<<10);// disable powerLPC_LCD->CTRL &= ~(1<<11);// init pixel clockLPC_SC->LCD_CFG = 1;//CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER) / ((uint32_t)C_GLCD_PIX_CLK);// bypass inrenal clk dividerLPC_LCD->POL |=(1<<26);// clock source for the LCD block is HCLKLPC_LCD->POL &= ~(1<<5);// LCDFP pin is active LOW and inactive HIGHLPC_LCD->POL |= (1<<11);// LCDLP pin is active LOW and inactive HIGH// LPC_LCD->POL |= (1<<12);LPC_LCD->POL &= ~(1<<12);// data is driven out into the LCD on the falling edge// LPC_LCD->POL |= (1<<13);LPC_LCD->POL &= ~(1<<13);// active highLPC_LCD->POL &= ~(1<<14);LPC_LCD->POL &= ~(0x3FF <<16);LPC_LCD->POL |= (C_GLCD_H_SIZE-1)<<16;// init Horizontal TimingLPC_LCD->TIMH = 0; //reset TIMH before set valueLPC_LCD->TIMH |= (C_GLCD_H_BACK_PORCH - 1)<<24;LPC_LCD->TIMH |= (C_GLCD_H_FRONT_PORCH - 1)<<16;LPC_LCD->TIMH |= (C_GLCD_H_PULSE - 1)<<8;LPC_LCD->TIMH |= ((C_GLCD_H_SIZE/16) - 1)<<2;// init Vertical TimingLPC_LCD->TIMV = 0; //reset TIMV value before settingLPC_LCD->TIMV |= (C_GLCD_V_BACK_PORCH)<<24;LPC_LCD->TIMV |= (C_GLCD_V_FRONT_PORCH)<<16;LPC_LCD->TIMV |= (C_GLCD_V_PULSE - 1)<<10;LPC_LCD->TIMV |= C_GLCD_V_SIZE - 1;// Frame Base Address doubleword alignedLPC_LCD->UPBASE = (uint32_t)LCD_Frame_Buffer & ~7UL ;LPC_LCD->LPBASE = (uint32_t)LCD_Frame_Buffer & ~7UL ;for(i = C_GLCD_ENA_DIS_DL Y; i; i--);return ;}/************************************************************************* * Function Name: GLCD_Ctrl* Parameters: Bool bEna** Return: none** Description: GLCD enable disabe sequence**************************************************************************/void GLCD_Ctrl (BOOLEAN bEna){volatile uint32_t i;if (bEna){// LCD_CTRL_bit.LcdEn = 1;LPC_LCD->CTRL |= (1<<0);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdPwr= 1; // enable powerLPC_LCD->CTRL |= (1<<11);}else{// LCD_CTRL_bit.LcdPwr= 0; // disable powerLPC_LCD->CTRL &= ~(1<<11);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdEn = 0;LPC_LCD->CTRL &= ~(1<<0);}}void SetPixelIndex(int x, int y, int PixelIndex){if ((x < C_GLCD_H_SIZE) && (y < C_GLCD_V_SIZE)) {LCD_Frame_Buffer[x + y * C_GLCD_H_SIZE] = (uint16_t)PixelIndex;}}uint16_t GetPixelIndex(int x, int y){if ((x < C_GLCD_H_SIZE) && (y < C_GLCD_V_SIZE)) {return LCD_Frame_Buffer[x + y * C_GLCD_H_SIZE];}return 0;}void GLCD_On(void){uint32_t i;// LCD_CTRL_bit.LcdEn = 1;LPC_LCD->CTRL |= (1<<0);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--);// LCD_CTRL_bit.LcdPwr= 1; // enable powerLPC_LCD->CTRL |= (1<<11);}void GLCD_Off(void){uint32_t i;// LCD_CTRL_bit.LcdPwr= 0; // disable power LPC_LCD->CTRL &= ~(1<<11);for(i = C_GLCD_PWR_ENA_DIS_DL Y; i; i--); // LCD_CTRL_bit.LcdEn = 0;LPC_LCD->CTRL &= ~(1<<0);}。
嵌入式图形用户界面uc/gui在nios II上的移植uc/gui是一个优秀的嵌入式图形用户界面,这几天的工作就是将它移植到nios II系统上。
前人也做了一些工作,不过大部分都是针对其他硬核处理器,针对nios II软核处理器的移植资料那简直是凤毛麟角。
在阅读了相关文档后,我决定自己亲自动手实践,这下面的很多过程都是自己摸索出来的,并通过了实验的验证。
这只是一个初步的移植,也许在以后的更复杂的应用中,还需要对其进行调整。
但对目前我的应用而言,应该足够了。
写这篇文章的目的一是由于自己记性不好,所以需要给自己留个备忘,免得以后忘的一干二净;二是给有需要的朋友提供一些参考,也好相互交流,共同进步。
请大家多提宝贵意见。
一、源码和文档下载/上有很多不同版本的源码下载,目前能下到的最新版本是3.98,不过还有一些组件不是很完整,但作基础开发已经够用了。
ucgui3.98源码下载地址:uC-GUI-V3-98.zip。
ucgui最新版用户手册下载地址:uC-GUI-user.rar。
开发软件:quartus II 6.0, Nios II IDE 6.0。
二、移植过程先来看看解压后都有些什么东西:如图,核心的东西包括Config和GUI两个文件夹,这里面是ucgui的所有源码和配置文件。
ConvertColor包含彩色转换函数,ConvertMono包含灰度到彩色转换的函数,Core包含核心程序,Font是字体文件,LCDDriver包含多种控制器驱动,Widget是窗口控件库,WM是窗口库,提供复杂的功能。
其他文件夹包含一些应用范例以及一些有用的工具,留待慢慢探索。
1、config文件的移植:Config文件夹是ucgui的配置文件夹,里面有3个文件:GUIConf.h:gui的基本属性配置文件,有很多开关可以配置,具体可以参考ucgui的用户手册,这里只需配置几个必要的参数如下:#ifndef GUICONF_H#define GUICONF_H#define GUI_OS (1) /* 支持操作系统,nios系统自带了ucosII,所以我们选择此项,使gui支持该操作系统*/#define GUI_SUPPORT_TOUCH (0) /* 支持触摸屏,由于暂时没有用触摸屏,所以关掉这个开关*/#define GUI_SUPPORT_MOUSE (0) /* 支持鼠标,暂时关闭*/#define GUI_SUPPORT_UNICODE (1) /* Unicode字符串支持*/#define GUI_DEFAULT_FONT &GUI_Font6x8/* 默认字体*/#define GUI_ALLOC_SIZE 12500/* WM和memery device分配的内存*/ #define GUI_WINSUPPORT 1 /* Window manager available */#define GUI_SUPPORT_MEMDEV 0 /* Memory devices available,由于下载到的源代码中缺少memery device组件的源码,所以关闭此项*/#define GUI_SUPPORT_AA 1 /* Anti aliasing available */#endif /* Avoid multiple inclusion */LCDConf.h:LCD控制器的硬件配置文件,这个文件与硬件直接相关,一般是根据你所使用的LCD的类型和所用的LCD控制器的类型来配置。
UCGUI在44BO上的移植在网络上看到已经有不少人把UCGUI成功移植到44BO上了不过他们只提供了他们的演示程序而公开他们的移植方法过程这里我把我的移植过程写写希望对各位有帮助我们采用的是思创嵌入式开发网研发的S3C44B0黄金开发板及其液晶显示模块我的移植分两个大部分来做的一是液晶的正确初始化二是UCGUI移植原本应该包括触控屏的移植可是因为IAR下的中断一直没有调通就没有做触控屏的移植我的液晶是320240 16灰度的跟44BO的连接方式是4位单扫描一液晶的正确初始化液晶的初始化可以参照下面的函数最后得到显示缓冲区数组跟视窗屏幕的对应关系如下事实上液晶的正确初始化就是需要明确显示缓冲区跟视窗屏幕的对应关系为了达到这个目的可是通过单步调试逐个显示点来观察这种对应关系在上图中那就是这样一个顺序Bmp[0]=0xF000;//点0Bmp[0]=0xFF00;//点0 1Bmp[0]=0xFFF0;//点01 2Bmp[0]=0xFFFF;//点012 3单步执行查看液晶屏上显示点的位置这样就可以确定对应关系了这44BO中的液晶控制寄存器中有BSWP这个设置位它是用于调整每4个字节的字节顺序的也是通过单步调试来明确这种对应关系的#define SCR_XSIZE (320)//视窗屏幕大小#define SCR_YSIZE (240)#define LCD_XSIZE (320)//液晶屏幕大小#define LCD_YSIZE (240)#define MVAL_USED (0)#define MVAL (13)#define INVCLK (0)#define INVFRAME (0)#define INVLINE (0)#define CLKVAL_SL (8) //VCLK=MCLK/(CLKVAL*2) (CLKVAL >= 2)#define M5D(n) ((n) & 0x1fffff)#define ARRAY_SIZE_G16 (SCR_XSIZE*SCR_YSIZE)unsigned short Bmp[ARRAY_SIZE_G16/2];//液晶显示缓冲数组#define CLKVAL_G16 (10) //40Mhz, CLKVAL=10 ->101HzHOZVAL(LCD_XSIZE/4-1)#define(LCD_YSIZE-1)#defineLINEVALMVAL (13)#defineBSWP (1)//这个决定了每4个字节的顺序是否进行交换#define#define MODESEL (2)//Gray 16void LcdInit(void){//The following value has to be changed for better display.rDITHMODE=0x12210;//rDITHMODE=0x0;rDP1_2 =0xa5a5;=0xba5da65;rDP4_7=0xa5a5f;rDP3_5rDP2_3=0xd6b;=0xeb7b5ed;rDP5_7rDP3_4=0x7dbe;=0x7ebdf;rDP4_5=0x7fdfbfe;rDP6_7rLCDCON1 = (0)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G16<<12);// disable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,rLCDCON2 = (LINEVAL)|(HOZVAL<<10)|(10<<21);//LINEBLANK=10 (without any calculation)rLCDSADDR1 = (MODESEL<<27) | ( ((uint)Bmp>>22)<<21 ) | M5D((uint)Bmp>>1);// 16-gray, LCDBANK, LCDBASEUrLCDSADDR2 = (BSWP<<29)|M5D((((uint)Bmp+(SCR_XSIZE*LCD_YSIZE/2))>>1))|(MVAL<<21);rLCDSADDR3 = (LCD_XSIZE/4) | ( ((SCR_XSIZE-LCD_XSIZE)/4)<<9 );rLCDCON1 = (1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_G16<<12);}二UCGUI的移植移植的思路是使用UCGUI支持的buffer型的LCD控制器EPSON 1375我想就是这样一个使用双口RAM的LCD 控制器吧因为我注意到UCGUI的代码中若是使用1375控制器时需要定义四个读写函数#define LCD_READ_MEM(Off) *((U16*) (0xc00000+(((U32)(Off))<<1)))#define LCD_WRITE_MEM(Off,data) *((U16*) (0xc00000+(((U32)(Off))<<1)))=data#define LCD_READ_REG(Off) *((volatile U16*)(0xc1ffe0+(((U16)(Off))<<1)))#define LCD_WRITE_REG(Off,data) *((volatile U16*)(0xc1ffe0+(((U16)(Off))<<1)))=data前两个是读写内存的定义后两个是读写寄存器的定义注意到常数0xc00000和0xc1ffe0没有0xc00000是1375控制器的显示缓冲区开始地址(Base Address)0xc1ffe0是1375控制器的寄存器开始地址(Base Address)读写显示缓冲区就是根据地址偏移off和开始地址0xc00000来读写Buffer的读写控制寄存器就是根据地址偏移off和开始地址0xc1ffe0来读写Buffer的我想可以使用欺骗的一招我们把我们液晶的显示缓冲区的开始地址(Bmp[0])告诉这几个函数那么就可以了而读写寄存器的两个函数我们就不用了等我移植完毕我发现网络上的其它移植版本也是如此使用了1375控制器的了不信看看他们提供的演示DOME显示的液晶控制器是不是EPSON 13705在LCD.H中定义数据类型#define I8 signed char#define U8 unsigned char /* unsigned 8 bits. */#define I16 signed short /* signed 16 bits. */#define U16 unsigned short /* unsigned 16 bits. */#define I32 signed long /* signed 32 bits. */#define U32 unsigned long /* unsigned 32 bits. */#define I16P I16 /* signed 16 bits OR MORE ! */#define U16P U16 /* unsigned 16 bits OR MORE ! */在LCDConf.H中定义#define LCD_XSIZE (320) /* X-resolution of LCD, Logical coor. */#define LCD_YSIZE (240) /* Y-resolution of LCD, Logical coor. */#define LCD_BITSPERPIXEL (4) //16灰度#define LCD_CONTROLLER 1375extern unsigned short Bmp[]; //引入显示缓冲区数组#define LCD_READ_MEM(Off) *((U16*) (Bmp+(((U32)(Off)))))#define LCD_WRITE_MEM(Off,data) *((U16*) (Bmp+(((U32)(Off)))))=data//#define LCD_READ_REG(Off) //这个函数可以不用定义反正我们没有用到#define LCD_WRITE_REG(Off,data) //有些地方用到了定义为空避免做大改动#define LCD_SWAP_BYTE_ORDER (1) //这个是做字节转换的在LCD13XX.C中定义液晶总线宽度#ifndef LCD_BUSWIDTH#define LCD_BUSWIDTH (16)#endif这里提及关键对应部分->定义显示缓冲区时使用的short数据类型,它是16bit的:unsigned short Bmp[ARRAY_SIZE_G16/2];//液晶显示缓冲数组->定义读写缓冲区时使用的数据类型,也是16bit的U16:#define LCD_READ_MEM(Off) *((U16*) (Bmp+(((U32)(Off)))))#define LCD_WRITE_MEM(Off,data) *((U16*) (Bmp+(((U32)(Off)))))=data//#define LCD_READ_REG(Off) //这个函数可以不用定义反正我们没有用到#define LCD_WRITE_REG(Off,data) //有些地方用到了定义为空避免做大改动 ->定义液晶总线宽度定义位16bit的#ifndef LCD_BUSWIDTH#define LCD_BUSWIDTH (16)#endif->定义字节顺序#define LCD_SWAP_BYTE_ORDER (1) //16bit时需要交换的读者已经能看到了对应关系了都是使用16bit的数据类型这是关键别用错了由此延伸若是把这些对应关系换成8bit的数据类型如下->定义显示缓冲区时使用的char数据类型,它是8bit的:unsigned char Bmp[ARRAY_SIZE_G16];//液晶显示缓冲数组->定义读写缓冲区时使用的数据类型,也是8bit的U8:#define LCD_READ_MEM(Off) *((U8*) (Bmp+(((U32)(Off)))))#define LCD_WRITE_MEM(Off,data) *((U8*) (Bmp+(((U32)(Off)))))=data//#define LCD_READ_REG(Off) //这个函数可以不用定义反正我们没有用到#define LCD_WRITE_REG(Off,data) //有些地方用到了定义为空避免做大改动 ->定义液晶总线宽度定义位8bit的#ifndef LCD_BUSWIDTH#define LCD_BUSWIDTH (8)#endif->定义字节顺序#define LCD_SWAP_BYTE_ORDER (0) //8bit时不需要交换的这样的对应关系也是可行的我测试过不过若是你想把它换成32bit的话就不行了因为UCGUI不支持32bit 的液晶总线宽度的以上两部分是整个移植工作的关键当然还有一些繁琐的事情请阅读UCGUI的手册中Getting Started一章在IAR下移植时需要建立group对照文件夹加入UCGUI代码需要说明的是除了LCDDriver下只加入LCD13XX.C在Config下额外加入GUI_X.C外其余的都是加入相应文件夹中的所有C文件我还额外加入了跟开发板有关的文件:LCDLIB.C(液晶的初始化函数LcdInit())Platform.C(板级初始化函数它会调用LcdInit()来初始化液晶控制器)设置include路径:我加入的inclide路径为D:\Program Files\IAR Systems\UCGUI\gui\core\D:\Program Files\IAR Systems\UCGUI\Config\D:\Program Files\IAR Systems\UCGUI\gui\WM\D:\Program Files\IAR Systems\UCGUI\gui\Widget\D:\Program Files\IAR Systems\UCGUI\Sample\GUIDemo\在GUIConf.H中定义#define GUI_OS (0) /* Compile with multitasking support */#define GUI_WINSUPPORT (1) /* Use window manager if true (1) */#define GUI_SUPPORT_MEMDEV (1) /* Support memory devices */#define GUI_SUPPORT_TOUCH (0) /* Support a touch screen (req. win-manager) */#define GUI_SUPPORT_UNICODE (1) /* Support mixed ASCII/UNICODE strings */我们还没有移植到OS上也没有加入触摸屏的支持在GUI_X.C中定义三个未定义的函数void GUI_X_Log (const char *s) {}void GUI_X_Warn (const char *s) {}void GUI_X_ErrorOut(const char *s) {}修改一个函数定义void GUI_X_Delay(int ms) {// int tEnd = OS_TimeMS + ms;// while ((tEnd - OS_TimeMS) > 0);extern void Delay(int time);//我自己的延时函数Delay(150*ms);}原因是在UCGUI的应用中有一些函数是跟时间相关的UCGUI认为使用的是UCOS UCOS会维护时间OS_TimeMS;这里我调用我自己的延迟程序来实现延迟事实上正是因为有一些函数跟时间有关因此在UCGUI提供的演示程序中就出现了问题例如在GUIDEMO_Speed.C中有这么个循环for (i = 0; (((t + 8000) - (int)GUI_GetTime()) > 0) && !GUIDEMO_CheckCancel(); i++) {}它调用了GUI_GetTime读取当前系统时间来控制循环若是系统没有维护时间OS_TimeMS那就会出问题了我的简单解决方法是改为for (i = 0;i<0xFFF;i++){}在其它的GUIDEMO_XXXX.C中也有这样一些循环你要是调试是发现液晶屏上的显示一直停在一个画面上很久的话估计就是碰上了上面的问题好了加入那个最简单的主函数Basic_Helloworld.Cvoid BoardInit (void);void main(void) {/*ToDo: Make sure hardware is initilized first!!*/BoardInit ();//板级初始化它调用了LcdInit()GUI_Init();GUI_DispString("Hello world!");while(1);}应该能在你的液晶屏上看到UCGUI跟你打招呼的了"Hello world!"这样UCGUI的移植基本上已经完成了当然了这里只提供了移植关键的部分更多的更完整的移植还需要做不少的工作如触控屏的移植键盘鼠标的移植中文字体的移植UCGUI支持UNICODE中文字体不成大问题的还有DEBUG输出的移植不难吧直接输出到串口不久可以了嘛若是在做UCGUI的移植前你的系统已经使用同一个编译环境移植了UCOS那么UCGUI的演示效果将是更好的原因就是由于UCGUI中有一些跟时间相关的调用――liandaolycld@。
uC/GUI NIOS II移植及应用笔记这是前些日子在使用uc/GUI的时候即下来的一些东西原来发布在EDACN的bbs上面。
现在不知道沉到哪里去了。
现在把它重新整理发布在这里。
随后在明年过年的时候把后续的几个高级主题整理出来。
下面开始我的笔记!有兴趣的兄弟们可以来看看。
step1.下载uC/GUI的代码。
(废话没有源代码移植个鸟)我下载的时uC/GUI3.32这是能得到的源代码中最全的一个版本。
看看里面都有些什么东西。
由于这里的发间大小的限制的问题不能上传源代码。
很是郁闷。
有需要的同志可以联系我。
Email:william7447@首先看看所有名叫Simulation的东西这是uC/GUI在VC中仿真的VC工程,他的仿真功能非常的实用可以在没有具体硬件的情况下先行开发软件,而丝毫不影响软件的兼容性。
但是有一个问题比较郁闷,就是速度的问题。
大家知道嵌入式系统的CPU运算能力有限,而电脑的cpu.........我的整个项目的gui是在电脑上完成的。
拿到目标系统上面编译.......通过。
经过紧张的下载.....................运行..........显示出了第一个画面,无比的兴奋。
但测试发现极其郁闷而几乎无法解决的问题......目标系统的处理能力只有100mips而我的电脑的cpu是P4 3.0。
速度的差别太大了。
解决这个问题几乎成了我后半段工作的主题。
GUI文件夹存放全部uC/GUI源代码的地方看看它的属性有多达390个文件,全部是.c和.h。
可以看出GUI系统是一个庞大复杂的东西。
我在调试系统的时候跟踪过完整的消息循环再进入了60多个子函数调用后还没有看到希望,就彻底的放弃了跟踪的想法。
下来会具体说明这里面都有些什么东西。
config文件夹uC/GUI的配置文件夹。
里面存放的是uC/GUI的配置头文件。
改动里面的相应的就可以改动uC/GUI的配置。
这个GUI功能十分强大。
ucGUI移植笔记完善版最近在弄ucGUI的移植,网上搜了不少资料,也问了同学,总算把简单的一个程序弄好了,也感谢openedv论坛和hua290565456的网友,看了他的贴子,才恍然大悟弄好。
该程序是直接用的原子大哥的TFTLCD显示的例子,直接拿过来移植的,感谢原子大哥的程序,在我学习STM32的旅途上帮助我不少。
所用到的是原子大哥TFTLCD例子(库函数版本)和ucGUI3.90源码。
建工程就不说了,附件里有,相信大家也看到别人建的工程了,下面直接说重点。
补充说明:如果你移植的时候怎么也不成功,大部分原因是GUI无法初始化LCD。
考虑两方面的原因:一、你写的底层驱动程序;二、底层驱动程序与GUI系统的接口,即GUI的配置。
所有的问题几乎都是出现在这两方面,造成GUI无法成功调用正确的底层初始化程序。
所以:1.确保你的底层驱动在没有移植GUI之前,能顺序驱动LCD成功。
2.然后,确保你的底层驱动接口没有与上层GUI有相同的公共的变量。
可以有同名的变量,但所有的变量都必须是私有的。
也就是原子哥的那个结构体LCD不能在.h中定义。
如果LCD驱动文件是lcd.c和lcd.h,最好改为别的名字,比如ili93xx.c和ili93xx.h。
然后还要把LCD_Init()初始化函数改为LCDx_Init();因为GUI系统已经有名为LCD.c的文件和LCD_Init()的函数。
总而言之,确保你的底层的接口文件(xx.h)没有与上层同名的公共变量。
3.修改GUI系统与底层的接口:A.LCDConf.h中按照下面的图就行,其余的可以删除掉,一定要删除其他的,因为有相同的LCD_CONTROLLER定义,会造成硬件出错而进入硬件出错中断死循环。
注意红框中是刚刚改过的LCD初始化函数,改为刚刚更改的初始化函数就行。
B.接下来是GUIConf.h中的设置,目前只是用到简单的一个现实函数,多以就全部设为0C.然后是LCDDummy.c。
uCGUI学习笔记最近一段时间以来,准备移植uCGUI。
在网络上找了大量的移植资料和学习教程,但都没有什么突破性进展。
不知道是自己水平有限,还是网络上的资料不够系统,总是不得入门之路。
经过自己的不断努力,感觉移植并不是什么难事,关键是要知道移植的过程。
现将学习中遇到的问题和已经记录下来,方面自己的翻阅,已可以为初学者提供一条捷径。
一、 uCGUI的了解:在移植之前最好对uCGUI有一定的了解,这样会加快移植的速度,也可以减少不少弯路。
①.最好通读一遍《uCGUI用户手册》,在网络上有很多。
有中文版也有英文版的,里边详细的介绍了uCGUI的所有API函数及一些例程,并提供了配置说明。
特别是从20章开始就跟移植有很大的关系,而前面的十几章主要是介绍应用。
②.对源代码要有所了解,当然这方面的介绍在《uCGUI用户手册》的第二章中也有。
不过不同版本的文件夹有所不同,但内核基本是相同的就是加了些附加功能而已。
下表显示了GUI 所有子目录的内容:(带“*”标志的为可选项,不同版本带的有所不同)说明:移植是要特别注意配置文件Config和GUI/LCDDriver。
①.GUI/LCDDriver文件夹中存放的是一些LCD驱动代码,如果你使用的LCD在这里可以找到代码,可以直接通过Config中的LCDConfig.h里边的:#define LCD_CONTROLLER -1// -1:表示没有选择的LCD驱动,而是使用里边的样本程序进行修改。
uCGUI中具体支持哪些LCD?可以查询《uCGUI用户手册》的第22章 LCD驱动程序。
里边详细的说明了,支持些什么控制器的LCD。
②.在工程中只需加载需要的LCD驱动代码文件即可。
如果设置为-1,则选择加载LCDDummy.C或LCDTemplate.C文件(不同的版本,此代码的文件名可能会不同)。
二、代码移植:1. 必须编写好LCD的驱动函数,当然如果uCGUI中已经包含了移植需要的LCD底层驱动,就不用再编写。
uCGUI3.90a移植教程声明:本教程是作者学习uCGUI过程中的笔记,最后整理出来,献给初学者,旨在带领初学者入门uCGUI,仅供学习之用,不得用于商业。
如需转载,请注明出处。
作者:Stone_up时间:2013-08-01版本:V1.0说明平台: stm32f103zet6 TFTLCD型号: 2.8寸9341控制器ucgui源码: 3.90a版本触屏:不带触屏(后续更新)操作系统:不支持移植教程一、准备工作:(一)源码:准备3.90版本的UCGUI源码注:如果需要跑GUIDEMO,那么还需准备GUIDEMO源码。
(二)LCD底层驱动:准备LCD屏的底层驱动,接口函数如下:1、设置坐标点;static void lcd_set_cursor(u16 xpos, u16 ypos);2、在指定点画指定颜色的点;void lcd_set_point(u16 xpos, u16 ypos, u16 color);3、读取某个点的颜色值;u16 lcd_get_point(u16 x, u16 y);4、在指定区域填充颜色(开窗口的方式,速度更快);void lcd_window_fill(u16 sx, u16 sy, u16 ex, u16 ey, u16 color);5、LCD屏初始化(主要是出厂初始化代码);void ili9341_initialize(void);注:这里列出了和UCGUI的接口函数,这些函数的具体实现需要根据自己的LCD屏具体实现这些函数。
二、移植过程(一)把UCGUI源码copy到自己的工程中,UCGUI文件夹下面,方便管理;(二)添加UCGUI源码到工程中,放在对应的组下面,方便管理,如图:(三)添加头文件路径,如图:(四)打开GUI_Config文件夹,编辑GUIConf.h文件,内容如下:#define GUI_OS (0)#define GUI_SUPPORT_TOUCH (0)#define GUI_SUPPORT_UNICODE (1)#define GUI_DEFAULT_FONT &GUI_Font6x8#define GUI_ALLOC_SIZE 40*1024#define GUI_WINSUPPORT 0#define GUI_SUPPORT_MEMDEV 1#define GUI_SUPPORT_AA 1(五)打开GUI_Config文件夹,编辑LCDConf.h文件,内容如下:#define LCD_XSIZE (320)#define LCD_YSIZE (240)#define LCD_BITSPERPIXEL (16)#define LCD_CONTROLLER (-1)#define LCD_FIXEDPALETTE (565)#define LCD_SWAP_RB (1)#define LCD_INIT_CONTROLLER() ili9341_initialize();(六)打开GUI_LCDDriver文件夹,编辑LCDDummy.c文件,内容如下:1、先添加LCD驱动文件的头文件,以便下面函数调用;如:#include "tftlcd.h"2、确保#if (LCD_CONTROLLER == -1) \&& (!defined(WIN32) | defined(LCD_SIMCONTROLLER))中的LCD_CONTROLLER == -1 ,和LCDConf.h中的宏定义对应3、在void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) 函数最后一行添加如下语句:lcd_set_point(xPhys, yPhys, PixelIndex);4、在unsigned int LCD_L0_GetPixelIndex(int x, int y) 函数return语句之前添加如下语句:PixelIndex = lcd_get_point(x, y);5、现在回到main函数1)添加头文#include "GUI.h"#include "GUIDEMO.h"2)在main函数中先调用必要的初始化函数后,再调用GUI_Init(); 函数,这个函数会调用LCD屏的初始化函数3)为了测试UCGUI是否初始化成功,我们先调用几个函数试试,在GUI_Init();下面接着调用如下函数:GUI_SetBkColor(GUI_BLACK);GUI_SetColor(GUI_RED);GUI_Clear();GUI_SetFont(&GUI_Font24_1);GUI_DispStringAt("- - uCGUI disp Function sample - -",4,10);// 延时3s,方便观看结果delay_ms(1000);delay_ms(1000);delay_ms(1000);看看是否把LCD刷成黑色,是否显示红色字符串4)然后再while循环中调用GUIDEMO_main(); 函数,开始运行GUIDEMO(七)定时器中断配置,给UCGUI系统一个时钟(个人观点,仅供参考),否则GUIDEMO程序无法运行1、在这里用定时器2,所以需要配置定时器和NVIC中断,配置函数大家就自己做了,只是这里的定时器配置成2KHz的频率,如果想要界面变化快点,那么提高频率即可;然后我们进入定时器2的中断函数,首先在stm32f10x_it.c 文件中加入外部变量声明extern volatile int OS_TimeMS; 然后加入定时器2中断函数,如下:void TIM2_IRQHandler(void){if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ){TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);OS_TimeMS++;if(OS_TimeMS%20==0){//GUI_TOUCH_Exec(); // 不带触摸不需要这条语句}} }后记作者新浪博客:/s/blog_9763553701018h2h.html技术讨论QQ:2898295180如有bug,恳请指出,欢迎各位网友一起讨论,一起进步,祝大家学业有成。
uCUI移植总结做了两个星期终于把gui搞通了,现将移植方法总结如下,仅供学习交流之用。
2014/8/23一、uCGUI移植步骤1、uCGUI及TFT驱动文件准备(1)将TFT驱动文件ili9320.h、ili9320.c 及其字体文件ili9320_font.h 复制至keil 工程模板的文件夹中;(2) 准备好uCGUI源文件(本例使用的版本3.90a),将START 文件夹下的GUI 文件夹全部复制到keil 工程模板的文件夹中;再将START 文件夹下的Config 文件夹复制至GUI 文件夹下;最后将Sample 文件夹下GUI_X 中的GUI_X.c 复制到Config 文件夹中。
最终文件结构如图1-1所示:图1-12、添加文件至工程,文件目录结构组如图2-2示:图2-1在添加文件时应注意uCGUI下除了gui_config 下需要添加所有的.h 头文件外其余所有均不需要添加头文件;图2-23、GUI配置(1)G UIConf.h配置:#define GUI_OS (0) /*编译多任务支持#define GUI_SUPPORT_TOUCH (0) /* 触屏支持*/#define GUI_SUPPORT_UNICODE (1) /*支持ASCII/UNICODE码*/ #define GUI_DEFAULT_FONT &GUI_Font6x8 /*初始化字体大小*/#define GUI_ALLOC_SIZE 5*1024 /*开辟动态空间大小*/图3-1注意:动态空间受芯片容量大小制约,不可开辟过大,否则报错图3-2(2) LCD 相关文件配置:LCDConfig.h 的配置#define LCD_XSIZE (320)#define LCD_YSIZE (240) /*x,y方向像素设置*/#define LCD_BITSPERPIXEL (16) /*像素位数*/#define LCD_CONTROLLER 9320 /*LCD驱动器型号*/图3-3继续修改第110行#define LCD_INIT_CONTROLLER() ili9320_Initializtion()并将其后的语句注释掉。
ucGUI移植笔记
最近在弄ucGUI的移植,网上搜了不少资料,也问了同学,总算把简单的一个程序弄好了,也感谢openedv论坛和hua290565456的网友,看了他的贴子,才恍然大悟弄好。
该程序是直接用的原子大哥的TFTLCD显示的例子,直接拿过来移植的,感谢原子大哥的程序,在我学习STM32的旅途上帮助我不少。
所用到的是原子大哥TFTLCD例子(库函数版本)和ucGUI3.90源码。
建工程就不说了,附件里有,相信大家也看到别人建的工程了,下面直接说重点。
1.如果LCD驱动文件是lcd.c和lcd.h,最好改为别的名字,比如ili93xx.c和ili93xx.h。
然
后还要把LCD_Init()初始化函数改为LCDx_Init();
2.需要改的地方:
A.LCDConf.h中按照下面的图就行,其余的可以删除掉,注意红框中是刚刚改过的LCD
初始化函数,改为刚刚更改的初始化函数就行。
B.接下来事GUIConf.h中的设置,目前只是用到简单的一个现实函数,多以就全部设
为0
C.这个是LCD驱动函数的修改,这三个最好改红框选中的文件
接下来就是更改的第一块,首先的把第1部所更改的相应的LCD底层函数的头文件加进来,不然ucGUI没办法正常工作。
然后就是第二个红框给为自己的驱动芯片型号。
再就是第二块,找到画蓝线的两个函数,用方框里的函数取代,如果是用原子大哥的,第一个函数必须要用快速画点函数,因为函数参数里有颜色这个参数,画点函数没有,如果是别的程序,也是一样,加入画点函数就行,但必须要有颜色的参数。
第二个函数就是读取某点的颜色值的函数,加进来就行,我这儿直接就用了原子大哥的程序。
3.最后修改主函数
在前面文件中不是有个宏定义嘛
这个宏定义已经在这个文件中调用,见下图哦
还有一项特别注意的,移植完后,你会发现你的屏幕先白屏一下之后就马上黑屏,而且后面无论设置什么颜色都是这样的情况。
在调用
GUI_Init()的时候,这个函数会进入LCD_Init(),然后在LCD_Init()
函数里面有着样的语句
#if (GUI_DEFAULT_BKCOLOR != GUI_INVALID_COLOR)
/* Clear video memory */
LCD_SetDrawMode(GUI_DRAWMODE_REV);
LCD_FillRect(0,0, GUI_XMAX, GUI_YMAX);
LCD_SetDrawMode(0);
#endif
这句#if (GUI_DEFAULT_BKCOLOR != GUI_INVALID_COLOR)里面的GUI_DEFAULT_BKCOLOR 初值是OXFFFF,GUI_INVALID_COLOR 初值也是0XFFFF,而原子哥的初始化函数最后有一句LCD_Clear(WHITE);这样就把GUI_INVALID_COLOR 的值设置成了0X0000;导致调用了下面的三个函数。
从而出现上面的问题。
只要把原子哥的初始化函数LCD_Clear(WHITE); 注释掉就不会错了,小问题大错误。
这是引用的hua290565456的帖子里的话,觉得很有用,就粘贴过来了。
这就是一个基本的ucGUI的移植。