别是, 如果一个一个点写, 则会出现闪的现象, 因为一个一个点的画, 如果速度慢, 可以扞到画一个复杂的图形时,是分几步一点点的画出来的。但是如果先画到内存当中, 再一次性COPY所有象素点到显示设备就不会有这种现象, 是一个连续的过程。画点时是连续的画,没有间隔。
(8)关于GUI_SUPPORT_AAGUI_SUPPORT_AA 是指是否须要对边界进行模糊填充的功能, 比如说, 画一条斜线, 可以看到是一段一段的:这样从效果上看, 那么不是特别美观, 如果可以在线的偏离的周围进行线的颜色的淡化处理,即在线的周围填充一点*近线的颜色的象素点。那么看上去将会偏离得没那么明显, 比较模糊一点。
3.2.2 GUI触摸屏的控制(Guitouch.h)
#ifndef GUITOUCH_CONF_H #define GUITOUCH_CONF_H
#define GUI_TOUCH_AD_LEFT 20 /*左边界A/D转换值*/ #define GUI_TOUCH_AD_RIGHT 240 /*右边界A/D转换值*/ #define GUI_TOUCH_SWAP_XY 1 /*是否交换X,Y轴坐标*/ #define GUI_TOUCH_MIRROR_X 0 #define GUI_TOUCH_MIRROR_Y 1 #endif
由以上可以看出.GUITouch.h 可预定义的选项很少, 只是一些数值上的定义, 基本不会影响到UCGUI 编译后的代码大小.
3.2.3 GUILCD的控制(LCDconf.h)
#define LCD_XSIZE (320) //LCD 的水平分辨率320 #define LCD_YSIZE (240) //LCD 的水平分辨率240 #define LCD_BITSPERPIXEL (8) //每像素位8 位 #define LCD_CONTROLLER 1376 //选择1376LCD 控制器
#define LCD_SWAP_BYTE_ORDER (1) //激活CPU 和LCD 控制器中的反转 #define LCD_FIXEDPALETTE (332) //指定颜色模式332(有效颜色数256) //采用完整总线接口配置
28
/*图像存储器基地址0x440000, RAM 存取16 位,相邻存储器之间的距离为2 字节*/
#define LCD_READ_MEM(Off) *((U16*) (0x440000+(((U32)(Off))<<1))) #define
LCD_WRITE_MEM(Off,data)
*((U16*)
(0x440000+(((U32)(Off))<<1)))=data
/*寄存器基地址0x400000,寄存器存取16 位,相邻寄存器之间的距离为2 字节*/ #define
LCD_READ_REG(Off)
*((volatile
U16*)(0x400000+(((U16)(Off))<<1))) #define
LCD_WRITE_REG(Off,data)*((volatile
U16*)(0x400000+(((U16)(Off))<<1)))=data
3.2.4-UcGui的移植与测试
在完成了移植后,编写了一个简单的触摸屏的检验小程序。(图3.2.4) #include \void MainTask(void) { GUI_PID_STATE TouchState; GUI_Init(); GUI_CURSOR_Show(); GUI_Delay(1000);
GUI_CURSOR_Select(&GUI_CursorCrossL); GUI_Delay(1000); while (1) {
GUI_TOUCH_GetState(&TouchState);
GUI_DispStringAt(\ GUI_DispDec(GUI_TOUCH_GetxPhys(),4); GUI_DispString(\
GUI_DispDec(GUI_TOUCH_GetyPhys(),4);
GUI_DispStringAt(\
29
GUI_DispDec(TouchState.x,4); GUI_DispString(\
GUI_DispDec(TouchState.y,4);
GUI_Delay(100); }; };
图3.2.4 简易触摸屏A/D转换
第四章.扩展内容
4.1-uCGui的消息处理机制
1.UCGUI的消息流转泵, UCGUI的执行路径是单一执行绪的, 并没有专门的消息收集以及消息处理的线程, 它是先收集到消息并马上同步处理,紧接着根据消息引起的屏幕画面变化(窗体移动/销毁/生成/尺寸及Z序变化等), 绘制变化后的屏幕画面, 主要是处理无效窗体的重绘. 在MainTask()这个用户入口点上, 调用WM_Exec1(),就可以让UCGUI的消息流转起来.
2.消息队列问题, UCGUI消息处理不用队列, 而是采取两个变量, 一个变量记载当前消息,一个变量记载先前消息, 比较两者是决定是否要处理该消息, 处理完
30
消息再将当前消息更新到先前消息变量中.这样处理起来,比起采用消息队列, 就省了不知道多少空间了,因为在启用MOSUE类设备时,移动消息是非常多的.不采用消息队列, 也导致了UGGUI中的所有的消息处理都是同步的, 但这对于UCGUI来说也不是什么严重的问题, 并不是必须的功能; 没有消息队列, 则每个消息的处理不能占用大量的时间, 否则严重影响消息处理的灵敏度,造成消息的丢失.但是这些问题都是可以接受的, 因为带来的空间效率太有帮助了.
3.消息多层挂起的问题, 由于是单一执行绪而且是同步处理所有消息, 所以如果在消息处理过程中又导致了再次调用WM_Exec1(), 进入到新的消息LOOP当中, 那么旧的消息LOOP就被永远挂起来了,在打开多话框时即产生此问题, 避免的办法:
[1].仅创建对话框,不进入对话框消息LOOP; [2].将消息LOOP放在MainTask()任务入口中调用.
虽然UCGUI的消息处理已经加入了互斥机制, 但是UCGUI中各个窗体没有单独队列, 消息都是一些全局变量, 所以开启多个任务没有实质上的意义, 因为一个任务处理完消息时,另外一个任务只能在空转, 因为消息已经处理完毕了.
4.2-UcGui支持的几种输入设备
1.按键式的键盘类输入设备.
键盘内设备的处理比较简单,UCGUI中也是采用了节约空间的微型设计方案, 只求可以正常处理设备消息即可; 具体的思路:向外提供一个键盘驱动接口, 让具体实现键盘输入设备驱动的用户, 在自己处理键盘输入驱动处调用此函数, 将得到的硬件键盘值传送给UCGUI, 即完成一次键盘事件,UCGUI就会在消息处理LOOP当中处理按键, 将其发发到UCGUI中的当前焦点窗体.
UCGUI中的键盘消息, 采用一个的全局键盘消息变量以及是否有按键的全局变量,如下所示:
static int _KeyMsgCnt; //是否有按键消息. static struct { int Key;
31
相关推荐: