OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 16349|回复: 7

在STM32移植ucGUI之存储设备与抗锯齿

[复制链接]

10

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2012-8-16
在线时间
13 小时
发表于 2013-7-5 09:52:02 | 显示全部楼层 |阅读模式

更多更精彩内容见晓梦逸尘的博客:www.xiaomengyc.com
1  
存储设备

1.1   存储设备概述

存储设备用来防止显示屏在有对象重叠的绘图操作时的闪烁现象。当在液晶屏上绘制一些文字叠加在图片上的效果时,通常是先在液晶屏上绘制底层的图片,然后再在图片上叠加上文字。而如果使用了存储设备,这些操作首先是由单片机进行处理,它通过将所有的绘图操作进行综合,在其内部形成一个处理后的图像,然后再将其一次性绘制到液晶屏上。从而有效的消除了闪烁。

存储设备在ucGUI中是一个附加的可选包,它位于子目录GUI\Memdev下。当在软件中需要使用存储设备时,应首先在GUIConf.h中将该部分的预处理命令开启。

#define  GUI_SUPPORT_MEMDEV   1

存储设备的使用非常简单,通常的步骤如下所示:

1. 建立存储设备(使用 GUI_MEMDEV_Create);fficeffice" />

2. 激活它(使用 GUI_MEMDEV_Select);

3. 执行绘图操作;

4. 将结果拷贝到显示屏(使用 GUI_MEMDEV_CopyToLCD);

5. 如果你不再需要存储设备,删除它(使用 GUI_MEMDEV_Delete)。

当同一个器件用于不同的屏幕区域或存储设备的内容拷贝到不同的区域时,修改存储设备的原点比删除然后重建它更有效。此时我们可以实用void GUI_MEMDEV_SetOrg()函数。

 

1.2  分片存储设备

一个存储设备首先通过执行指定的绘图函数进行内容填充。设备填充完毕后,其内容写入LCD。有些情况下,可能没有足够的有效存储器空间能够立刻用于所有输出区域的存储,这依赖于在GUIConf.h中对GUI_ALLOC_SIZE宏的配置。一个分片存储设备将需要绘制的LCD区域分成几个片段,在每一个片段里面用尽可能多占用当前可用的存储空间。

不同于普通存储设备的是分片存储设备的使用更加简洁,只需要用GUI_RECT声明一个需要需要绘图的区域,然后调用GUI_MEMDEV_Draw()函数即可执行绘图操作。该函数原型如下所示:

int GUI_MEMDEV_Draw ( GUI_RECT* pRect,GUI_CALLBACK_VOID_P* pDraw,void* pData,

int NumLines,int Flags)

参数

含义

pRect

需要执行绘图操作的LCD区域的GUI_RECT指针

pDraw

执行绘图操作的回调函数的指针

pData

作为回调函数参数使用的一个数据结构的指针

NumLines

0(推荐)或者是存储设备使用的分段数量

Flags

0 或者 GUI_MEMDEV_HASTRANS

 

1.3   自动存储设备

一个自动设备对象是基于分片存储设备建立的,它可以再某些应用方面更有效,例如移动标志,这种情况下,在一段时间内显示屏只有一小部分要更新。

该设备能自动识别显示屏的哪一部分包含固定的对象,哪一部分包含移动或改变的对象(必须更新)。当绘图函数第一次被调用时,所有的对象都被绘制出。而以后的函数调用只更新需要移动或改变的物体。实际的绘图操作使用分片存储设备机制,但只在需要的空间内使用。使用一个自动存储设备(与直接使用分片存储设备相比)的主要优点是节省了计算时间,因为它需要更新整个显示屏。

GUI_AUTODEV_INFO 结构包含有哪些对象必须要由用户函数绘制的信息():

typedef struct

{

char DrawFixed;

} GUI_AUTODEV_INFO;

如果所有的对象都要绘制,DrawFixed 设为1。当只有被移动或改变的物体才需要绘制的

时候,设为0(由软件自动进行计算)。在使用自动绘图设备进行绘图操作时,推荐使用下面的程序结构:

typedef struct

{

GUI_AUTODEV_INFO AutoDevInfo; /* 哪些内容需要绘制的信息 */

/* 给用户函数添加使用的数据 */

……

} PARAM;

static void Draw(void * p)

{

PARAM * pParam = (PARAM *)p;

if (pParam->AutoDevInfo.DrawFixed)

{

/* 绘固定的背景 */

……

}

/* 绘制移动的物体 */

……

if (pParam->AutoDevInfo.DrawFixed)

{

/* 绘固定的前景(如果需要) */

……

}

}

void main (void)

{

PARAM Param; /* 绘图函数的参数*/

GUI_AUTODEV AutoDev; /* 分片存储设备的对象 */

/* 绘图函数的 设置/修改 信息 */

……

GUI_MEMDEV_CreateAuto(&AutoDev); /* 建立 GUI_AUTODEV 对象 */

GUI_MEMDEV_DrawAuto ( &AutoDev, /* 使用 GUI_AUTODEV 对象用于绘图 */

&aram.AutoDevInfo,

&Draw, &aram);

GUI_MEMDEV_DeleteAuto(&AutoDev); /* 删除 GUI_AUTODEV 对象 */

}

 

2  抗锯齿

ucGUI中抗锯齿是作为一个独立的部分发布的,它位于GUI\AntiAlias目录下。

 

2.1  抗锯齿的品质

抗锯齿的品质由函数GUI_AA_SetFactor设定。总共可以设置的等级为1~6,其中等级为1表示没有使用抗锯齿。一般来说抗锯齿系数取4就可以适应大部分的应用,再增加抗锯齿系数对于最终结果的影响并不显著,只会增加计算时间。

 

2.2 高分辨率坐标

当使用抗锯齿进行绘图时,使用的坐标与非抗锯齿的函数一样的,这是默认模式。在函数中不必考虑抗锯齿系数。ucGUI的高分辨率坐标特性可以使用抗锯齿系数和显示屏所决定的区域进行绘图。高分辨率坐标必须由函数GUI_AA_EnableHiRes启动,使用GUI_AA_DisableHiRes函数进行进行显示。

为了使用抗锯齿系数为3 的高分辨率模式从像素(50,100)到(100,50)绘一条直线,

程序应当这样写:

GUI_AA_DrawLine(150, 300, 300, 150);

 

3  示例代码分析

见附件
更多更精彩内容见晓梦逸尘的博客:www.xiaomengyc.com

高分辨率坐标示例.zip

1.36 MB, 下载次数: 1581

分片存储设备示例.zip

1.36 MB, 下载次数: 1778

暂不做硬件,投身机器学习和数据挖掘。欢迎交流!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-5 10:29:27 | 显示全部楼层
回复 支持 反对

使用道具 举报

4

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2013-6-25
在线时间
0 小时
发表于 2013-7-15 17:20:39 | 显示全部楼层
谢谢啦,学习中
回复 支持 反对

使用道具 举报

2

主题

16

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2012-8-28
在线时间
0 小时
发表于 2013-8-21 20:59:45 | 显示全部楼层
感谢啊
回复 支持 反对

使用道具 举报

4

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2013-10-18
在线时间
0 小时
发表于 2013-11-18 17:48:25 | 显示全部楼层
受教了
回复 支持 反对

使用道具 举报

1

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2013-3-26
在线时间
0 小时
发表于 2014-1-28 16:20:54 | 显示全部楼层
回复【楼主位】xiaomengyichen:
---------------------------------
请问一下楼主,我用uc的存储功能做了一个时钟,却发现指针的转动速度非常慢,我在回调函数中并未加入延时啊,请问我是不是应该调整一下刷屏的速率,还是该怎么办
回复 支持 反对

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
83
金钱
83
注册时间
2015-11-21
在线时间
22 小时
发表于 2016-1-21 23:45:30 | 显示全部楼层
请教一下大家,我把例程MEMDEV_MemDev.c的main里面改成这样后,它们的效果是一样的啊,请问怎么体现存储设备的作用呢?
       hMem = GUI_MEMDEV_Create(Rect.x0, Rect.y0, Rect.x1 - Rect.x0, Rect.y1 - Rect.y0);        //创建存储设备
        GUI_MEMDEV_Select(hMem);        //选择hMem作为绘制操作目标的存储设备
        _Draw(0);                                          //执行要显示的内容复制到存储设备中
        GUI_MEMDEV_Select(0);                  //选中LCD
        while (1)
        {
                for (i = 0; i < 3; i++)
                {
                        GUI_Delay(250);
                        GUI_ClearRect(LCD_GetXSize() - Rect.x1, Rect.y0, LCD_GetXSize(), Rect.y1);  //清除选中的屏幕
                        GUI_Delay(250);
                        GUI_MEMDEV_CopyToLCDAt(hMem, LCD_GetXSize() - Rect.x1, Rect.y0); //将存储设备的内容从内存复制到LCD
                }
                GUI_Delay(500);  
       

                for (i = 0; i < 3; i++)
                {
                        //未使用存储设备
                        GUI_Delay(250);
                        GUI_ClearRect(Rect.x0-3, Rect.y0-3, Rect.x1+3, Rect.y1+3);  //清除选中的屏幕
                        GUI_Delay(250);
                        _Draw(0);   //原来是_Draw(400);  的
                }
                GUI_Delay(500);  
                GUI_ClearRect(0, 150, 799, 210);
        }
回复 支持 反对

使用道具 举报

10

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
204
金钱
204
注册时间
2012-8-16
在线时间
13 小时
 楼主| 发表于 2016-4-22 20:59:57 | 显示全部楼层
电光火石 发表于 2014-1-28 16:20
回复【楼主位】xiaomengyichen:
---------------------------------
请问一下楼主,我用uc的存储功能做了一 ...

sorry...已经很久不做硬件了,转投Machine Learning 了。。。。
暂不做硬件,投身机器学习和数据挖掘。欢迎交流!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-16 22:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表