一、先说说什么是EmWin,它就是一款中间软件包,弄好了之后,我们的界面设计就会变得很简单,在电脑GUI_Builder上做一个界面,生成.c文件,复制到自己的工程里面,我们的显示屏就能得到一模一样的功能。
二、在我们使用一个带触摸和显示器的系统的时候,首先就是驱动他们,做完了就应该是这样的:
也就是说我们的系统首先得有一个带触摸(不带也行)的系统,接着就是把这两个东西和EmWin关联起来。
三、EmWin基本上算是一个“系统”,一个调度显示和触摸的系统,系统也得有自己的地方,就是他需要自己的运行内存。
四、所以把EmWin移植到我们的开发板上我们需要以下三步:
1、给EmWin一个运行内存
2、把触摸得到的坐标点数据交给EmWin
3、让EmWin能够在显示屏上作图,控制显示器
具体实现起来:
1、添加与EmWin有关的所有的文件,既然使用了EmWin,我们就应该可以找到文件夹,在我们的工程文件夹下加上一个EmWin文件夹,包括如下内容:
里面具体什么不加以赘述,就是从EmWin的lib里面直接粘贴过来,最终在文件里面加上这些就可以了:
在demo里面是一些界面,都是由GUI_Builder做出来的,再经过调用就可以显示出来了。
倒数第二个lib格式的文件对应的是keil,是EmWin的库文件,换言之我们不可见的,最核心的文件。使用IAR的话就添加一个IAR的lib就好
其余的文件就是关联和配置用的,我们下面来说说:
2、先给EmWin分配动态内存,
在GUIConfig.c文件里面:
#define USE_EXRAM 1 // "1" 使用外部RAM
//设置EMWIN内存大小
#define GUI_NUMBYTES (50*1024)
#define GUI_BLOCKSIZE 0X8000 //块大小
//GUI_X_Config
//初始化的时候调用,用来设置emwin所使用的内存
void GUI_X_Config(void) {
if(USE_EXRAM) //使用外部RAM
{
U32 *aMemory = Mem_malloc(EXSRAM,GUI_NUMBYTES); //从外部SRAM中分配GUI_NUMBYTES
//字节的内存
GUI_ALLOC_AssignMemory((void*)aMemory, GUI_NUMBYTES); //为存储管理系统分配一个
//存储块
GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE); //设置存储快的平均尺寸,该区越大,可用的存
//储快数量越少
GUI_SetDefaultFont(GUI_FONT_6X8); //设置默认字体
}else //使用内部RAM
{
U32 *aMemory = Mem_malloc(INSRAM,GUI_NUMBYTES); //从内部RAM中分配GUI_NUMBYTES字
//节的内存
GUI_ALLOC_AssignMemory((U32 *)aMemory, GUI_NUMBYTES); //为存储管理系统分配一个存
//储块
GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE); //设置存储快的平均尺寸,该区越大,可用的存
//储快数量越少
GUI_SetDefaultFont(GUI_FONT_6X8); //设置默认字体
}
}
我这个例程里面的地址是由mem_malloc函数分配的,但是事实上我们只是把相应的内部或者是外部RAM地址交给EmWin就好了,使用的函数是这两个:
GUI_ALLOC_AssignMemory((void*)aMemory, GUI_NUMBYTES);
GUI_ALLOC_SetAvBlockSize(GUI_BLOCKSIZE);
3、把显示屏几交给EmWin,具体首先应该实现显示屏的驱动,也就是可以在显示屏上画色块,画点,写文字,接着就是替换函数,简言之就是告诉EmWin“我是这么画这个点的,你要是画点的话就用这个函数啊!”,EmWin在构造一个界面的时候就会“好,我们就在这里画吧,一个点一个点画,怎么画点呢?就调用程序员给我的这个函数好了”,于是就实现了EmWin对显示屏LCD的控制:
在GUIDRV_Template.c文件里:
static void _SetPixelIndex(GUI_DEVICE * pDevice, int x, int y, int PixelIndex)
{
LCD_Color_DrawPoint(x,y,PixelIndex);
}
这个函数就是EmWin用于画点的函数,里面的函数是我们画点的函数:
/****************************************************************************
* 名 称: void LCD_Color_DrawPoint(u16 x,u16 y,u16 color)
* 功 能:在设置的坐标处画相应颜色(在该点写入自定义颜色)
* 入口参数:x:x坐标
y:y坐标
color 此点的颜色值
* 返回参数:无
* 说 明:color:写入此点的颜色值 UCGUI调用该函数
****************************************************************************/
void LCD_Color_DrawPoint(u16 x,u16 y,u16 color)
{
if(lcd_id==0X9341)
{
LCD_CMD=setxcmd;
LCD_DATA=(x>>8);
LCD_DATA=(x&0XFF);
LCD_CMD=setycmd;
LCD_DATA=(y>>8);
LCD_DATA=(y&0XFF);
}
else
{
if(dir_flag==1)x=lcd_width-1-x; //横屏就是调转x,y坐标
LCD_WriteReg(setxcmd,x);
LCD_WriteReg(setycmd,y);
}
LCD_CMD=write_gramcmd;
LCD_DATA=color;
}
能看出来,这个就是我们经常用于画点的函数,以及到了基础的寄存器写入了,就是我们平常做的画点。
至此,EmWin就可以在我们的显示屏上画图了。
4、接着就是把触摸屏的数据交个EmWin
在GUI_X_Touch_Analog.c 文件里:
int GUI_TOUCH_X_MeasureX(void)
{
return RTouch_Read_XorY(0xD0); //CMD_RDX=0XD0
}
int GUI_TOUCH_X_MeasureY(void)
{
return RTouch_Read_XorY(0x90); //CMD_RDY=0X90
}
这两个函数都是EmWin直接调用的,返回值就是我们的触摸屏的返回值就好,打开用作返回的两个函数:
/****************************************************************************
* 名 称: u16 RTouch_Read_XorY(u8 xy)
* 功 能:读取一个坐标值(x或者y)
* 入口参数:xoy:指令(CMD_RDX/CMD_RDY
* 返回参数: 读到的数据
* 说 明:连续读取5次数据,对这些数据升序排列, 然后去掉最低和最1个数,取平均值
****************************************************************************/
u16 RTouch_Read_XorY(u8 xoy)
{
u16 i, j;
u16 buf[5];
u16 sum=0;
u16 temp;
for(i=0;i<5;i++)buf[i] = SPI_Read_AD(xoy);
for(i=0;i<5-1; i++) //排序
{
for(j=i+1;j<5;j++)
{
if(buf[i]>buf[j])//升序排列
{
temp=buf[i];
buf[i]=buf[j];
buf[j]=temp;
}
}
}
sum=0;
for(i=1;i<5-1;i++)sum+=buf[i];
temp=sum/(5-2*1);
return temp;
}
而那两个函数由GUI_TOUCH_Exec()函数,这个EmWin内部函数调用,这个函数就是扫描函数,定时扫描就好:
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET) //溢出中断
{
TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位
GUI_TOUCH_Exec();
}
}
定时器一定时间中断一次,扫描一下。
我们这样就将所有的有关于显示触摸的东西交给EmWin了
5、综上,首先有一个好使的带触摸屏系统,然后添加EmWin有关文件,之后把动态内存地址交给EmWin(动态内存地址不是片内RAM地址就是FSMC分配的片外RAM地址),把显示屏画点的权利交给EmWin,把触摸屏读点的权利交给EmWin。就可以通过在main函数里用GUI_INIT函数初始化EmWin,再调用demo里面的maintask();就可以实现票亮的界面了。
五、补充:以上是移植所需要的最主干的东西,具体的移植步骤我很快还会推出,另外刚才的获取触摸的方法不唯一,安富莱V6做的也很漂亮,我也会去写。
最新评论