硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3635|回复: 7
收起左侧

[emWin教程入门篇] 【emWin实战教程V2.0】第52章      GRAPH-图形控件

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2017-3-9 15:44:41 | 显示全部楼层 |阅读模式
完整65章+12章附件教程下载地址:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=19834





第52章      GRAPH-图形控件


        本章节为大家讲解STemWin支持的图形控件,相比前面几个章节讲解的控件,图形控件的使用要稍麻烦些。图形控件在显示数据的波形曲线时非常方便,不过这个控件也有一个缺点,显示速度慢,所以仅适合显示一些温度,湿度,CPU利用率等只需慢速更新的场合。
        52.1 初学者重要提示
        52.2 图形控件基础知识
        52.3 使用GUIBuilder创建图形控件并用模拟器显示出来
        52.4 官方WIDGET_GraphYT.c实例
        52.5 实验例程说明(RTOS)
        52.6 实验例程说明(裸机)
        52.7 总结
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-9 15:46:18 | 显示全部楼层
52.1  初学者重要提示

1、初学者爱问的问题简单汇总:
        (1)问题1:图形控件是否可以从左往右显示,系统默认都是从右往左显示?
        答:可以的,详情看这个帖子的说明http://www.armbbs.cn/forum.php?mod=viewthread&tid=22517
        (2)问题2:图形控件的显示速度比较慢,是否可以加快?
        答:不支持,图形控件的波形刷新速度的确比较慢,所以仅适合用于波形慢速刷新的场合。
2、图形控件不支持皮肤色设置。
3、图形控件的所有API函数在emWin手册中都有讲解,下图是中文版手册里面API函数位置:
2.1.png


        下图是英文版手册里面API函数的位置:
2.2.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-9 15:50:40 | 显示全部楼层
52.2 图形控件基础知识

        图形控件用于数据可视化,图形控件的典型应用是显示测量值(比如CPU利用率,温度值,湿度值等等)或函数图形的曲线,特点如下:
1、可同时显示多条曲线。
2、可使用水平和垂直刻度来标记曲线。
3、可在背景上显示具有不同水平和垂直间距的网格。
4、如果图形的可见区域无法容纳数组中所有的数据进行显示,图形控件可以自动显示滚动条,从而可通过滚动条显示数组中的所有数据。


52.2.1    图形控件的结构


        下面我们通过图形控件的结构对其有一个感性的认识,图形控件由不同种类的对象组成:
1、图形控件自身,可以附加数据对象和刻度对象。
2、可选的一个或多个数据对象。
3、可选的一个或多个刻度对象。
下图显示了图形控件的详细结构:
2.3.png

截图中每个参数表示的含义如下:
2.4.png


52.2.2   图形控件支持的曲线类型


        图形控件支持以下两种方式的曲线绘制:
2.5.png

GRAPH_DATA_XY此数据对象用于绘制由坐标值(x,y)组成的曲线,每个坐标位置确定一个点,这种方式的典型应用是绘制函数图形。
GRAPH_DATA_YT此数据对象用于绘制每个x位置都具有一个y值的曲线。这种方式的典型应用是数据连续更新的曲线。

52.2.3   图形控件支持的通知代码

        图形控件不支持通知代码。


52.2.4   图形控件支持的键盘反应(输入聚焦)


        图形控件不支持输入聚焦,这点要特别注意。不支持输入聚焦的话,外置键盘或者类似外置键盘的输入设备给图形控件发消息是没有任何反应的。
        (输入聚焦是一个重要的知识点,使用外置键盘或者类似外置键盘的输入设备要用到)

52.2.5   图形控件API函数


        图形控件的API函数比较多,对比前面章节的几个控件,图形控件的调用还是有些难度的,后面用到什么函数再跟大家详细讲解。
        本章节教程配套例子是将图形控件配合对话框一起使用的,实际项目中也推荐大家这么做,可以很方便的进行界面管理。在对话框上面使用图形框控件是通过函数GRAPH_CreateIndirect()来实现的。根据第41章41.7.1小节讲解的<WIDGET>_CreateIndirect()函数,GUI_WIDGET_CREATE_INFO结构体类型定义如下:
  1. typedef struct {
  2. GUI_WIDGET_CREATE_FUNC * pfCreateIndirect;    // 间接创建函数
  3. const char * pName;                           // 控件名(不是所有控件都需要)
  4. I16 Id;                                       // 控件ID
  5. I16 x0, y0, xSize, ySize;                     // 控件的坐标位置和大小
  6. I16 Flags;                                    // 控件用到的标志,没有就写0
  7. I32 Para;                                     // 控件用到的参数,没有就写0
  8. U32 NumExtraBytes;                            // 函数 <WIDGET>_SetUserData & <WIDGET>_GetUserData用到的
  9. // 额外字节。
  10. } GUI_WIDGET_CREATE_INFO;
复制代码
        上面结构体成员里面的标记Flags和参数Para是可选的,函数GRAPH_CreateIndirect()没有用到参数Para,但用到了标记Flags,与函数GRAPH_CreateEx的形参ExFlags是等效的,具体形参ExFlags支持哪些标记参看emWin官方手册中的说明即可
        这里举一个对话框资源列表里面创建图形控件的例子,帮助大家更好的理解:
  1. /*
  2. *********************************************************************************************************
  3. *                           宏定义
  4. *********************************************************************************************************
  5. */
  6. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
  7. #define ID_GRAPH_0    (GUI_ID_USER + 0x01)
  8. /*
  9. *********************************************************************************************************
  10. *                           GUI_WIDGET_CREATE_INFO类型数组
  11. *********************************************************************************************************
  12. */
  13. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
  14. {
  15.    { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  16.    { GRAPH_CreateIndirect, "Graph", ID_GRAPH_0, 10, 10, 400, 240, 0, 0x0, 0 },
  17. };
复制代码
上面的对话框资源列表里面依次创建了框架窗口控件,图形控件。图形控件的参数和GUI_WIDGET_CREATE_INFO结构成员的对应关系如下:

pfCreateIndirect = GRAPH_CreateIndirect;
pName = "Graph";
Id = ID_GRAPH_0;
x0 = 10;
y0 = 10;
xSize = 400;
ySzie = 240;
Flags = 0;
Para = 0;
NumExtraBytes = 0;
对于这个对应关系要注意以下两点:
1、这里的x0y0坐标位置是相对于对话框资源列表中框架窗口的客户端窗口的位置坐标。
2、Id号,这里的Id号是用户自定义的,emWin在GUI.h文件中也定义了部分绘图控件的Id号,用户是可以直接使用的:
  1. #define GUI_ID_GRAPH0     0x220
  2. #define GUI_ID_GRAPH1     0x221
  3. #define GUI_ID_GRAPH2     0x222
  4. #define GUI_ID_GRAPH3     0x223
复制代码

52.2.6   创建和删除图形控件


        创建图形控件的过程如下:
1、创建图形控件并设置所需的属性。
2、创建数据对象。
3、将数据对象附加到图形控件。
4、创建可选的刻度对象。
5、将刻度对象附加到图形控件。
附加到图形控件后,就不需要通过应用程序来删除数据和刻度对象,直接删除图形控件即可,数据对象和刻度对象会被自动删除
示例
  1. GRAPH_DATA_Handle hData;
  2. GRAPH_SCALE_Handle hScale;
  3. WM_HWIN hGraph;
  4. /* 1. 创建图形控件 */
  5. hGraph = GRAPH_CreateEx(10, 10, 216, 106, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_GRAPH0);
  6. /* 2. 创建数据对象 */
  7. hData = GRAPH_DATA_YT_Create(GUI_DARKGREEN, NumDataItems, aData0, MaxNumDataItems);
  8. /* 3. 将创建的数据对象附件到图形控件  */
  9. GRAPH_AttachData(hGraph, hData);
  10. /* 4. 创建刻度对象 */
  11. hScale = GRAPH_SCALE_Create(28, GUI_TA_RIGHT, GRAPH_SCALE_CF_VERTICAL, 20);
  12. /* 5. 将创建的可读对象附件到图形控件 */
  13. GRAPH_AttachScale(hGraph, hScale);
  14. /*
  15. 6. 操作图形控件,此时省略未写
  16. */
  17. /* 7. 不使用了,直接删除图形控件即可,数据对象和刻度对象无需再单独删除  */
  18. WM_DeleteWindow(hGraph);
复制代码

52.2.7   图形控件绘制过程


        官方手册中给了一个图形控件的绘制顺序,讲解太笼统(重点还是配合本章节配套的例子进行学习),我们这里也将其罗列出来:
1. 用背景色填充背景。
2. 调用可选的回调函数。比如,可以用这种方式绘制用户定义的网格。
3. 绘制网格(如果已启用)。
4. 绘制数据对象和边框区域。
5. 绘制刻度对象。
6. 调用可选的回调函数。比如,可以用这种方式绘制用户定义的刻度,或一些其他的文本和图形。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-9 15:55:24 | 显示全部楼层
52.3  使用GUIBuilder创建图形控件并用模拟器显示出来

        (这句话放在开头说,GUIBuilder仅仅能够创建图形控件的框架,直接使用还要做一些函数的初始化)
        首先需要大家按照第2章2.3.4小节的说明下载STemWin的软件包,其中GUIBuilder5.32位于路径:STM32Cube_FW_F4_V1.13.0\\Middlewares\\ST\\STemWin\\Software里面
2.6.png


52.3.1   第一步:建立一个对话框,主体是框架窗口
1、到GUIBuilder后,打开这个软件,并按照如下方式建立一个对话框。
2.7.png
2、修改框架窗口大小为800*480
2.8.png
3、下面设置对话框标题的字体,对齐方式,和显示的文本。首先,在建立的对话框上面右击鼠标,选择Set font
2.9.png

        弹出如下界面,并选择字体GUI_FONT_32B_ASCII,点击OK。
2.10.png

设置好字体以后再设置对齐方式,还是右击鼠标,选择Set text alignment,并选择居中
2.11.png

配置完成后,上面的文本Framewin会居中显示,然后还是鼠标右击,选择Set title text,并更改Framewin为armfly,修改的地方在左下角:
2.12.png

设置好以后,对话框就算建立完毕。

52.3.2   第二步:在对话框上面建立图形控件


        图形控件的建立方法和上面的对话框是一样的。先将图形控件拖到对话框上面,建立后的效果如下所示:
2.13.png

对于建立的图形控件,用户可以任意拖动,并通过鼠标调整其大小,调整方法如下:先左击选中相应控件,会出现绿色的边框,在边框的地方拖动鼠标即可修改大小
2.14.png

我们这里直接通过鼠标左键选中后,在左下角的表格里面设置大小为400*240。
2.15.png

设置完毕后,鼠标左键选中图形控件,右击选择Set boader sizes,设置上下左右四个边界的大小分别是10,10,20,10。
2.16.png

GUIBuilder仅支持设置这一项,别的设置不支持,需要我们在代码里面实现。

52.3.3   第三步:建立好后点击File-save


        保存方法如下:
2.17.png

保存后生成的文件在GUIBuilder5.32软件所在的文件夹里面:
2.18.png


52.3.4   第四步:在模拟器上运行GUIBuilder生成的代码


        在模拟器上面如何演示GUIBuilder生成的代码已经在第6章的6.3小节详细讲述了,这里不再赘述。可以在模拟器上面运行的完整代码如下,此代码对应的例子是V6-575_STemWin实验_Graph图形控件(模拟器):
(由于GUIBuilder创建图形控件的功能有限,我们这里要添加的代码稍多)
  1. /*********************************************************************
  2. *                                                                    *
  3. *                SEGGER Microcontroller GmbH & Co. KG                *
  4. *        Solutions for real time microcontroller applications        *
  5. *                                                                    *
  6. **********************************************************************
  7. *                                                                    *
  8. * C-file generated by:                                               *
  9. *                                                                    *
  10. *        GUI_Builder for emWin version 5.32                          *
  11. *        Compiled Oct  8 2015, 11:59:02                              *
  12. *        (c) 2015 Segger Microcontroller GmbH & Co. KG               *
  13. *                                                                    *
  14. **********************************************************************
  15. *                                                                    *
  16. *        Internet: www.segger.com  Support: support@segger.com       *
  17. *                                                                    *
  18. **********************************************************************
  19. */
  20. // USER START (Optionally insert additional includes)
  21. // USER END
  22. #include "DIALOG.h"
  23. #include "stdlib.h"
  24. /*********************************************************************
  25. *
  26. *       Defines
  27. *
  28. **********************************************************************
  29. */
  30. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
  31. #define ID_GRAPH_0 (GUI_ID_USER + 0x01)
  32. // USER START (Optionally insert additional defines)
  33. // USER END
  34. /*********************************************************************
  35. *
  36. *       Static data
  37. *
  38. **********************************************************************
  39. */
  40. static GRAPH_SCALE_Handle hScaleV;     //--------------(1)
  41. static GRAPH_DATA_Handle  ahData;
  42. // USER START (Optionally insert additional static data)
  43. // USER END
  44. /*********************************************************************
  45. *
  46. *       _aDialogCreate
  47. */
  48. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  49.   { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  50.   { GRAPH_CreateIndirect, "Graph", ID_GRAPH_0, 10, 10, 400, 240, 0, 0x0, 0 },  //--------------(2)
  51.   // USER START (Optionally insert additional widgets)
  52.   // USER END
  53. };
  54. /*********************************************************************
  55. *
  56. *       Static code
  57. *
  58. **********************************************************************
  59. */
  60. // USER START (Optionally insert additional static code)
  61. // USER END
  62. /*********************************************************************
  63. *
  64. *       _cbDialog
  65. */
  66. static void _cbDialog(WM_MESSAGE * pMsg) {
  67.   WM_HWIN hItem;
  68.   // USER START (Optionally insert additional variables)
  69.   // USER END
  70.   switch (pMsg->MsgId) {
  71.   case WM_INIT_DIALOG:
  72.     //
  73.     // Initialization of 'Framewin'
  74.     //
  75.     hItem = pMsg->hWin;
  76.     FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  77.     FRAMEWIN_SetText(hItem, "armfly");
  78.     FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  79.     //
  80.     // Initialization of 'Graph'
  81.     //
  82.     hItem = WM_GetDialogItem(pMsg->hWin, ID_GRAPH_0); //--------------(3)
  83.      /* 创建数据对象 ***********************/
  84.      ahData = GRAPH_DATA_YT_Create(GUI_GREEN, 400, 0, 0);  //--------------(4)
  85.         
  86.      /* 数据对象添加到图形控件 */
  87.      GRAPH_AttachData(hItem, ahData);  //--------------(5)
  88.      /* 设置Y轴方向的栅格间距 */
  89.      GRAPH_SetGridDistY(hItem, 20);   //--------------(6)
  90.    
  91.      /* 固定X轴方向的栅格 */
  92.     GRAPH_SetGridFixedX(hItem, 1);  //--------------(7)
  93.      /* 设置栅格可见 */
  94.     GRAPH_SetGridVis(hItem, 1);    //--------------(8)
  95.      /* 创建刻度对象  ********************/
  96.     hScaleV = GRAPH_SCALE_Create( 20, GUI_TA_RIGHT, GRAPH_SCALE_CF_VERTICAL, 20); //--------------(9)
  97.         
  98.      /* 将垂直刻度对象添加到图形控件 */
  99.     GRAPH_AttachScale(hItem, hScaleV);  //--------------(10)
  100.    
  101.      /* 用于设置比例刻度的因子 */
  102.      GRAPH_SCALE_SetFactor(hScaleV, 0.5); //--------------(11)
  103.    
  104.      /* 设置标签字体颜色 */
  105.     GRAPH_SCALE_SetTextColor(hScaleV, GUI_RED); //--------------(12)
  106.      /* 设置上下左右边界的大小 */
  107.     GRAPH_SetBorder(hItem, 20, 10, 10, 10); //--------------(13)
  108.     // USER START (Optionally insert additional code for further widget initialization)
  109.     // USER END
  110.     break;
  111.   // USER START (Optionally insert additional message handling)
  112.   // USER END
  113.   default:
  114.     WM_DefaultProc(pMsg);
  115.     break;
  116.   }
  117. }
  118. /*********************************************************************
  119. *
  120. *       Public code
  121. *
  122. **********************************************************************
  123. */
  124. /*********************************************************************
  125. *
  126. *       CreateFramewin
  127. */
  128. WM_HWIN CreateFramewin(void);
  129. WM_HWIN CreateFramewin(void) {
  130.   WM_HWIN hWin;
  131.   hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  132.   return hWin;
  133. }
  134. /*********************************************************************
  135. *
  136. *       MainTask
  137. */
  138. void MainTask(void)
  139. {
  140.      /* 初始化 */
  141.      GUI_Init();
  142.      /* 窗口自动使用存储设备 */
  143.      WM_SetCreateFlags(WM_CF_MEMDEV);
  144.      /* 创建对话框,使用GUIBulder5.32生成的对话框创建函数 */
  145.      CreateFramewin();
  146.      while(1)
  147.      {
  148.          /* 每50ms给绘图控件添加一次新的数据 */
  149.          GRAPH_DATA_YT_AddValue(ahData, rand()%100); //--------------(14)
  150.          GUI_Delay(50);
  151.      }
  152. }
  153. /*************************** End of file ****************************/
复制代码
创建的这个例子相对稍麻烦,主要实现了在对话框上面创建一个图形控件,对话框的主体是用的框架窗口控件。
1.     定义刻度对象和数据对象的句柄变量。
2.     在对话框的资源列表中创建一个图形控件。
3.     通过函数WM_GetDialogItem获得对话框上ID为ID_GRAPH_0的图形控件句柄。
4.     通过函数GRAPH_DATA_YT_Create创建数据对象,此类对象要求 x 轴上的每个点在 y 轴上都有一个值,通常用于与时间相关的图形,每个参数的定义说明如下(最后两个参数仅在首次创建的时候使用一次,以后将用不上,我们这里直接取0,不使用):
  1. ahData = GRAPH_DATA_YT_Create(GUI_GREEN,   /* 图形控件上面显示波形的颜色 */
  2. 400,   /* 此数据对象最大支持的数据个数 */
  3. 0,   /* 首次创建指向的数据地址 */
  4. 0);  /* 首次创建添加的数据个数 */
复制代码
5.     通过函数GRAPH_AttachData将数据对象附加到图形控件。
6.     通过函数GRAPH_SetGridDistY设置Y轴方向的栅格间距。
7.     通过函数GRAPH_SetGridFixedX固定X轴方向的栅格间距。
8.     通过函数GRAPH_SetGridVis设置栅格可见。
9.     通过函数GRAPH_SCALE_Create可以为图形控件创建X轴方向和Y轴方向的刻度标签,这里是创建的Y轴方向的刻度标签,此函数具体每个形参的定义说明如下:
  1. hScaleV = GRAPH_SCALE_Create( 20  /* 相对于图形控件顶边或者左边的距离,由于这里创建的是垂直刻度,所以是
  2. 左边 */,               
  3. GUI_TA_RIGHT,            /* 刻度标记的对齐方式 */
  4. GRAPH_SCALE_CF_VERTICAL, /* 绘制的垂直刻度 */
  5. 20);                     /* 刻度标记之间的间距 */
复制代码
10.  通过函数GRAPH_AttachScale将垂直标记附加到图形控件。
11.  通过函数GRAPH_SCALE_SetFactor设置垂直刻度的比例因子,比如此函数的第二个参数设置为1,那么刻度就是以实际像素为单位进行创建的,如果这里设置为0.5表示缩小到一半,也就是2个像素点代表一个刻度,设置为0.1表示缩小10倍,也就是10个像素代表一个刻度,以此类推。如果此参数的取值大于1,表示放大,比如取值10,表示0.1个像素代表一个刻度。如果还不理解的话,实际
操作下就明白了。
12.  通过函数GRAPH_SCALE_SetTextColor设置刻度标签的颜色。
13.  通过函数GRAPH_SetBorder设置上下左右四个边界的大小。如果不理解这几个参数的作用,可以在GUIBuilder上面操作这个四个边界值,就比较明白了。
14.  通过函数GRAPH_DATA_YT_AddValue给图形控件的数据对象添加数据,这里是通过GUI_Delay每50ms执行一次,从而实现慢速更新的效果。

实际显示效果如下,分辨率800*480:
2.19.png

对于这个创建和演示过程,强烈建议初学者实际动手操作。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-9 15:57:24 | 显示全部楼层
52.4  官方WIDGET_GraphYT.c实例讲解

        这个例子在模拟器中的位置:
2.20.png

主要功能介绍:
        如果打算深入学习图形控件,这个例子非常具有代表性,基本演示所有YT方式的相关API函数。另外,由于这个例子比较长,我们直接将注释写到程序代码里面
        这个例子的整体框架比较清晰,就是创建了一个对话框,在上面创建了按钮控件,滑块控件,复选框等,这些控件用于设置图形控件的显示效果,从而可以让用户很方便的查看图形控件不同配置下的不同显示效果。
程序代码如下:
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include "DIALOG.h"
  4. #include "GRAPH.h"
  5. /*********************************************************************
  6. *
  7. *       Defines
  8. *
  9. **********************************************************************
  10. */
  11. #define MAX_VALUE 180
  12. //
  13. // Recommended memory to run the sample with adequate performance
  14. //
  15. #define RECOMMENDED_MEMORY (1024L * 30)
  16. /*********************************************************************
  17. *
  18. *       Static data
  19. *
  20. **********************************************************************
  21. */
  22. static GRAPH_DATA_Handle  _ahData[3]; /* 定义三个数据对象句柄  */
  23. static GRAPH_SCALE_Handle _hScaleV;   /* 垂直刻度句柄 */
  24. static GRAPH_SCALE_Handle _hScaleH;   /* 水平刻度句柄  */
  25. static I16 _aValue[3];
  26. static int _Stop = 0;
  27. /* 三种数据对象显示曲线的颜色定义 */
  28. static GUI_COLOR _aColor[] = {GUI_RED, GUI_GREEN, GUI_LIGHTBLUE};
  29. //
  30. // 对话框资源列表
  31. //
  32. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  33.   { FRAMEWIN_CreateIndirect, "Graph widget demo",  0,   0,   0, 320, 240, FRAMEWIN_CF_MOVEABLE },
  34.   { GRAPH_CreateIndirect,     0,                   GUI_ID_GRAPH0    ,   5,   5, 265, 170 },
  35.   { TEXT_CreateIndirect,      "Spacing X:",        0                ,  10, 180,  50,  20 },
  36.   { TEXT_CreateIndirect,      "Spacing Y:",        0                ,  10, 200,  50,  20 },
  37.   { SLIDER_CreateIndirect,    0,                   GUI_ID_SLIDER0   ,  60, 180,  60,  16 },
  38.   { SLIDER_CreateIndirect,    0,                   GUI_ID_SLIDER1   ,  60, 200,  60,  16 },
  39.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK0    , 130, 180,  50,   0 },
  40.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK1    , 130, 200,  50,   0 },
  41.   { TEXT_CreateIndirect,      "Border",            0                , 275,   5,  35,  15 },
  42.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK2    , 275,  20,  35,   0 },
  43.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK3    , 275,  40,  35,   0 },
  44.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK4    , 275,  60,  35,   0 },
  45.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK5    , 275,  80,  35,   0 },
  46.   { TEXT_CreateIndirect,      "Effect",            0                , 275, 100,  35,  15 },
  47.   { RADIO_CreateIndirect,     0,                   GUI_ID_RADIO0    , 270, 115,  35,   0, 0, 3 },
  48.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK6    , 180, 180,  50,   0 },
  49.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK7    , 180, 200,  50,   0 },
  50.   { BUTTON_CreateIndirect,    "Full Screen",       GUI_ID_BUTTON0   , 240, 180,  65,  18 },
  51.   { CHECKBOX_CreateIndirect,  0,                   GUI_ID_CHECK8    , 240, 200,  70,   0 },
  52. };
  53. /*********************************************************************
  54. *
  55. *       Static code
  56. *
  57. **********************************************************************
  58. */
  59. /*********************************************************************
  60. *
  61. *       _AddValues
  62. *
  63. * 函数描述:
  64. *   为三个数据对象添加随机数。
  65. */
  66. static void _AddValues(void) {
  67.   unsigned i;
  68.   /* 通过for语句循环三次给三个数据对象_ahData[i]添加随机数 */
  69.   for (i = 0; i < GUI_COUNTOF(_aColor); i++) {
  70.     int Add = ((unsigned)rand()) % (2 + i * i);
  71.     int Vz  = (((unsigned)(rand()) % 2) << 1) - 1;
  72.     _aValue[i] += Add * Vz;
  73.     if (_aValue[i] > MAX_VALUE) {
  74.       _aValue[i] = MAX_VALUE;
  75.     } else if (_aValue[i] < 0) {
  76.       _aValue[i] = 0;
  77. }
  78. /* 将生成的随机数添加数据对象,从而更新波形数据 */
  79.     GRAPH_DATA_YT_AddValue(_ahData[i], _aValue[i]);
  80.   }
  81. }
  82. /*********************************************************************
  83. *
  84. *       _UserDraw
  85. *
  86. * 函数描述:
  87. *   在绘制之前和绘制之后调用这个函数 ,此函数只是显示字母Temperature
  88. */
  89. static void _UserDraw(WM_HWIN hWin, int Stage) {
  90.     /* 在绘制之后被调用 */
  91. if (Stage == GRAPH_DRAW_LAST) {
  92.     char acText[] = "Temperature";
  93.     GUI_RECT Rect;
  94.     GUI_RECT RectInvalid;
  95.     int FontSizeY;
  96.     /* 设置字体 */
  97.     GUI_SetFont(&GUI_Font13_ASCII);
  98. FontSizeY = GUI_GetFontSizeY();
  99. /* 获得图形控件区域坐标 */
  100.     WM_GetInsideRect(&Rect);
  101.     WM_GetInvalidRect(hWin, &RectInvalid);
  102.     Rect.x1 = Rect.x0 + FontSizeY;
  103. GUI_SetColor(GUI_YELLOW);
  104. /* 根据获取的图形控件坐标和字体的高度,将字母Temperature显示出来 */
  105.     GUI_DispStringInRectEx(acText, &Rect, GUI_TA_HCENTER, strlen(acText), GUI_ROTATE_CCW);
  106.   }
  107. }
  108. /*********************************************************************
  109. *
  110. *       _ForEach
  111. *
  112. * 函数描述:
  113. *   这个函数用于隐藏或者显示所有的窗口,除了button,graph和scroll控件
  114. */
  115. static void _ForEach(WM_HWIN hWin, void * pData) {
  116.   int Id;
  117.   int FullScreenMode;
  118.   FullScreenMode = *(int *)pData;
  119.   Id = WM_GetId(hWin);
  120.   if ((Id == GUI_ID_GRAPH0) || (Id == GUI_ID_BUTTON0) || (Id == GUI_ID_VSCROLL) || (Id == GUI_ID_HSCROLL)) {
  121.     return;
  122.   }
  123.   if (FullScreenMode) {
  124.     WM_HideWindow(hWin);
  125.   } else {
  126.     WM_ShowWindow(hWin);
  127.   }
  128. }
  129. /*********************************************************************
  130. *
  131. *       _ToggleFullScreenMode
  132. *
  133. * 函数描述:
  134. *   这个函数用于设置进入全屏模式与否,进入相应的模式以后需要放大或者缩小控件
  135. *   
  136. */
  137. static void _ToggleFullScreenMode(WM_HWIN hDlg) {
  138.   static int FullScreenMode;
  139.   static GUI_RECT Rect;
  140.   static unsigned ScalePos;
  141.   WM_HWIN hGraph;
  142.   WM_HWIN hButton;
  143.   WM_HWIN hClient;
  144.   GUI_RECT RectInside;
  145.   int xPos, yPos;
  146.   hGraph  = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  147.   hButton = WM_GetDialogItem(hDlg, GUI_ID_BUTTON0);
  148.   FullScreenMode ^= 1;
  149.   if (FullScreenMode) {      
  150.     //
  151.     // 进入全屏模式
  152.     //
  153.     hClient = WM_GetClientWindow(hDlg);
  154. BUTTON_SetText(hButton, "Back");
  155.    /* 相对移动*/
  156. WM_MoveWindow(hButton, 0, 11);
  157.     /* 隐藏框架串口标题 */
  158. FRAMEWIN_SetTitleVis(hDlg, 0);
  159.      /* 得到用户区的坐标 */
  160.     WM_GetInsideRectEx(hClient, &RectInside);
  161. /* 返回窗口大小 */
  162. WM_GetWindowRectEx(hGraph, &Rect);
  163. /* 遍历所有的子控件,并且将其隐藏 */;
  164.     WM_ForEachDesc(hClient, _ForEach, &FullScreenMode);
  165.     xPos = WM_GetWindowOrgX(hClient);
  166.     yPos = WM_GetWindowOrgY(hClient);
  167.     /* 设置窗口位置  */
  168. WM_SetWindowPos(hGraph, xPos, yPos, RectInside.x1, RectInside.y1);
  169. /* 设置水平刻度对象位置 */
  170. ScalePos = GRAPH_SCALE_SetPos(_hScaleH, RectInside.y1 - 20);
  171.   } else {
  172.     //
  173.     // 返回正常模式
  174.     //
  175.     BUTTON_SetText(hButton, "Full Screen");
  176.     WM_MoveWindow(hButton, 0, -11);
  177.     WM_ForEachDesc(WM_GetClientWindow(hDlg), _ForEach, &FullScreenMode);
  178.     WM_SetWindowPos(hGraph, Rect.x0, Rect.y0, Rect.x1 - Rect.x0 + 1, Rect.y1 - Rect.y0 + 1);
  179.     FRAMEWIN_SetTitleVis(hDlg, 1);
  180.     GRAPH_SCALE_SetPos(_hScaleH, ScalePos);
  181.   }
  182. }
  183. /*********************************************************************
  184. *
  185. *       _cbCallback
  186. *
  187. * 函数描述:
  188. *  对话框回调函数
  189. */
  190. static void _cbCallback(WM_MESSAGE * pMsg) {
  191.   unsigned i;
  192.   int      NCode;
  193.   int      Id;
  194.   int      Value;
  195.   WM_HWIN  hDlg;
  196.   WM_HWIN  hItem;
  197.   hDlg = pMsg->hWin;
  198.   switch (pMsg->MsgId) {
  199.   case WM_INIT_DIALOG:
  200.     hItem = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  201.     //
  202.     // 创建3个数据对象,并将其添加到图形控件。
  203.     //
  204.     for (i = 0; i < GUI_COUNTOF(_aColor); i++) {
  205.       _aValue[i] = rand() % 180;
  206.       /* 创建数据对象,设置了数据波形的颜色和最大支持500个数据 */
  207.       _ahData[i] = GRAPH_DATA_YT_Create(_aColor[i], 500, 0, 0);
  208.       /* 将数据对象附加到窗口控件 */
  209.       GRAPH_AttachData(hItem, _ahData[i]);
  210.     }
  211.     //
  212.     // 设置图形控件的属性
  213. //
  214. /* 设置Y轴方向栅格的高度 */
  215. GRAPH_SetGridDistY(hItem, 25);
  216. /* 设置栅格可见 */
  217. GRAPH_SetGridVis(hItem, 1);
  218. /* 固定X轴方向栅格 */
  219. GRAPH_SetGridFixedX(hItem, 1);
  220. /* 设置用户绘制 */
  221.     GRAPH_SetUserDraw(hItem, _UserDraw);
  222.     //
  223.     // 创建垂直刻度对象,并将其附加到图形控件
  224.     //
  225.     _hScaleV = GRAPH_SCALE_Create( 35, GUI_TA_RIGHT, GRAPH_SCALE_CF_VERTICAL, 25); /* 创建垂直刻度对象 */
  226.     GRAPH_SCALE_SetTextColor(_hScaleV, GUI_YELLOW); /* 设置刻度标签的颜色 */
  227.     GRAPH_AttachScale(hItem, _hScaleV); /* 将垂直刻度对象添加到图形控件  */
  228.     //
  229.     // 创建水平刻度对象,并将其附加到图形控件
  230.     //
  231.     _hScaleH = GRAPH_SCALE_Create(155, GUI_TA_HCENTER, GRAPH_SCALE_CF_HORIZONTAL, 50);/* 创建水平刻度对象*/
  232.     GRAPH_SCALE_SetTextColor(_hScaleH, GUI_DARKGREEN); /* 设置刻度标签的颜色 */
  233.     GRAPH_AttachScale(hItem, _hScaleH); /* 将水平刻度对象添加到图形控件 */
  234.     //
  235.     // 初始化复选框
  236.     //
  237.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK2);
  238.     CHECKBOX_SetText(hItem, "L");
  239.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK3);
  240.     CHECKBOX_SetText(hItem, "T");
  241.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK4);
  242.     CHECKBOX_SetText(hItem, "R");
  243.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK5);
  244.     CHECKBOX_SetText(hItem, "B");
  245.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK0);
  246.     CHECKBOX_SetText(hItem, "Stop");
  247.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK1);
  248.     CHECKBOX_SetText(hItem, "Grid");
  249.     CHECKBOX_SetState(hItem, 1);
  250.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK6);
  251.     CHECKBOX_SetText(hItem, "HScroll");
  252.     CHECKBOX_SetState(hItem, 1);
  253.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK7);
  254.     CHECKBOX_SetText(hItem, "VScroll");
  255.     hItem = WM_GetDialogItem(hDlg, GUI_ID_CHECK8);
  256.     CHECKBOX_SetText(hItem, "MirrorX");
  257.     //
  258.     // 初始化滑块控件
  259.     //
  260.     hItem = WM_GetDialogItem(hDlg, GUI_ID_SLIDER0);
  261.     SLIDER_SetRange(hItem, 0, 10);
  262.     SLIDER_SetValue(hItem, 5);
  263.     SLIDER_SetNumTicks(hItem, 6);
  264.     hItem = WM_GetDialogItem(hDlg, GUI_ID_SLIDER1);
  265.     SLIDER_SetRange(hItem, 0, 20);
  266.     SLIDER_SetValue(hItem, 5);
  267.     SLIDER_SetNumTicks(hItem, 6);
  268.     //
  269.     // 初始化单选框控件
  270.     //
  271.     hItem = WM_GetDialogItem(hDlg, GUI_ID_RADIO0);
  272.     RADIO_SetText(hItem, "3D", 0);
  273.     RADIO_SetText(hItem, "flat", 1);
  274.     RADIO_SetText(hItem, "-", 2);
  275.     //
  276.     // 初始化按钮控件
  277.     //
  278.     hItem = WM_GetDialogItem(hDlg, GUI_ID_BUTTON0);
  279.     WM_SetStayOnTop(hItem, 1);
  280.     break;
  281.   case WM_NOTIFY_PARENT:
  282.     Id    = WM_GetId(pMsg->hWinSrc);      // Id of widget
  283.     NCode = pMsg->Data.v;                 // Notification code
  284.     switch (NCode) {
  285.     case WM_NOTIFICATION_CLICKED:
  286.       switch (Id) {
  287.       /* 按钮控件点击消息实现进入全屏和退出全屏模式的反转设置 */
  288.       case GUI_ID_BUTTON0:
  289.         _ToggleFullScreenMode(hDlg);
  290.         break;
  291.       }
  292.       break;
  293.     case WM_NOTIFICATION_VALUE_CHANGED:
  294.       switch (Id) {
  295.       case GUI_ID_CHECK0:
  296.         //
  297.         // 停止和重启波形刷新的反转设置
  298.         //
  299.         _Stop ^= 1;
  300.         break;
  301.       /* */
  302.       case GUI_ID_CHECK1:
  303.         //
  304.         // 显示表格和不显示表格的反转设置
  305.         //
  306.         hItem = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  307.         GRAPH_SetGridVis(hItem, CHECKBOX_IsChecked(WM_GetDialogItem(hDlg, GUI_ID_CHECK1)));
  308.         break;
  309.       case GUI_ID_CHECK2:
  310.       case GUI_ID_CHECK3:
  311.       case GUI_ID_CHECK4:
  312.       case GUI_ID_CHECK5:
  313.         //
  314.         // 图形控件是否显示边界的反转设置
  315.         //
  316.         hItem = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  317.         GRAPH_SetBorder(hItem,
  318.                         CHECKBOX_IsChecked(WM_GetDialogItem(hDlg, GUI_ID_CHECK2)) * 40,
  319.                         CHECKBOX_IsChecked(WM_GetDialogItem(hDlg, GUI_ID_CHECK3)) * 5,
  320.                         CHECKBOX_IsChecked(WM_GetDialogItem(hDlg, GUI_ID_CHECK4)) * 5,
  321.                         CHECKBOX_IsChecked(WM_GetDialogItem(hDlg, GUI_ID_CHECK5)) * 5);
  322.         break;
  323.       case GUI_ID_SLIDER0:
  324.         //
  325.         // 水平刻度和水平表格的间距设置
  326.         //
  327.         hItem = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  328.         Value = SLIDER_GetValue(pMsg->hWinSrc) * 10;
  329.         GRAPH_SetGridDistX(hItem, Value);
  330.         GRAPH_SCALE_SetTickDist(_hScaleH, Value);
  331.         break;
  332.       case GUI_ID_SLIDER1:
  333.         //
  334.         // 垂直刻度和垂直表格的间距设置
  335.         //
  336.         hItem = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  337.         Value = SLIDER_GetValue(pMsg->hWinSrc) * 5;
  338.         GRAPH_SetGridDistY(hItem, Value);
  339.         GRAPH_SCALE_SetTickDist(_hScaleV, Value);
  340.         break;
  341.       case GUI_ID_RADIO0:
  342.         //
  343.         // 控件的三种显示效果切换
  344.         //
  345.         hItem = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  346.         switch (RADIO_GetValue(pMsg->hWinSrc)) {
  347.         case 0:
  348.           WIDGET_SetEffect(hItem, &WIDGET_Effect_3D);
  349.           break;
  350.         case 1:
  351.           WIDGET_SetEffect(hItem, &WIDGET_Effect_Simple);
  352.           break;
  353.         case 2:
  354.           WIDGET_SetEffect(hItem, &WIDGET_Effect_None);
  355.           break;
  356.         }
  357.         break;
  358.       case GUI_ID_CHECK6:
  359.         //
  360.         // 是否显示图形控件水平滚动条的反转设置
  361.         //
  362.         hItem = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  363.         if (CHECKBOX_IsChecked(WM_GetDialogItem(hDlg, GUI_ID_CHECK6))) {
  364.           GRAPH_SetVSizeX(hItem, 500);
  365.         } else {
  366.           GRAPH_SetVSizeX(hItem, 0);
  367.         }
  368.         break;
  369.       case GUI_ID_CHECK7:
  370.         //
  371.         // 是否显示图形控件垂直滚动条的反转设置
  372.         //
  373.         hItem = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  374.         if (CHECKBOX_IsChecked(WM_GetDialogItem(hDlg, GUI_ID_CHECK7))) {
  375.           GRAPH_SetVSizeY(hItem, 300);
  376.         } else {
  377.           GRAPH_SetVSizeY(hItem, 0);
  378.         }
  379.         break;
  380.       case GUI_ID_CHECK8:
  381.         //
  382.         // 设置图形控件波形的显示是从左往右,还是从右往左。
  383.         //
  384.         WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  385.         for (i = 0; i < GUI_COUNTOF(_aColor); i++) {
  386.           if (CHECKBOX_IsChecked(WM_GetDialogItem(hDlg, GUI_ID_CHECK8))) {
  387.             GRAPH_DATA_YT_SetAlign(_ahData[i], GRAPH_ALIGN_LEFT); /* 设置对其方式 */
  388.             GRAPH_DATA_YT_MirrorX (_ahData[i], 1);                /* 设置X轴镜像  */
  389.           } else {
  390.             GRAPH_DATA_YT_SetAlign(_ahData[i], GRAPH_ALIGN_RIGHT); /* 设置对其方式 */
  391.             GRAPH_DATA_YT_MirrorX (_ahData[i], 0);                 /* 设置X轴镜像  */
  392.           }
  393.         }
  394.         break;
  395.       }
  396.       break;
  397.     }
  398.     break;
  399.   default:
  400.     WM_DefaultProc(pMsg);
  401.   }
  402. }
  403. /*********************************************************************
  404. *
  405. *       Public code
  406. *
  407. **********************************************************************
  408. */
  409. /*********************************************************************
  410. *
  411. *       MainTask
  412. */
  413. void MainTask(void) {
  414.   WM_HWIN hDlg;
  415.   WM_HWIN hGraph;
  416.   hGraph = 0;
  417.   GUI_Init();
  418.   //
  419.   // Check if recommended memory for the sample is available
  420.   //
  421.   if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
  422.     GUI_ErrorOut("Not enough memory available.");
  423.     return;
  424.   }
  425.   GUI_CURSOR_Show();
  426.   WM_SetDesktopColor(GUI_BLACK);
  427.   #if GUI_SUPPORT_MEMDEV
  428.     WM_SetCreateFlags(WM_CF_MEMDEV);
  429.   #endif
  430.   hDlg = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbCallback, 0, 0, 0);
  431.   while (1) {
  432.     #ifdef WIN32
  433.       GUI_Delay(10);
  434. #endif
  435. /* 更新图形控件数据 */
  436.     if (!_Stop) {
  437.       if (!hGraph) {
  438.         hGraph = WM_GetDialogItem(hDlg, GUI_ID_GRAPH0);
  439.       }
  440.       _AddValues();
  441.     }
  442.     GUI_Exec();
  443.   }
  444. }
复制代码

实际显示效果如下:
2.21.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-9 16:03:05 | 显示全部楼层
52.5  实验例程说明(RTOS)


配套例子:
        V6-573_STemWin实验_Graph图形控件(RTOS)
实验目的:
        1.     本实验主要学习图形控件的使用。
        2.     emWin功能的实现在MainTask.c文件里面。
实验内容:
        1.     K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
        2.     K2按键按下,实现截图功能,将图片以BMP格式保存到SD卡中。
        3.     GUI任务主要在对话框上面创建了一个图形控件,每50ms更新一次数据。
        4.     各个任务实现的功能如下:
              App Task Start   任务:实现按键和触摸扫描。
              App Task MspPro任务 :实现截图功能,将图片以BMP格式保存到SD卡中。
              App Task UserIF  任务:按键消息处理。
              App Task COM   任务:暂未使用。
              App Task GUI    任务:GUI任务。
μCOS-III任务调试信息(按K1按键,串口打印):
2.22.png

STemWin界面显示效果:
         800*480分辨率界面效果。
2.23.png

STemWin动态内存配置:
        GUIConf.c文件中的配置如下:
  1. #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
  2. #if EX_SRAM
  3. #define GUI_NUMBYTES  (1024*1024*8)
  4. #else
  5. #define GUI_NUMBYTES  (100*1024)
  6. #endif
复制代码
        通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM    1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM    0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
        LCDConf_Lin_Template.c文件中共12项emWin配置:
  1. /*
  2. **********************************************************************************************************
  3.                                           用户可以配置的选项
  4. **********************************************************************************************************
  5. */
  6. /* 0. 在官方代码的基础上再做优化,官方的部分函数效率低,耗内存, 0表示优化 */
  7. #define emWin_Optimize   0
  8. /*
  9.   1. 显示屏的物理分辨率,驱动已经做了显示屏自适应,支持4.3寸,5寸和7寸屏
  10.      这里填写自适应显示屏中的最大分辨率。
  11. */
  12. #define XSIZE_PHYS       800
  13. #define YSIZE_PHYS       480
  14. /* 2. 多缓冲 / 虚拟屏,多缓冲和虚拟屏不可同时使用,emWin不支持 */
  15. #define NUM_BUFFERS      3 /* 定义多缓冲个数,仅可以设置1,2和3,也就是最大支持三缓冲 */
  16. #define NUM_VSCREENS     1 /* 定义虚拟屏个数 */
  17. /* 3. 没有图层激活时,背景色设置, 暂时未用到 */
  18. #define BK_COLOR         GUI_DARKBLUE
  19. /*
  20.    4. 重定义图层数,对于STM32F429/439,用户可以选择一个图层或者两个图层,不支持三图层
  21.       (1). 设置GUI_NUM_LAYERS = 1时,即仅使用图层1时,默认触摸值是发送给图层1的。
  22.        (2). 设置GUI_NUM_LAYERS = 2时,即图层1和图层2都已经使能,此时图层2是顶层,
  23.             用户需要根据自己的使用情况设置如下两个地方。
  24.             a. 在bsp_touch.c文件中的函数TOUCH_InitHard里面设置参数State.Layer = 1,1就表示
  25.                给图层2发送触摸值。
  26.             b. 调用GUI_Init函数后,调用函数GUI_SelectLayer(1), 设置当前操作的是图层2。
  27. */
  28. #undef  GUI_NUM_LAYERS
  29. #define GUI_NUM_LAYERS    1
  30. /*
  31.    5. 设置图层1和图层2对应的显存地址
  32.       (1) EXT_SDRAM_ADDR 是SDRAM的首地址。
  33.       (2) LCD_LAYER0_FRAME_BUFFER 是图层1的显存地址。
  34.        (3) LCD_LAYER1_FRAME_BUFFER 是图层2的显存地址。
  35.        (4) 每个图层的显存大小比较考究,这里进行下简单的说明。
  36.            如果用户选择的颜色模式 = 32位色ARGB8888,显存的大小:
  37.            XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS * NUM_BUFFERS
  38.          
  39.            颜色模式 = 24位色RGB888,显存的大小:
  40.            XSIZE_PHYS * YSIZE_PHYS * 3 * NUM_VSCREENS * NUM_BUFFERS
  41.          
  42.            颜色模式 = 16位色RGB566,ARGB1555, ARGB4444,AL88,那么显存的大小就是:
  43.            XSIZE_PHYS * YSIZE_PHYS * 2 * NUM_VSCREENS * NUM_BUFFERS
  44.            颜色模式 = 8位色L8,AL44,那么显存的大小就是:
  45.            XSIZE_PHYS * YSIZE_PHYS * 1 * NUM_VSCREENS * NUM_BUFFERS  
  46.      
  47.       这里为了方便起见,将开发板配套的16MB的SDRAM前8MB分配给LCD显存使用,后8MB用于emWin动态内存。
  48.        对于24位色,16位色,8位色,用户可以对其使能三缓冲,并且使能双图层。但是32位色也使能三缓冲和双
  49.        图层的话会超出8MB,所以用户根据自己的情况做显存和emWin动态内存的分配调整。
  50.          举一个例子,对于800*480分辨率的显示屏,使能32位色,三缓冲,那么最终一个图层需要的大小就是
  51.       800 * 480 * 4 * 3  = 4.394MB的空间,如果是双图层,已经超出8MB的分配范围。
  52.      
  53.       (5)为了方便起见,图层2的宏定义LCD_LAYER1_FRAME_BUFFER中的参数4是按照32位色设置的,如果用户的图层1
  54.          使用的是8位色,这里填数字1,如果是16位色,这里填2,如果是24位色,这里填3。
  55. */
  56. #define LCD_LAYER0_FRAME_BUFFER  EXT_SDRAM_ADDR
  57. #define LCD_LAYER1_FRAME_BUFFER  (LCD_LAYER0_FRAME_BUFFER + XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS *
  58. NUM_BUFFERS)
  59. /*
  60.    6. STM32F429/439支持的颜色模式,所有模式都支持,用户可任意配置。
  61.       特别注意如下两个问题:
  62.        (1) 如果用户选择了ARGB8888或者RGB888模式,LCD闪烁比较厉害的话,
  63.            请降低LTDC的时钟大小,在文件bsp_tft_429.c的函数LCD_ConfigLTDC里面设置。
  64.            a. 一般800*480分辨率的显示屏,ARGB8888或者RGB888模式LTDC时钟选择10-20MHz即可。
  65.            b. 480*272分辨率的可以高些,取20MHz左右即可。
  66.        (2) 16位色或者8位色模式,LTDC的时钟频率一般可以比24位色或者32位色的高一倍。
  67. */
  68. #define _CM_ARGB8888      1
  69. #define _CM_RGB888        2
  70. #define _CM_RGB565        3
  71. #define _CM_ARGB1555      4
  72. #define _CM_ARGB4444      5
  73. #define _CM_L8            6
  74. #define _CM_AL44          7
  75. #define _CM_AL88          8
  76. /* 7. 配置图层1的颜色模式和分辨率大小 */
  77. #define COLOR_MODE_0      _CM_RGB565
  78. #define XSIZE_0           XSIZE_PHYS
  79. #define YSIZE_0           YSIZE_PHYS
  80. /* 8. 配置图层2的的颜色模式和分辨率大小 */
  81. #define COLOR_MODE_1      _CM_RGB565
  82. #define XSIZE_1           XSIZE_PHYS
  83. #define YSIZE_1           YSIZE_PHYS
  84. /* 9. 单图层情况下,根据用户选择的颜色模式可自动选择图层1的emWin的驱动和颜色模式 */
  85. #if   (COLOR_MODE_0 == _CM_ARGB8888)
  86.   #define COLOR_CONVERSION_0 GUICC_M8888I
  87.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_32
  88. #elif (COLOR_MODE_0 == _CM_RGB888)
  89.   #define COLOR_CONVERSION_0 GUICC_M888
  90.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_24
  91. #elif (COLOR_MODE_0 == _CM_RGB565)
  92.   #define COLOR_CONVERSION_0 GUICC_M565
  93.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  94. #elif (COLOR_MODE_0 == _CM_ARGB1555)
  95.   #define COLOR_CONVERSION_0 GUICC_M1555I
  96.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  97. #elif (COLOR_MODE_0 == _CM_ARGB4444)
  98.   #define COLOR_CONVERSION_0 GUICC_M4444I
  99.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  100. #elif (COLOR_MODE_0 == _CM_L8)
  101.   #define COLOR_CONVERSION_0 GUICC_8666
  102.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  103. #elif (COLOR_MODE_0 == _CM_AL44)
  104.   #define COLOR_CONVERSION_0 GUICC_1616I
  105.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  106. #elif (COLOR_MODE_0 == _CM_AL88)
  107.   #define COLOR_CONVERSION_0 GUICC_88666I
  108.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  109. #else
  110.   #error Illegal color mode 0!
  111. #endif
  112. /* 10. 双图层情况下,根据用户选择的颜色模式可自动选择图层2的emWin的驱动和颜色模式 */
  113. #if (GUI_NUM_LAYERS > 1)
  114. #if   (COLOR_MODE_1 == _CM_ARGB8888)
  115.   #define COLOR_CONVERSION_1 GUICC_M8888I
  116.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_32
  117. #elif (COLOR_MODE_1 == _CM_RGB888)
  118.   #define COLOR_CONVERSION_1 GUICC_M888
  119.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_24
  120. #elif (COLOR_MODE_1 == _CM_RGB565)
  121.   #define COLOR_CONVERSION_1 GUICC_M565
  122.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  123. #elif (COLOR_MODE_1 == _CM_ARGB1555)
  124.   #define COLOR_CONVERSION_1 GUICC_M1555I
  125.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  126. #elif (COLOR_MODE_1 == _CM_ARGB4444)
  127.   #define COLOR_CONVERSION_1 GUICC_M4444I
  128.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  129. #elif (COLOR_MODE_1 == _CM_L8)
  130.   #define COLOR_CONVERSION_1 GUICC_8666
  131.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  132. #elif (COLOR_MODE_1 == _CM_AL44)
  133.   #define COLOR_CONVERSION_1 GUICC_1616I
  134.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  135. #elif (COLOR_MODE_1 == _CM_AL88)
  136.   #define COLOR_CONVERSION_1 GUICC_88666I
  137.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  138. #else
  139.   #error Illegal color mode 1!
  140. #endif
  141. #else
  142. #undef XSIZE_0
  143. #undef YSIZE_0
  144. #define XSIZE_0       XSIZE_PHYS
  145. #define YSIZE_0       YSIZE_PHYS
  146. #endif
  147. /*11. 配置选项检测,防止配置错误或者某些选项没有配置 */
  148. #ifndef   XSIZE_PHYS
  149.   #error Physical X size of display is not defined!
  150. #endif
  151. #ifndef   YSIZE_PHYS
  152.   #error Physical Y size of display is not defined!
  153. #endif
  154. #ifndef   NUM_VSCREENS
  155.   #define NUM_VSCREENS 1
  156. #else
  157.   #if (NUM_VSCREENS <= 0)
  158.     #error At least one screeen needs to be defined!
  159.   #endif
  160. #endif
  161. #if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
  162.   #error Virtual screens and multiple buffers are not allowed!
  163. #endif
复制代码
        对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
任务栈大小分配:
        μCOS-III任务栈大小在os_cfg.h文件中配置:
#define  APP_CFG_TASK_START_STK_SIZE                     512u
#define  APP_CFG_TASK_MsgPro_STK_SIZE                    512u
#define  APP_CFG_TASK_COM_STK_SIZE                       512u
#define  APP_CFG_TASK_USER_IF_STK_SIZE                    512u
#define  APP_CFG_TASK_GUI_STK_SIZE                        1024u
        任务栈大小的单位是4字节,那么每个任务的栈大小如下:
App Task Start   任务:2048字节。
       App Task MspPro任务 :2048字节。
       App Task UserIF  任务:2048字节。
       App Task COM   任务:2048字节。
App Task GUI    任务:4096字节。
系统栈大小分配:
       μCOS-III的系统栈大小在os_cfg_app.h文件中配置:
        #define  OS_CFG_ISR_STK_SIZE                      512u      
        系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB。
μCOS-III初始化:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main(void)
  10. {
  11.     OS_ERR  err;
  12.    
  13.      /* 初始化uC/OS-III 内核 */
  14.     OSInit(&err);
  15.      /* 创建一个启动任务(也就是主任务)。启动任务会创建所有的应用程序任务 */
  16.      OSTaskCreate((OS_TCB       *)&AppTaskStartTCB,  /* 任务控制块地址 */           
  17.                  (CPU_CHAR     *)"App Task Start",  /* 任务名 */
  18.                  (OS_TASK_PTR   )AppTaskStart,      /* 启动任务函数地址 */
  19.                  (void         *)0,                 /* 传递给任务的参数 */
  20.                  (OS_PRIO       )APP_CFG_TASK_START_PRIO, /* 任务优先级 */
  21.                  (CPU_STK      *)&AppTaskStartStk[0],     /* 堆栈基地址 */
  22.                  (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE / 10, /* 堆栈监测区,这里表示后10%作为监测区 */
  23.                  (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE,      /* 堆栈空间大小 */
  24.                  (OS_MSG_QTY    )0,  /* 本任务支持接受的最大消息数 */
  25.                  (OS_TICK       )0,  /* 设置时间片 */
  26.                  (void         *)0,  /* 堆栈空间大小 */
  27.                  (OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  28.         
  29.                     /*  定义如下:
  30.                        OS_OPT_TASK_STK_CHK      使能检测任务栈,统计任务栈已用的和未用的
  31.                        OS_OPT_TASK_STK_CLR      在创建任务时,清零任务栈
  32.                        OS_OPT_TASK_SAVE_FP      如果CPU有浮点寄存器,则在任务切换时保存浮点寄存器的内容
  33.                     */
  34.                  (OS_ERR       *)&err);
  35.      /* 启动多任务系统,控制权交给uC/OS-III */
  36.     OSStart(&err);                                             
  37.    
  38.     (void)&err;
  39.    
  40.     return (0);
  41. }
复制代码
硬件外设初始化
        硬件外设的初始化是在bsp.c文件实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: bsp_Init
  4. *    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void bsp_Init(void)
  10. {
  11.      /*
  12.          由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
  13.          启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
  14.          系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
  15.      */
  16.      /* 使能CRC 因为使用STemWin前必须要使能 */
  17.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  18.    
  19.      /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
  20.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  21.    
  22.      SystemCoreClockUpdate();    /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
  23.      bsp_InitUart();        /* 初始化串口 */
  24.      bsp_InitKey();         /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
  25.    
  26.      bsp_InitExtIO();       /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
  27.      bsp_InitLed();         /* 初始LED指示灯端口 */
  28.    
  29.      bsp_InitI2C();         /* 配置I2C总线 */
  30.      bsp_InitSPIBus();       /* 配置SPI总线 */
  31.    
  32.      bsp_InitSFlash();       /* 初始化SPI Flash */
  33.    
  34.      bsp_InitExtSDRAM();   /* 初始化SDRAM */
  35.      bsp_DetectLcdType();  /* 检测触摸板和LCD面板型号, 结果存在全局变量 g_TouchType, g_LcdType */
  36.    
  37.      TOUCH_InitHard();    /* 初始化配置触摸芯片 */
  38.      LCD_ConfigLTDC();     /* 初始化配置LTDC */
  39.    
  40.      result = f_mount(&fs, "0:/", 0);     /* 挂载文件系统 */
  41. }
复制代码
五个μCOS-III任务的实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: AppTaskStart
  4. *    功能说明: 这是一个启动任务,在多任务系统启动后,必须初始化滴答计数器。本任务主要实现按键和触摸检测。
  5. *    形    参: p_arg 是在创建该任务时传递的形参
  6. *    返 回 值: 无
  7.      优 先 级: 2
  8. *********************************************************************************************************
  9. */
  10. static  void  AppTaskStart (void *p_arg)
  11. {
  12.      OS_ERR      err;
  13.      uint8_t  ucCount = 0;
  14.      uint8_t  ucCount1 = 0;
  15.    
  16.     /* 仅用于避免编译器告警,编译器不会产生任何目标代码 */  
  17.     (void)p_arg;
  18.    
  19.      /* BSP 初始化。 BSP = Board Support Package 板级支持包,可以理解为底层驱动。*/
  20.      CPU_Init();  /* 此函数要优先调用,因为外设驱动中使用的us和ms延迟是基于此函数的 */
  21.      bsp_Init();      
  22.      BSP_Tick_Init();
  23.    
  24. #if OS_CFG_STAT_TASK_EN > 0u
  25.      OSStatTaskCPUUsageInit(&err);  
  26. #endif
  27. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  28.     CPU_IntDisMeasMaxCurReset();
  29. #endif
  30.         
  31.      /* 创建应用程序的任务 */
  32.      AppTaskCreate();
  33.    
  34.      /* 创建任务通信 */
  35.      AppObjCreate();
  36.    
  37.     while(1)
  38.     {
  39.          /* 1ms一次触摸扫描,电阻触摸屏 */
  40.          if(g_tTP.Enable == 1)
  41.          {
  42.               TOUCH_Scan();
  43.             
  44.               /* 按键扫描 */
  45.               ucCount++;
  46.               if(ucCount == 10)
  47.               {
  48.                    ucCount = 0;
  49.                    bsp_KeyScan();
  50.               }
  51.              OSTimeDly(1, OS_OPT_TIME_DLY, &err);         
  52.          }
  53.         
  54.          /* 20ms一次触摸扫描,电容触摸屏GT811
  55.             GT811取20ms比较稳定,取10ms偶尔会有跳动。
  56.          */
  57.          if(g_GT811.Enable == 1)
  58.          {
  59.               bsp_KeyScan();
  60.               ucCount1++;
  61.               if(ucCount1 == 2)
  62.               {
  63.                    ucCount1 = 0;
  64.                    GT811_OnePiontScan();
  65.               }
  66.              OSTimeDly(10, OS_OPT_TIME_DLY, &err);     
  67.          }
  68.         
  69.          /* 10ms一次触摸扫描,电容触摸屏FT5X06 */
  70.          if(g_tFT5X06.Enable == 1)
  71.          {
  72.               bsp_KeyScan();
  73.               FT5X06_OnePiontScan();
  74.              OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  75.          }
  76.     }   
  77. }
  78. /*
  79. *********************************************************************************************************
  80. *    函 数 名: AppTaskMsgPro
  81. *    功能说明: 实现截图功能,将图片以BMP格式保存到SD卡中
  82. *    形    参: p_arg 是在创建该任务时传递的形参
  83. *    返 回 值: 无
  84.      优 先 级: 3
  85. *********************************************************************************************************
  86. */
  87. static void AppTaskMsgPro(void *p_arg)
  88. {
  89.      uint32_t ulStart, ulEnd;
  90.      OS_ERR      err;
  91.      uint8_t       Pic_Name = 0;
  92.      char buf[20];
  93.      (void)p_arg;
  94.          
  95.      while(1)
  96.      {   
  97.           /* 等待获取信号量同步消息,接收到后执行串口打印 */
  98.          OSSemPend((OS_SEM *)&SEM_SYNCH,
  99.                      (OS_TICK )0,
  100.                      (OS_OPT  )OS_OPT_PEND_BLOCKING,
  101.                      (CPU_TS  )0,
  102.                      (OS_ERR *)&err);
  103.         
  104.          if(err == OS_ERR_NONE)
  105.          {   
  106.               sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
  107.             
  108.               /* 记录截图前起始时间 */
  109.               ulStart = OSTimeGet(&err);
  110.             
  111.               /* 开启调度锁 */
  112.               OSSchedLock(&err);
  113.             
  114.               /* 如果SD卡中没有PicSave文件,会进行创建 */
  115.               result = f_mkdir("0:/PicSave");
  116.             
  117.               /* 创建截图 */
  118.               result = f_open(&file,buf, FA_WRITE|FA_CREATE_ALWAYS);
  119.             
  120.               /* 向SD卡绘制BMP图片 */
  121.               GUI_BMP_Serialize(_WriteByte2File, &file);
  122.             
  123.               /* 创建完成后关闭file */
  124.              result = f_close(&file);
  125.             
  126.               /* 开启调度锁 */
  127.               OSSchedUnlock(&err);
  128.             
  129.               /* 记录截图后时间并获取截图过程耗时 */
  130.               ulEnd = OSTimeGet(&err);
  131.               ulEnd -= ulStart;
  132.             
  133.               App_Printf("截图完成,耗时 = %dms\\r\\n", ulEnd);
  134.               Pic_Name++;      
  135.          }                                                                                                                  
  136.      }  
  137. }
  138. /*
  139. *********************************************************************************************************
  140. *    函 数 名: AppTaskUserIF
  141. *    功能说明: 按键消息处理
  142. *    形    参: p_arg 是在创建该任务时传递的形参
  143. *    返 回 值: 无
  144.      优 先 级: 4
  145. *********************************************************************************************************
  146. */
  147. static void AppTaskUserIF(void *p_arg)
  148. {
  149.      OS_ERR      err;
  150.      uint8_t  ucKeyCode;
  151.    
  152.      (void)p_arg;                /* 避免编译器报警 */
  153.    
  154.      while (1)
  155.      {      
  156.          ucKeyCode = bsp_GetKey();
  157.         
  158.          if (ucKeyCode != KEY_NONE)
  159.          {
  160.               switch (ucKeyCode)
  161.               {
  162.                    case KEY_DOWN_K1:             /* K1键按下 打印任务执行情况 */
  163.                        DispTaskInfo();        
  164.                        break;
  165.                   
  166.                    case KEY_DOWN_K2:             /* K2键按下 向消息队列发送数据 */
  167.                        OSSemPost((OS_SEM *)&SEM_SYNCH,
  168.                                   (OS_OPT  )OS_OPT_POST_1,
  169.                                   (OS_ERR *)&err);
  170.                        break;
  171.                   
  172.                    default:                     /* 其他的键值不处理 */
  173.                        break;
  174.               }
  175.          }
  176.         
  177.          OSTimeDly(20, OS_OPT_TIME_DLY, &err);
  178.      }
  179. }
  180. /*
  181. *********************************************************************************************************
  182. *    函 数 名: AppTaskCom
  183. *    功能说明: 暂未使用
  184. *    形    参: p_arg 是在创建该任务时传递的形参
  185. *    返 回 值: 无
  186.      优 先 级: 5
  187. *********************************************************************************************************
  188. */
  189. static void AppTaskCOM(void *p_arg)
  190. {
  191.      OS_ERR  err;      
  192.    
  193.      (void)p_arg;
  194.    
  195.      while(1)
  196.      {   
  197.          OSTimeDly(500, OS_OPT_TIME_DLY, &err);
  198.      }                                                                                                
  199. }
  200. /*
  201. *********************************************************************************************************
  202. *    函 数 名: AppTaskGUI
  203. *    功能说明: GUI任务,最低优先级                        
  204. *    形    参:p_arg 是在创建该任务时传递的形参
  205. *    返 回 值: 无
  206. *   优 先 级:OS_CFG_PRIO_MAX - 4u
  207. *********************************************************************************************************
  208. */
  209. static void AppTaskGUI(void *p_arg)
  210. {
  211.     (void)p_arg;       /* 避免编译器告警 */
  212.         
  213.      while (1)
  214.      {
  215.          MainTask();
  216.      }
  217. }
复制代码
emWin任务的具体实现(在MainTask.c文件里面):
  1. #include "MainTask.h"
  2. #include "includes.h"
  3. /*
  4. *********************************************************************************************************
  5. *                                         变量
  6. *********************************************************************************************************
  7. */
  8. static GRAPH_SCALE_Handle hScaleV;   
  9. static GRAPH_DATA_Handle  ahData;
  10. /*
  11. *********************************************************************************************************
  12. *                                         宏定义
  13. *********************************************************************************************************
  14. */
  15. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
  16. #define ID_GRAPH_0    (GUI_ID_USER + 0x01)
  17. /*
  18. *********************************************************************************************************
  19. *                           GUI_WIDGET_CREATE_INFO类型数组
  20. *********************************************************************************************************
  21. */
  22. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
  23. {
  24.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  25.      { GRAPH_CreateIndirect, "Graph", ID_GRAPH_0, 10, 10, 400, 240, 0, 0x0, 0 },
  26. };
  27. /*
  28. *********************************************************************************************************
  29. *    函 数 名: _cbDialog
  30. *    功能说明: 对话框回调函数        
  31. *    形    参: pMsg  回调参数
  32. *    返 回 值: 无
  33. *********************************************************************************************************
  34. */
  35. static void _cbDialog(WM_MESSAGE * pMsg)
  36. {
  37.      WM_HWIN hItem;
  38.      switch (pMsg->MsgId)
  39.      {
  40.          case WM_INIT_DIALOG:
  41.             
  42.               //
  43.               // 初始化
  44.               //
  45.               hItem = pMsg->hWin;
  46.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  47.               FRAMEWIN_SetText(hItem, "armfly");
  48.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  49.               //
  50.               // 初始化Graph控件
  51.               //
  52.               hItem = WM_GetDialogItem(pMsg->hWin, ID_GRAPH_0);
  53.               /* 创建数据对象 *******************************************************/
  54.               ahData = GRAPH_DATA_YT_Create(GUI_GREEN, 400, 0, 0);
  55.               /* 数据对象添加到图形控件 */
  56.               GRAPH_AttachData(hItem, ahData);
  57.               /* 设置Y轴方向的栅格间距 */
  58.               GRAPH_SetGridDistY(hItem, 20);
  59.               /* 固定X轴方向的栅格 */
  60.               GRAPH_SetGridFixedX(hItem, 1);
  61.               /* 设置栅格可见 */
  62.               GRAPH_SetGridVis(hItem, 1);
  63.               /* 创建刻度对象  ***************************************************/
  64.               hScaleV = GRAPH_SCALE_Create(20, GUI_TA_RIGHT, GRAPH_SCALE_CF_VERTICAL, 20);
  65.               /* 将垂直刻度对象添加到图形控件 */
  66.               GRAPH_AttachScale(hItem, hScaleV);
  67.               /* 用于设置比例刻度的因子 */
  68.               GRAPH_SCALE_SetFactor(hScaleV, 0.5);
  69.               /* 设置标签字体颜色 */
  70.               GRAPH_SCALE_SetTextColor(hScaleV, GUI_RED);
  71.               /* 设置上下左右边界的大小 */
  72.               GRAPH_SetBorder(hItem, 20, 10, 10, 10);
  73.               break;
  74.             
  75.          default:
  76.               WM_DefaultProc(pMsg);
  77.               break;
  78.      }
  79. }
  80. /*
  81. *********************************************************************************************************
  82. *    函 数 名: CreateFramewin
  83. *    功能说明: 创建对话框      
  84. *    形    参: 无
  85. *    返 回 值: 返回对话框句柄
  86. *********************************************************************************************************
  87. */
  88. WM_HWIN CreateFramewin(void)
  89. {
  90.      WM_HWIN hWin;
  91.      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  92.      return hWin;
  93. }
  94. /*
  95. *********************************************************************************************************
  96. *    函 数 名: MainTask
  97. *    功能说明: GUI主函数
  98. *    形    参: 无
  99. *    返 回 值: 无
  100. *********************************************************************************************************
  101. */
  102. void MainTask(void)
  103. {
  104.    
  105.      /* 初始化 */
  106.      GUI_Init();
  107.    
  108.      /*
  109.       关于多缓冲和窗口内存设备的设置说明
  110.         1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
  111.            WM_MULTIBUF_Enable(1);
  112.         2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
  113.         3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
  114.            STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
  115.            感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
  116.         4. 所有emWin例子默认是开启三缓冲。
  117.      */
  118.      WM_MULTIBUF_Enable(1);
  119.    
  120.      /*
  121.        触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
  122.         此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
  123.      */
  124.     //TOUCH_Calibration();
  125.    
  126.      /* 创建对话框 */
  127.      CreateFramewin();
  128.         
  129.      while(1)
  130.      {
  131.           /* 每50ms给绘图控件添加一次新的数据 */
  132.          GRAPH_DATA_YT_AddValue(ahData, rand()%100);
  133.          GUI_Delay(50);
  134.      }
  135. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-9 16:06:03 | 显示全部楼层
52.6 实验例程说明(裸机)


配套例子:
        V6-574_STemWin实验_Graph图形控件(裸机)
实验目的:
        1.     本实验主要学习图形控件的使用。
        2.     emWin功能的实现在MainTask.c文件里面。
实验内容:
        1.     GUI任务主要在对话框上面创建了一个图形控件,每50ms更新一次数据。
STemWin界面显示效果:
        800*480分辨率界面效果。
2.24.png


STemWin动态内存配置:
        GUIConf.c文件中的配置如下:
  1. #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
  2. #if EX_SRAM
  3. #define GUI_NUMBYTES  (1024*1024*8)
  4. #else
  5. #define GUI_NUMBYTES  (100*1024)
  6. #endif
复制代码
        通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM    1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM    0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
        LCDConf_Lin_Template.c文件中共12项emWin配置:
  1. /*
  2. **********************************************************************************************************
  3.                                           用户可以配置的选项
  4. **********************************************************************************************************
  5. */
  6. /* 0. 在官方代码的基础上再做优化,官方的部分函数效率低,耗内存, 0表示优化 */
  7. #define emWin_Optimize   0
  8. /*
  9.   1. 显示屏的物理分辨率,驱动已经做了显示屏自适应,支持4.3寸,5寸和7寸屏
  10.      这里填写自适应显示屏中的最大分辨率。
  11. */
  12. #define XSIZE_PHYS       800
  13. #define YSIZE_PHYS       480
  14. /* 2. 多缓冲 / 虚拟屏,多缓冲和虚拟屏不可同时使用,emWin不支持 */
  15. #define NUM_BUFFERS      3 /* 定义多缓冲个数,仅可以设置1,2和3,也就是最大支持三缓冲 */
  16. #define NUM_VSCREENS     1 /* 定义虚拟屏个数 */
  17. /* 3. 没有图层激活时,背景色设置, 暂时未用到 */
  18. #define BK_COLOR         GUI_DARKBLUE
  19. /*
  20.    4. 重定义图层数,对于STM32F429/439,用户可以选择一个图层或者两个图层,不支持三图层
  21.       (1). 设置GUI_NUM_LAYERS = 1时,即仅使用图层1时,默认触摸值是发送给图层1的。
  22.        (2). 设置GUI_NUM_LAYERS = 2时,即图层1和图层2都已经使能,此时图层2是顶层,
  23.             用户需要根据自己的使用情况设置如下两个地方。
  24.             a. 在bsp_touch.c文件中的函数TOUCH_InitHard里面设置参数State.Layer = 1,1就表示
  25.                给图层2发送触摸值。
  26.             b. 调用GUI_Init函数后,调用函数GUI_SelectLayer(1), 设置当前操作的是图层2。
  27. */
  28. #undef  GUI_NUM_LAYERS
  29. #define GUI_NUM_LAYERS    1
  30. /*
  31.    5. 设置图层1和图层2对应的显存地址
  32.       (1) EXT_SDRAM_ADDR 是SDRAM的首地址。
  33.       (2) LCD_LAYER0_FRAME_BUFFER 是图层1的显存地址。
  34.        (3) LCD_LAYER1_FRAME_BUFFER 是图层2的显存地址。
  35.        (4) 每个图层的显存大小比较考究,这里进行下简单的说明。
  36.            如果用户选择的颜色模式 = 32位色ARGB8888,显存的大小:
  37.            XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS * NUM_BUFFERS
  38.          
  39.            颜色模式 = 24位色RGB888,显存的大小:
  40.            XSIZE_PHYS * YSIZE_PHYS * 3 * NUM_VSCREENS * NUM_BUFFERS
  41.          
  42.            颜色模式 = 16位色RGB566,ARGB1555, ARGB4444,AL88,那么显存的大小就是:
  43.            XSIZE_PHYS * YSIZE_PHYS * 2 * NUM_VSCREENS * NUM_BUFFERS
  44.            颜色模式 = 8位色L8,AL44,那么显存的大小就是:
  45.            XSIZE_PHYS * YSIZE_PHYS * 1 * NUM_VSCREENS * NUM_BUFFERS  
  46.      
  47.       这里为了方便起见,将开发板配套的16MB的SDRAM前8MB分配给LCD显存使用,后8MB用于emWin动态内存。
  48.        对于24位色,16位色,8位色,用户可以对其使能三缓冲,并且使能双图层。但是32位色也使能三缓冲和双
  49.        图层的话会超出8MB,所以用户根据自己的情况做显存和emWin动态内存的分配调整。
  50.          举一个例子,对于800*480分辨率的显示屏,使能32位色,三缓冲,那么最终一个图层需要的大小就是
  51.       800 * 480 * 4 * 3  = 4.394MB的空间,如果是双图层,已经超出8MB的分配范围。
  52.      
  53.       (5)为了方便起见,图层2的宏定义LCD_LAYER1_FRAME_BUFFER中的参数4是按照32位色设置的,如果用户的图层1
  54.          使用的是8位色,这里填数字1,如果是16位色,这里填2,如果是24位色,这里填3。
  55. */
  56. #define LCD_LAYER0_FRAME_BUFFER  EXT_SDRAM_ADDR
  57. #define LCD_LAYER1_FRAME_BUFFER  (LCD_LAYER0_FRAME_BUFFER + XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS *
  58. NUM_BUFFERS)
  59. /*
  60.    6. STM32F429/439支持的颜色模式,所有模式都支持,用户可任意配置。
  61.       特别注意如下两个问题:
  62.        (1) 如果用户选择了ARGB8888或者RGB888模式,LCD闪烁比较厉害的话,
  63.            请降低LTDC的时钟大小,在文件bsp_tft_429.c的函数LCD_ConfigLTDC里面设置。
  64.            a. 一般800*480分辨率的显示屏,ARGB8888或者RGB888模式LTDC时钟选择10-20MHz即可。
  65.            b. 480*272分辨率的可以高些,取20MHz左右即可。
  66.        (2) 16位色或者8位色模式,LTDC的时钟频率一般可以比24位色或者32位色的高一倍。
  67. */
  68. #define _CM_ARGB8888      1
  69. #define _CM_RGB888        2
  70. #define _CM_RGB565        3
  71. #define _CM_ARGB1555      4
  72. #define _CM_ARGB4444      5
  73. #define _CM_L8            6
  74. #define _CM_AL44          7
  75. #define _CM_AL88          8
  76. /* 7. 配置图层1的颜色模式和分辨率大小 */
  77. #define COLOR_MODE_0      _CM_RGB565
  78. #define XSIZE_0           XSIZE_PHYS
  79. #define YSIZE_0           YSIZE_PHYS
  80. /* 8. 配置图层2的的颜色模式和分辨率大小 */
  81. #define COLOR_MODE_1      _CM_RGB565
  82. #define XSIZE_1           XSIZE_PHYS
  83. #define YSIZE_1           YSIZE_PHYS
  84. /* 9. 单图层情况下,根据用户选择的颜色模式可自动选择图层1的emWin的驱动和颜色模式 */
  85. #if   (COLOR_MODE_0 == _CM_ARGB8888)
  86.   #define COLOR_CONVERSION_0 GUICC_M8888I
  87.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_32
  88. #elif (COLOR_MODE_0 == _CM_RGB888)
  89.   #define COLOR_CONVERSION_0 GUICC_M888
  90.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_24
  91. #elif (COLOR_MODE_0 == _CM_RGB565)
  92.   #define COLOR_CONVERSION_0 GUICC_M565
  93.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  94. #elif (COLOR_MODE_0 == _CM_ARGB1555)
  95.   #define COLOR_CONVERSION_0 GUICC_M1555I
  96.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  97. #elif (COLOR_MODE_0 == _CM_ARGB4444)
  98.   #define COLOR_CONVERSION_0 GUICC_M4444I
  99.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  100. #elif (COLOR_MODE_0 == _CM_L8)
  101.   #define COLOR_CONVERSION_0 GUICC_8666
  102.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  103. #elif (COLOR_MODE_0 == _CM_AL44)
  104.   #define COLOR_CONVERSION_0 GUICC_1616I
  105.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  106. #elif (COLOR_MODE_0 == _CM_AL88)
  107.   #define COLOR_CONVERSION_0 GUICC_88666I
  108.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  109. #else
  110.   #error Illegal color mode 0!
  111. #endif
  112. /* 10. 双图层情况下,根据用户选择的颜色模式可自动选择图层2的emWin的驱动和颜色模式 */
  113. #if (GUI_NUM_LAYERS > 1)
  114. #if   (COLOR_MODE_1 == _CM_ARGB8888)
  115.   #define COLOR_CONVERSION_1 GUICC_M8888I
  116.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_32
  117. #elif (COLOR_MODE_1 == _CM_RGB888)
  118.   #define COLOR_CONVERSION_1 GUICC_M888
  119.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_24
  120. #elif (COLOR_MODE_1 == _CM_RGB565)
  121.   #define COLOR_CONVERSION_1 GUICC_M565
  122.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  123. #elif (COLOR_MODE_1 == _CM_ARGB1555)
  124.   #define COLOR_CONVERSION_1 GUICC_M1555I
  125.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  126. #elif (COLOR_MODE_1 == _CM_ARGB4444)
  127.   #define COLOR_CONVERSION_1 GUICC_M4444I
  128.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  129. #elif (COLOR_MODE_1 == _CM_L8)
  130.   #define COLOR_CONVERSION_1 GUICC_8666
  131.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  132. #elif (COLOR_MODE_1 == _CM_AL44)
  133.   #define COLOR_CONVERSION_1 GUICC_1616I
  134.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  135. #elif (COLOR_MODE_1 == _CM_AL88)
  136.   #define COLOR_CONVERSION_1 GUICC_88666I
  137.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  138. #else
  139.   #error Illegal color mode 1!
  140. #endif
  141. #else
  142. #undef XSIZE_0
  143. #undef YSIZE_0
  144. #define XSIZE_0       XSIZE_PHYS
  145. #define YSIZE_0       YSIZE_PHYS
  146. #endif
  147. /*11. 配置选项检测,防止配置错误或者某些选项没有配置 */
  148. #ifndef   XSIZE_PHYS
  149.   #error Physical X size of display is not defined!
  150. #endif
  151. #ifndef   YSIZE_PHYS
  152.   #error Physical Y size of display is not defined!
  153. #endif
  154. #ifndef   NUM_VSCREENS
  155.   #define NUM_VSCREENS 1
  156. #else
  157.   #if (NUM_VSCREENS <= 0)
  158.     #error At least one screeen needs to be defined!
  159.   #endif
  160. #endif
  161. #if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
  162.   #error Virtual screens and multiple buffers are not allowed!
  163. #endif
复制代码
        对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
栈大小分配:
        系统栈大小在startup_stm32f429_439xx.s文件中配置:
2.25.png

        栈大小的单位是字节,那么这里配置系统栈大小为8192字节。
主函数初始化:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main (void)
  10. {   
  11.      /* 初始化外设 */
  12.      bsp_Init();
  13.      /* 进入emWin主函数 */
  14.      MainTask();
  15. }
复制代码
硬件外设初始化
        硬件外设的初始化是在bsp.c文件实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: bsp_Init
  4. *    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void bsp_Init(void)
  10. {
  11.      /*
  12.          由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
  13.          启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
  14.          系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
  15.      */
  16.      /* 使能CRC 因为使用STemWin前必须要使能 */
  17.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  18.    
  19.      /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
  20.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  21.    
  22.      SystemCoreClockUpdate();    /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
  23.      bsp_InitUart();        /* 初始化串口 */
  24.      bsp_InitKey();         /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
  25.    
  26.      bsp_InitExtIO();       /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
  27.      bsp_InitLed();         /* 初始LED指示灯端口 */
  28.    
  29.      bsp_InitI2C();         /* 配置I2C总线 */
  30.      bsp_InitSPIBus();       /* 配置SPI总线 */
  31.    
  32.      bsp_InitSFlash();       /* 初始化SPI Flash */
  33.    
  34.      bsp_InitExtSDRAM();   /* 初始化SDRAM */
  35.      bsp_DetectLcdType();  /* 检测触摸板和LCD面板型号, 结果存在全局变量 g_TouchType, g_LcdType */
  36.    
  37.      TOUCH_InitHard();    /* 初始化配置触摸芯片 */
  38.      LCD_ConfigLTDC();     /* 初始化配置LTDC */
  39.    
  40.      result = f_mount(&fs, "0:/", 0);     /* 挂载文件系统 */
  41. }
复制代码
emWin功能的具体实现(在MainTask.c文件里面):
  1. #include "MainTask.h"
  2. #include "bsp.h"
  3. /*
  4. *********************************************************************************************************
  5. *                                         变量
  6. *********************************************************************************************************
  7. */
  8. static GRAPH_SCALE_Handle hScaleV;   
  9. static GRAPH_DATA_Handle  ahData;
  10. /*
  11. *********************************************************************************************************
  12. *                                         宏定义
  13. *********************************************************************************************************
  14. */
  15. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
  16. #define ID_GRAPH_0    (GUI_ID_USER + 0x01)
  17. /*
  18. *********************************************************************************************************
  19. *                           GUI_WIDGET_CREATE_INFO类型数组
  20. *********************************************************************************************************
  21. */
  22. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
  23. {
  24.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  25.      { GRAPH_CreateIndirect, "Graph", ID_GRAPH_0, 10, 10, 400, 240, 0, 0x0, 0 },
  26. };
  27. /*
  28. *********************************************************************************************************
  29. *    函 数 名: _cbDialog
  30. *    功能说明: 对话框回调函数        
  31. *    形    参: pMsg  回调参数
  32. *    返 回 值: 无
  33. *********************************************************************************************************
  34. */
  35. static void _cbDialog(WM_MESSAGE * pMsg)
  36. {
  37.      WM_HWIN hItem;
  38.      switch (pMsg->MsgId)
  39.      {
  40.          case WM_INIT_DIALOG:
  41.             
  42.               //
  43.               // 初始化
  44.               //
  45.               hItem = pMsg->hWin;
  46.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  47.               FRAMEWIN_SetText(hItem, "armfly");
  48.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  49.               //
  50.               // 初始化Graph控件
  51.               //
  52.               hItem = WM_GetDialogItem(pMsg->hWin, ID_GRAPH_0);
  53.               /* 创建数据对象 *******************************************************/
  54.               ahData = GRAPH_DATA_YT_Create(GUI_GREEN, 400, 0, 0);
  55.               /* 数据对象添加到图形控件 */
  56.               GRAPH_AttachData(hItem, ahData);
  57.               /* 设置Y轴方向的栅格间距 */
  58.               GRAPH_SetGridDistY(hItem, 20);
  59.               /* 固定X轴方向的栅格 */
  60.               GRAPH_SetGridFixedX(hItem, 1);
  61.               /* 设置栅格可见 */
  62.               GRAPH_SetGridVis(hItem, 1);
  63.               /* 创建刻度对象  ***************************************************/
  64.               hScaleV = GRAPH_SCALE_Create(20, GUI_TA_RIGHT, GRAPH_SCALE_CF_VERTICAL, 20);
  65.               /* 将垂直刻度对象添加到图形控件 */
  66.               GRAPH_AttachScale(hItem, hScaleV);
  67.               /* 用于设置比例刻度的因子 */
  68.               GRAPH_SCALE_SetFactor(hScaleV, 0.5);
  69.               /* 设置标签字体颜色 */
  70.               GRAPH_SCALE_SetTextColor(hScaleV, GUI_RED);
  71.               /* 设置上下左右边界的大小 */
  72.               GRAPH_SetBorder(hItem, 20, 10, 10, 10);
  73.               break;
  74.             
  75.          default:
  76.               WM_DefaultProc(pMsg);
  77.               break;
  78.      }
  79. }
  80. /*
  81. *********************************************************************************************************
  82. *    函 数 名: CreateFramewin
  83. *    功能说明: 创建对话框      
  84. *    形    参: 无
  85. *    返 回 值: 返回对话框句柄
  86. *********************************************************************************************************
  87. */
  88. WM_HWIN CreateFramewin(void)
  89. {
  90.      WM_HWIN hWin;
  91.      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  92.      return hWin;
  93. }
  94. /*
  95. *********************************************************************************************************
  96. *    函 数 名: MainTask
  97. *    功能说明: GUI主函数
  98. *    形    参: 无
  99. *    返 回 值: 无
  100. *********************************************************************************************************
  101. */
  102. void MainTask(void)
  103. {
  104.    
  105.      /* 初始化 */
  106.      GUI_Init();
  107.    
  108.      /*
  109.       关于多缓冲和窗口内存设备的设置说明
  110.         1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
  111.            WM_MULTIBUF_Enable(1);
  112.         2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
  113.         3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
  114.            STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
  115.            感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
  116.         4. 所有emWin例子默认是开启三缓冲。
  117.      */
  118.      WM_MULTIBUF_Enable(1);
  119.    
  120.      /*
  121.        触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
  122.         此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
  123.      */
  124.     //TOUCH_Calibration();
  125.    
  126.      /* 创建对话框 */
  127.      CreateFramewin();
  128.         
  129.      while(1)
  130.      {
  131.           /* 每50ms给绘图控件添加一次新的数据 */
  132.          GRAPH_DATA_YT_AddValue(ahData, rand()%100);
  133.          GUI_Delay(50);
  134.      }
  135. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-9 16:06:31 | 显示全部楼层
52.7   总结


        本期教程主要是跟大家讲解了图形控件的使用,熟练掌握图形控件还是要花些时间的,希望大家可以把本期教程中讲的例子运行下,然后自己设计一个相关的例子进行试验学习。另外,我们本章节仅测试了YT方式的波形绘制,没有做XY方式的波形绘制,需要初学者自行学习,官方模拟器也有提供参考实例,可以参考学习。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-30 04:21 , Processed in 0.216456 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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