硬汉嵌入式论坛

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

[emWin教程入门篇] 【emWin实战教程V2.0】第64章      STemWin多个窗口

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

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




第64章      STemWin多个窗口切换方法


        初学者经常问这方面的问题,特此做了这么一章节,实际项目中难免要做多个窗口的切换,了解并学习这方面的知识就尤为关键了。
64.1 初学者重要提示
64.2 多窗口切换的实现思路及其注意事项
64.2 官方DIALOG_MenuStructure.c实例讲解
64.4 实验例程说明(RTOS)
64.5 实验例程说明(裸机)
64.6 总结
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-4-2 15:10:34 | 显示全部楼层
64.1  初学者重要提示


        做一个安全稳定的多窗口切换例子,需要初学者逐渐积累这方面的经验。当前可以先把本章节提供
的多窗口切换例子用熟练,然后逐步提升多窗口的应用经验。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-4-2 15:11:31 | 显示全部楼层
64.2 多窗口切换的实现思路及其注意事项


        多窗口切换的处理思路主要有三种(当然,还有很多其它种类,我们这里仅说明以下三种):
1、1种类似ATM机操作界面
        大家在ATM机取钱的时候应该都有印象,ATM机有一个主界面,然后一路点击下去,直到把钱取出来,退出后回到主界面。这种形式简单总结下就是多级窗口之间任意切换,删除之前的窗口,创建新窗口,这里有个演示效果,让大家有个感性认识:http://bbs.armfly.com/searcher.php
        本章节配套的例子,我们就是采用的这种形式。
2、2种类似电脑端,手机端的主界面
        这种方式有一个主界面,主界面上面有很多图标,点击某个图标进入功能界面,这个功能界面也可以有多级子界面,比如本教程配套的开发板的综合Demo就是这种形式:http://www.armbbs.cn/forum.php?mod=viewthread&tid=17330 。想返回到主界面,直接关闭这些子界面即可。
3、3种采用隐藏和显示的方式
        这种方式简单实用,系统启动后先把所有需要显示的窗口全部创建好,并用函数WM_HideWindow将这些窗口全部隐藏起来,需要显示哪个窗口的时候,调用函数WM_ShowWindow即可,缺点是所有的窗口要一直占用着内存。
------------------------------
        多窗口切换主要集中在两个地方出问题,一个是用户不规范的创建和删除窗口,控件或者对话框,另一个是有些控件忘记单独删除,一直在重复的创建,最终导致动态内存不足而死机,比如我们前面章节讲解的绘图控件Graph就是要单独删除的。针对这种情况,最好的解决办法就是调用函数GUI_ALLOC_GetNumFreeBytes()查询emWin动态内存的剩余,特别是在创建和关闭窗口,控件和对话框时,查询动态内存的剩余,看看是否动态内存一直在减少。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-4-2 15:14:09 | 显示全部楼层
64.3 官方DIALOG_MenuStructure.c实例讲解

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


主要功能介绍:
        本例子很好的演示了多窗口切换的实现方法,结构清晰,非常具有代表性,望初学者务必掌握。此例子创建了三个对话框,分别是对话框1,对话框2和对话框3,相互之间可以任意切换,通过点击当前对话框上面的两个按钮,可以选择切换到其它两个对话框。切换方法是通过在按钮的释放消息里面调用函数GUI_EndDialog关闭自己,然后调用函数GUI_CreateDialogBox创建新的对话框。关于这个例子还有三点必须要认识到:
1、这个例子的框架非常好,用户的界面全部通过对话框去管理,while(1)大循环里面只有一个GUI_Delay,简单实用,而且易于维护,望初学者掌握这种框架。
2、while(1)大循环里面的函数GUI_Delay非常关键,前面的章节中,我们多次强调它不仅仅是一个延迟函数,窗口管理器的执行就是通过它来实现的,本例子创建的三个对话框可以正常的切换就靠函GUI_Delay的执行,当然,周期性的调用函数WM_Exec或者GUI_Exec也是可以的。
3、不同对话框或者窗口上的控件ID可以相同,同一个窗口或者对话框上的控件ID必须不同。
程序代码如下:
  1. #include "Dialog.h"
  2. /*********************************************************************
  3. *
  4. *       Defines
  5. *
  6. **********************************************************************
  7. */
  8. #define ID_FRAMEWIN_0  (GUI_ID_USER + 0x00)
  9. #define ID_BUTTON_0    (GUI_ID_USER + 0x01)
  10. #define ID_BUTTON_1    (GUI_ID_USER + 0x02)
  11. #define ID_TEXT_0      (GUI_ID_USER + 0x03)
  12. #define ID_RADIO_0     (GUI_ID_USER + 0x04)
  13. #define ID_CHECKBOX_0  (GUI_ID_USER + 0x05)
  14. //
  15. // Recommended memory to run the sample with adequate performance
  16. //
  17. #define RECOMMENDED_MEMORY (1024L * 10)
  18. /*********************************************************************
  19. *
  20. *       Static data
  21. *
  22. **********************************************************************
  23. */
  24. /*********************************************************************
  25. *
  26. *       _aDialogCreate1
  27. */
  28. static const GUI_WIDGET_CREATE_INFO _aDialogCreate1[] = {  //--------------(1)
  29.   { FRAMEWIN_CreateIndirect, "Framewin1", ID_FRAMEWIN_0,   0,  0, 320, 240, 0, 0x64, 0 },
  30.   { BUTTON_CreateIndirect, "Button",      ID_BUTTON_0,     5,  5,  80,  20, 0, 0x0,  0 },
  31.   { BUTTON_CreateIndirect, "Button",      ID_BUTTON_1,     5, 30,  80,  20, 0, 0x0,  0 },
  32.   { TEXT_CreateIndirect,   "Text",        ID_TEXT_0,     110, 60, 160,  32, 0, 0x64, 0 },
  33. };
  34. /*********************************************************************
  35. *
  36. *       _aDialogCreate2
  37. */
  38. static const GUI_WIDGET_CREATE_INFO _aDialogCreate2[] = {  //--------------(2)
  39.   { FRAMEWIN_CreateIndirect, "Framewin2", ID_FRAMEWIN_0,   0,  0, 320, 240, 0, 0x64,   0 },
  40.   { BUTTON_CreateIndirect, "Button",      ID_BUTTON_0,     5,  5,  80,  20, 0, 0x0,    0 },
  41.   { BUTTON_CreateIndirect, "Button",      ID_BUTTON_1,     5, 30,  80,  20, 0, 0x0,    0 },
  42.   { RADIO_CreateIndirect, "Radio",        ID_RADIO_0,    110, 60,  80,  60, 0, 0x1403, 0 },
  43. };
  44. /*********************************************************************
  45. *
  46. *       _aDialogCreate3
  47. */
  48. static const GUI_WIDGET_CREATE_INFO _aDialogCreate3[] = {  //--------------(3)
  49.   { FRAMEWIN_CreateIndirect, "Framewin3", ID_FRAMEWIN_0,   0,  0, 320, 240, 0, 0x64, 0 },
  50.   { BUTTON_CreateIndirect, "Button",      ID_BUTTON_0,     5,  5,  80,  20, 0, 0x0,  0 },
  51.   { BUTTON_CreateIndirect, "Button",      ID_BUTTON_1,     5, 30,  80,  20, 0, 0x0,  0 },
  52.   { CHECKBOX_CreateIndirect, "Checkbox",  ID_CHECKBOX_0, 110, 60, 100,  20, 0, 0x0,  0 },
  53. };
  54. /*********************************************************************
  55. *
  56. *       Prototypes
  57. *
  58. **********************************************************************
  59. */
  60. static void _cbDialog1(WM_MESSAGE * pMsg);
  61. static void _cbDialog2(WM_MESSAGE * pMsg);
  62. static void _cbDialog3(WM_MESSAGE * pMsg);
  63. /*********************************************************************
  64. *
  65. *       Static code
  66. *
  67. **********************************************************************
  68. */
  69. /*********************************************************************
  70. *
  71. *       _cbDialog1
  72. */
  73. static void _cbDialog1(WM_MESSAGE * pMsg) {   //--------------(4)
  74.   WM_HWIN hItem;
  75.   int     NCode;
  76.   int     Id;
  77.   switch (pMsg->MsgId) {
  78.   case WM_INIT_DIALOG:
  79.     //
  80.     // Initialization of 'Framewin1'
  81.     //
  82.     hItem = pMsg->hWin;
  83.     FRAMEWIN_SetText(hItem, "Screen 1");
  84.     FRAMEWIN_SetFont(hItem, GUI_FONT_32_ASCII);
  85.     //
  86.     // Initialization of 'Button'
  87.     //
  88.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  89.     BUTTON_SetText(hItem, "Screen 2");
  90.     //
  91.     // Initialization of 'Button'
  92.     //
  93.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  94.     BUTTON_SetText(hItem, "Screen 3");
  95.     //
  96.     // Initialization of 'Text'
  97.     //
  98.     hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
  99.     TEXT_SetFont(hItem, GUI_FONT_32_ASCII);
  100.     TEXT_SetText(hItem, "Some text");
  101.     break;
  102.   case WM_NOTIFY_PARENT:
  103.     Id    = WM_GetId(pMsg->hWinSrc);
  104.     NCode = pMsg->Data.v;
  105.     switch(Id) {
  106.     case ID_BUTTON_0: // Notifications sent by 'Button'
  107.       switch(NCode) {
  108.       case WM_NOTIFICATION_CLICKED:
  109.         // USER START (Optionally insert code for reacting on notification message)
  110.         // USER END
  111.         break;
  112.       case WM_NOTIFICATION_RELEASED:   //--------------(5)
  113.         GUI_EndDialog(pMsg->hWin, 0);
  114.         GUI_CreateDialogBox(_aDialogCreate2, GUI_COUNTOF(_aDialogCreate2), _cbDialog2, WM_HBKWIN, 0, 0);
  115.         break;
  116.       }
  117.       break;
  118.     case ID_BUTTON_1: // Notifications sent by 'Button'
  119.       switch(NCode) {
  120.       case WM_NOTIFICATION_CLICKED:
  121.         // USER START (Optionally insert code for reacting on notification message)
  122.         // USER END
  123.         break;
  124.       case WM_NOTIFICATION_RELEASED:  //--------------(6)
  125.         GUI_EndDialog(pMsg->hWin, 0);
  126.         GUI_CreateDialogBox(_aDialogCreate3, GUI_COUNTOF(_aDialogCreate3), _cbDialog3, WM_HBKWIN, 0, 0);
  127.         break;
  128.       }
  129.       break;
  130.     }
  131.     break;
  132.   default:
  133.     WM_DefaultProc(pMsg);
  134.     break;
  135.   }
  136. }
  137. /*********************************************************************
  138. *
  139. *       _cbDialog2
  140. */
  141. static void _cbDialog2(WM_MESSAGE * pMsg) {   //--------------(7)
  142.   WM_HWIN hItem;
  143.   int     NCode;
  144.   int     Id;
  145.   switch (pMsg->MsgId) {
  146.   case WM_INIT_DIALOG:
  147.     //
  148.     // Initialization of 'Framewin2'
  149.     //
  150.     hItem = pMsg->hWin;
  151.     FRAMEWIN_SetText(hItem, "Screen 2");
  152.     FRAMEWIN_SetFont(hItem, GUI_FONT_32_ASCII);
  153.     //
  154.     // Initialization of 'Button'
  155.     //
  156.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  157.     BUTTON_SetText(hItem, "Screen 1");
  158.     //
  159.     // Initialization of 'Button'
  160.     //
  161.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  162.     BUTTON_SetText(hItem, "Screen 3");
  163.     //
  164.     // Initialization of 'Radio'
  165.     //
  166.     hItem = WM_GetDialogItem(pMsg->hWin, ID_RADIO_0);
  167.     RADIO_SetText(hItem, "Item 1", 0);
  168.     RADIO_SetText(hItem, "Item 2", 1);
  169.     RADIO_SetText(hItem, "Item 3", 2);
  170.     break;
  171.   case WM_NOTIFY_PARENT:
  172.     Id    = WM_GetId(pMsg->hWinSrc);
  173.     NCode = pMsg->Data.v;
  174.     switch(Id) {
  175.     case ID_BUTTON_0: // Notifications sent by 'Button'
  176.       switch(NCode) {
  177.       case WM_NOTIFICATION_CLICKED:
  178.         // USER START (Optionally insert code for reacting on notification message)
  179.         // USER END
  180.         break;
  181.       case WM_NOTIFICATION_RELEASED:  //--------------(8)
  182.         GUI_EndDialog(pMsg->hWin, 0);
  183.         GUI_CreateDialogBox(_aDialogCreate1, GUI_COUNTOF(_aDialogCreate1), _cbDialog1, WM_HBKWIN, 0, 0);
  184.         break;
  185.       }
  186.       break;
  187.     case ID_BUTTON_1: // Notifications sent by 'Button'
  188.       switch(NCode) {
  189.       case WM_NOTIFICATION_CLICKED:
  190.         // USER START (Optionally insert code for reacting on notification message)
  191.         // USER END
  192.         break;
  193.       case WM_NOTIFICATION_RELEASED:  //--------------(9)
  194.         GUI_EndDialog(pMsg->hWin, 0);
  195.         GUI_CreateDialogBox(_aDialogCreate3, GUI_COUNTOF(_aDialogCreate3), _cbDialog3, WM_HBKWIN, 0, 0);
  196.         break;
  197.       }
  198.       break;
  199.     case ID_RADIO_0: // Notifications sent by 'Radio'
  200.       switch(NCode) {
  201.       case WM_NOTIFICATION_CLICKED:
  202.         // USER START (Optionally insert code for reacting on notification message)
  203.         // USER END
  204.         break;
  205.       case WM_NOTIFICATION_RELEASED:
  206.         // USER START (Optionally insert code for reacting on notification message)
  207.         // USER END
  208.         break;
  209.       case WM_NOTIFICATION_VALUE_CHANGED:
  210.         // USER START (Optionally insert code for reacting on notification message)
  211.         // USER END
  212.         break;
  213.       }
  214.       break;
  215.     }
  216.     break;
  217.   default:
  218.     WM_DefaultProc(pMsg);
  219.     break;
  220.   }
  221. }
  222. /*********************************************************************
  223. *
  224. *       _cbDialog3
  225. */
  226. static void _cbDialog3(WM_MESSAGE * pMsg) {  //--------------(10)
  227.   WM_HWIN hItem;
  228.   int     NCode;
  229.   int     Id;
  230.   switch (pMsg->MsgId) {
  231.   case WM_INIT_DIALOG:
  232.     //
  233.     // Initialization of 'Framewin3'
  234.     //
  235.     hItem = pMsg->hWin;
  236.     FRAMEWIN_SetText(hItem, "Screen 3");
  237.     FRAMEWIN_SetFont(hItem, GUI_FONT_32_ASCII);
  238.     //
  239.     // Initialization of 'Button'
  240.     //
  241.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  242.     BUTTON_SetText(hItem, "Screen 1");
  243.     //
  244.     // Initialization of 'Button'
  245.     //
  246.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  247.     BUTTON_SetText(hItem, "Screen 2");
  248.     //
  249.     // Initialization of 'Checkbox'
  250.     //
  251.     hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0);
  252.     CHECKBOX_SetText(hItem, "Check me...");
  253.     break;
  254.   case WM_NOTIFY_PARENT:
  255.     Id    = WM_GetId(pMsg->hWinSrc);
  256.     NCode = pMsg->Data.v;
  257.     switch(Id) {
  258.     case ID_BUTTON_0: // Notifications sent by 'Button'
  259.       switch(NCode) {
  260.       case WM_NOTIFICATION_CLICKED:
  261.         // USER START (Optionally insert code for reacting on notification message)
  262.         // USER END
  263.         break;
  264.       case WM_NOTIFICATION_RELEASED: //--------------(11)
  265.         GUI_EndDialog(pMsg->hWin, 0);
  266.         GUI_CreateDialogBox(_aDialogCreate1, GUI_COUNTOF(_aDialogCreate1), _cbDialog1, WM_HBKWIN, 0, 0);
  267.         break;
  268.       }
  269.       break;
  270.     case ID_BUTTON_1: // Notifications sent by 'Button'
  271.       switch(NCode) {
  272.       case WM_NOTIFICATION_CLICKED:
  273.         // USER START (Optionally insert code for reacting on notification message)
  274.         // USER END
  275.         break;
  276.       case WM_NOTIFICATION_RELEASED:  //--------------(12)
  277.         GUI_EndDialog(pMsg->hWin, 0);
  278.         GUI_CreateDialogBox(_aDialogCreate2, GUI_COUNTOF(_aDialogCreate2), _cbDialog2, WM_HBKWIN, 0, 0);
  279.         break;
  280.       }
  281.       break;
  282.     case ID_CHECKBOX_0: // Notifications sent by 'Checkbox'
  283.       switch(NCode) {
  284.       case WM_NOTIFICATION_CLICKED:
  285.         // USER START (Optionally insert code for reacting on notification message)
  286.         // USER END
  287.         break;
  288.       case WM_NOTIFICATION_RELEASED:
  289.         // USER START (Optionally insert code for reacting on notification message)
  290.         // USER END
  291.         break;
  292.       case WM_NOTIFICATION_VALUE_CHANGED:
  293.         // USER START (Optionally insert code for reacting on notification message)
  294.         // USER END
  295.         break;
  296.       }
  297.       break;
  298.     }
  299.     break;
  300.   default:
  301.     WM_DefaultProc(pMsg);
  302.     break;
  303.   }
  304. }
  305. /*********************************************************************
  306. *
  307. *       CreateFramewin1
  308. */
  309. static WM_HWIN CreateFramewin1(void) {  //--------------(13)
  310.   WM_HWIN hWin;
  311.   hWin = GUI_CreateDialogBox(_aDialogCreate1, GUI_COUNTOF(_aDialogCreate1), _cbDialog1, WM_HBKWIN, 0, 0);
  312.   return hWin;
  313. }
  314. /*********************************************************************
  315. *
  316. *       Public code
  317. *
  318. **********************************************************************
  319. */
  320. /*********************************************************************
  321. *
  322. *       MainTask
  323. */
  324. void MainTask(void) {
  325.   #if GUI_SUPPORT_MEMDEV
  326.     WM_SetCreateFlags(WM_CF_MEMDEV);
  327.   #endif
  328.   //
  329.   // Check if recommended memory for the sample is available
  330.   //
  331.   if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
  332.     GUI_ErrorOut("Not enough memory available.");
  333.     return;
  334.   }
  335.   GUI_Init();
  336.   //
  337.   // Enable new skin
  338.   //
  339.   FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);
  340.   BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);
  341.   CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
  342.   RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);
  343.   //
  344.   // Create main menu
  345.   //
  346.   CreateFramewin1();//--------------(14)
  347.   while (1) {
  348.     GUI_Delay(100); //--------------(15)
  349.   }
  350. }
复制代码
1.     对话框1的资源列表。
2.     对话框2的资源列表。
3.     对话框3的资源列表。
4.     对话框1的回调函数。
5.     对话框1的界面中按钮控件ID_BUTTON_0的释放消息,如果用户点击此控件,释放后会触发这个消息。在这个消息里面通过函数GUI_EndDialog关闭对话框1,也就是关闭自己,然后通过函数GUI_CreateDialogBox创建对话框2。
6.     对话框1的界面中按钮控件ID_BUTTON_1的释放消息,如果用户点击此控件,释放后会触发这个消息。在这个消息里面通过函数GUI_EndDialog关闭对话框1,也就是关闭自己,然后通过函数GUI_CreateDialogBox创建对话框3。
7.     对话框2的回调函数。
8.     对话框2的界面中按钮控件ID_BUTTON_0的释放消息(不同对话框或者窗口上的控件ID可以相同,同一个窗口或者对话框上的控件ID必须不同),如果用户点击此控件,释放后会触发这个消息。在这个消息里面通过函数GUI_EndDialog关闭对话框2,也就是关闭自己,然后通过函数GUI_CreateDialogBox创建对话框1。
9.     对话框2的界面中按钮控件ID_BUTTON_1的释放消息,如果用户点击此控件,释放后会触发这个消息。在这个消息里面通过函数GUI_EndDialog关闭对话框2,也就是关闭自己,然后通过函数GUI_CreateDialogBox创建对话框3。
10.  对话框3的回调函数。
11.  对话框3的界面中按钮控件ID_BUTTON_0的释放消息,如果用户点击此控件,释放后会触发这个消息。在这个消息里面通过函数GUI_EndDialog关闭对话框3,也就是关闭自己,然后通过函数GUI_CreateDialogBox创建对话框1。
12.  对话框3的界面中按钮控件ID_BUTTON_1的释放消息,如果用户点击此控件,释放后会触发这个消息。在这个消息里面通过函数GUI_EndDialog关闭对话框3,也就是关闭自己,然后通过函数GUI_CreateDialogBox创建对话框2。
13.  通过函数GUI_CreateDialogBox创建对话框1。
14.  函数GUI_Delay非常关键,前面的章节中,我们多次强调它不仅仅是一个延迟函数,窗口管理器的执行就是通过它来实现的。本例子创建的三个对话框可以正常的切换就靠函数GUI_Delay的执行,当然,周期性的调用函数WM_Exec或者GUI_Exec也是可以的。
---------------
            总的来说,这个例子的框架非常好,用户的界面全部通过对话框去管理,while(1)大循环里面只有一个GUI_Delay,简单实用,而且易于维护
对话框1的显示效果:
64.2.png

对话框2的显示效果:
64.3.png

对话框3的显示效果:
64.4.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-4-2 15:19:14 | 显示全部楼层
64.4 实验例程说明(RTOS)


配套例子:
        V6-605_STemWin实验_多窗口之间切换实例(RTOS)
实验目的:
        1.     本实验主要学习多窗口切换方法。
        2.     emWin功能的实现在MainTask.c文件里面。
实验内容:
        1.     K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
        2.     K2按键按下,实现截图功能,将图片以BMP格式保存到SD卡中。
        3.     GUI任务主要创建了三个对话框,分别是对话框1,对话框2和对话框3,相互之间可以任意切换,通过点击当前对话框上面的两个按钮,可以选择切换到其它两个对话框。切换方法是通过在按钮的释放消息里面调用函数GUI_EndDialog关闭自己,然后调用函数
GUI_CreateDialogBox创建新的对话框。
        4.     各个任务实现的功能如下:
              App Task Start   任务:实现按键和触摸扫描。
              App Task MspPro任务 :实现截图功能,将图片以BMP格式保存到SD卡中。
              App Task UserIF  任务:按键消息处理。
              App Task COM   任务:暂未使用。
             App Task GUI    任务:GUI任务。
μCOS-III任务调试信息(按K1按键,串口打印):
64.5.png

STemWin界面显示效果:
        800*480分辨率界面效果,对话框1:
64.6.png


对话框2:
64.7.png


对话框3:
64.8.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. WM_HWIN CreateFramewin1(void);
  9. WM_HWIN CreateFramewin2(void);
  10. WM_HWIN CreateFramewin3(void);
  11. /*
  12. *********************************************************************************************************
  13. *                                         宏定义
  14. *********************************************************************************************************
  15. */
  16. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
  17. #define ID_BUTTON_0   (GUI_ID_USER + 0x01)
  18. #define ID_BUTTON_1   (GUI_ID_USER + 0x02)
  19. #define ID_CHECKBOX_0 (GUI_ID_USER + 0x03)
  20. #define ID_SLIDER_0   (GUI_ID_USER + 0x04)
  21. #define ID_PROGBAR_0  (GUI_ID_USER + 0x05)
  22. /*
  23. *********************************************************************************************************
  24. *                           GUI_WIDGET_CREATE_INFO类型数组
  25. *********************************************************************************************************
  26. */
  27. static const GUI_WIDGET_CREATE_INFO _aDialogCreate1[] =
  28. {
  29.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  30.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 34, 35, 177, 52, 0, 0x0, 0 },
  31.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 34, 130, 177, 52, 0, 0x0, 0 },
  32.      { CHECKBOX_CreateIndirect, "Checkbox", ID_CHECKBOX_0, 345, 138, 104, 40, 0, 0x0, 0},
  33.    
  34. };
  35. /*
  36. *********************************************************************************************************
  37. *    函 数 名: _cbDialog1
  38. *    功能说明: 对话框回调函数        
  39. *    形    参: pMsg  回调参数
  40. *    返 回 值: 无
  41. *********************************************************************************************************
  42. */
  43. static void _cbDialog1(WM_MESSAGE * pMsg)
  44. {
  45.      WM_HWIN hItem;
  46.      int     NCode;
  47.      int     Id;
  48.    
  49.      switch (pMsg->MsgId)
  50.      {
  51.          case WM_INIT_DIALOG:
  52.               //
  53.               // 初始化框架窗口
  54.               //
  55.               hItem = pMsg->hWin;
  56.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  57.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  58.               FRAMEWIN_SetText(hItem, "Screen 1");
  59.         
  60.               //
  61.               // 初始按钮控件
  62.               //
  63.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  64.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  65.               BUTTON_SetText(hItem, "Screen 2");
  66.         
  67.               //
  68.               // 初始化按钮控件
  69.               //
  70.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  71.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  72.               BUTTON_SetText(hItem, "Screen 3");
  73.             
  74.               //
  75.               // 初始化复选框控件
  76.               //
  77.               hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0);
  78.               CHECKBOX_SetText(hItem, "Check");
  79.               CHECKBOX_SetFont(hItem, GUI_FONT_16_1);
  80.               break;
  81.         
  82.          case WM_NOTIFY_PARENT:
  83.               Id    = WM_GetId(pMsg->hWinSrc);
  84.               NCode = pMsg->Data.v;
  85.               switch(Id)
  86.               {
  87.                    case ID_BUTTON_0:
  88.                        switch(NCode)
  89.                        {
  90.                             case WM_NOTIFICATION_CLICKED:
  91.                                  break;
  92.                            
  93.                             /* 关闭当前对话框, 创建对话框2 */
  94.                             case WM_NOTIFICATION_RELEASED:
  95.                                  GUI_EndDialog(pMsg->hWin, 0);
  96.                                  CreateFramewin2();
  97.                                  break;
  98.                        }
  99.                        break;
  100.                      
  101.                  case ID_BUTTON_1:
  102.                        switch(NCode)
  103.                        {
  104.                             case WM_NOTIFICATION_CLICKED:
  105.                                  break;
  106.                            
  107.                             /* 关闭当前对话框, 创建对话框3 */
  108.                             case WM_NOTIFICATION_RELEASED:
  109.                                  GUI_EndDialog(pMsg->hWin, 0);
  110.                                  CreateFramewin3();
  111.                                  break;
  112.                        }
  113.                        break;
  114.               }
  115.               break;
  116.             
  117.          default:
  118.               WM_DefaultProc(pMsg);
  119.               break;
  120.      }
  121. }
  122. /*
  123. *********************************************************************************************************
  124. *    函 数 名: CreateFramewin1
  125. *    功能说明: 创建对话框      
  126. *    形    参: 无
  127. *    返 回 值: 返回对话框句柄
  128. *********************************************************************************************************
  129. */
  130. WM_HWIN CreateFramewin1(void)
  131. {
  132.      WM_HWIN hWin;
  133.      hWin = GUI_CreateDialogBox(_aDialogCreate1, GUI_COUNTOF(_aDialogCreate1), _cbDialog1, WM_HBKWIN, 0, 0);
  134.      return hWin;
  135. }
  136. /*
  137. *********************************************************************************************************
  138. *                           GUI_WIDGET_CREATE_INFO类型数组
  139. *********************************************************************************************************
  140. */
  141. static const GUI_WIDGET_CREATE_INFO _aDialogCreate2[] =
  142. {
  143.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  144.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 34, 35, 177, 52, 0, 0x0, 0 },
  145.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 34, 130, 177, 52, 0, 0x0, 0 },
  146.      { SLIDER_CreateIndirect, "Slider", ID_SLIDER_0, 285, 230, 189, 37, 0, 0x0, 0 },
  147.    
  148. };
  149. /*
  150. *********************************************************************************************************
  151. *    函 数 名: _cbDialog2
  152. *    功能说明: 对话框回调函数        
  153. *    形    参: pMsg  回调参数
  154. *    返 回 值: 无
  155. *********************************************************************************************************
  156. */
  157. static void _cbDialog2(WM_MESSAGE * pMsg)
  158. {
  159.      WM_HWIN hItem;
  160.      int     NCode;
  161.      int     Id;
  162.    
  163.      switch (pMsg->MsgId)
  164.      {
  165.          case WM_INIT_DIALOG:
  166.               //
  167.               // 初始化框架窗口
  168.               //
  169.               hItem = pMsg->hWin;
  170.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  171.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  172.               FRAMEWIN_SetText(hItem, "Screen 2");
  173.         
  174.               //
  175.               // 初始按钮控件
  176.               //
  177.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  178.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  179.               BUTTON_SetText(hItem, "Screen 1");
  180.         
  181.               //
  182.               // 初始化按钮控件
  183.               //
  184.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  185.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  186.               BUTTON_SetText(hItem, "Screen 3");
  187.               break;
  188.         
  189.          case WM_NOTIFY_PARENT:
  190.               Id    = WM_GetId(pMsg->hWinSrc);
  191.               NCode = pMsg->Data.v;
  192.               switch(Id)
  193.               {
  194.                    case ID_BUTTON_0:
  195.                        switch(NCode)
  196.                        {
  197.                             case WM_NOTIFICATION_CLICKED:
  198.                                  break;
  199.                            
  200.                             /* 关闭当前对话框, 创建对话框1 */
  201.                             case WM_NOTIFICATION_RELEASED:
  202.                                  GUI_EndDialog(pMsg->hWin, 0);
  203.                                  CreateFramewin1();
  204.                                  break;
  205.                        }
  206.                        break;
  207.                      
  208.                    case ID_BUTTON_1:
  209.                        switch(NCode)
  210.                        {
  211.                             case WM_NOTIFICATION_CLICKED:
  212.                                 break;
  213.                            
  214.                             /* 关闭当前对话框, 创建对话框3 */
  215.                             case WM_NOTIFICATION_RELEASED:
  216.                                  GUI_EndDialog(pMsg->hWin, 0);
  217.                                  CreateFramewin3();
  218.                                  break;
  219.                        }
  220.                        break;
  221.               }
  222.               break;
  223.             
  224.          default:
  225.               WM_DefaultProc(pMsg);
  226.               break;
  227.      }
  228. }
  229. /*
  230. *********************************************************************************************************
  231. *    函 数 名: CreateFramewin2
  232. *    功能说明: 创建对话框      
  233. *    形    参: 无
  234. *    返 回 值: 返回对话框句柄
  235. *********************************************************************************************************
  236. */
  237. WM_HWIN CreateFramewin2(void)
  238. {
  239.      WM_HWIN hWin;
  240.      hWin = GUI_CreateDialogBox(_aDialogCreate2, GUI_COUNTOF(_aDialogCreate2), _cbDialog2, WM_HBKWIN, 0, 0);
  241.      return hWin;
  242. }
  243. /*
  244. *********************************************************************************************************
  245. *                           GUI_WIDGET_CREATE_INFO类型数组
  246. *********************************************************************************************************
  247. */
  248. static const GUI_WIDGET_CREATE_INFO _aDialogCreate3[] =
  249. {
  250.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  251.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 34, 35, 177, 52, 0, 0x0, 0 },
  252.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 34, 130, 177, 52, 0, 0x0, 0 },
  253.     { PROGBAR_CreateIndirect, "Progbar", ID_PROGBAR_0, 264, 213, 251, 39, 0, 0x0, 0},
  254. };
  255. /*
  256. *********************************************************************************************************
  257. *    函 数 名: _cbDialog3
  258. *    功能说明: 对话框回调函数        
  259. *    形    参: pMsg  回调参数
  260. *    返 回 值: 无
  261. *********************************************************************************************************
  262. */
  263. static void _cbDialog3(WM_MESSAGE * pMsg)
  264. {
  265.      WM_HWIN hItem;
  266.      int     NCode;
  267.      int     Id;
  268.    
  269.      switch (pMsg->MsgId)
  270.      {
  271.          case WM_INIT_DIALOG:
  272.               //
  273.               // 初始化框架窗口
  274.               //
  275.               hItem = pMsg->hWin;
  276.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  277.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  278.               FRAMEWIN_SetText(hItem, "Screen 3");
  279.         
  280.               //
  281.               // 初始按钮控件
  282.               //
  283.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  284.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  285.               BUTTON_SetText(hItem, "Screen 1");
  286.         
  287.               //
  288.               // 初始化按钮控件
  289.               //
  290.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  291.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  292.               BUTTON_SetText(hItem, "Screen 2");
  293.               break;
  294.         
  295.          case WM_NOTIFY_PARENT:
  296.               Id    = WM_GetId(pMsg->hWinSrc);
  297.               NCode = pMsg->Data.v;
  298.               switch(Id)
  299.               {
  300.                    case ID_BUTTON_0:
  301.                        switch(NCode)
  302.                        {
  303.                             case WM_NOTIFICATION_CLICKED:
  304.                                  break;
  305.                            
  306.                             /* 关闭当前对话框, 创建对话框1 */
  307.                             case WM_NOTIFICATION_RELEASED:
  308.                                  GUI_EndDialog(pMsg->hWin, 0);
  309.                                  CreateFramewin1();
  310.                                  break;
  311.                        }
  312.                        break;
  313.                      
  314.                    case ID_BUTTON_1:
  315.                        switch(NCode)
  316.                        {
  317.                             case WM_NOTIFICATION_CLICKED:
  318.                                  break;
  319.                            
  320.                             /* 关闭当前对话框, 创建对话框2 */
  321.                             case WM_NOTIFICATION_RELEASED:
  322.                                  GUI_EndDialog(pMsg->hWin, 0);
  323.                                  CreateFramewin2();
  324.                                  break;
  325.                        }
  326.                        break;
  327.               }
  328.               break;
  329.             
  330.          default:
  331.               WM_DefaultProc(pMsg);
  332.               break;
  333.      }
  334. }
  335. /*
  336. *********************************************************************************************************
  337. *    函 数 名: CreateFramewin3
  338. *    功能说明: 创建对话框      
  339. *    形    参: 无
  340. *    返 回 值: 返回对话框句柄
  341. *********************************************************************************************************
  342. */
  343. WM_HWIN CreateFramewin3(void)
  344. {
  345.      WM_HWIN hWin;
  346.      hWin = GUI_CreateDialogBox(_aDialogCreate3, GUI_COUNTOF(_aDialogCreate3), _cbDialog3, WM_HBKWIN, 0, 0);
  347.      return hWin;
  348. }
  349. /*
  350. *********************************************************************************************************
  351. *    函 数 名: MainTask
  352. *    功能说明: GUI主函数
  353. *    形    参: 无
  354. *    返 回 值: 无
  355. *********************************************************************************************************
  356. */
  357. void MainTask(void)
  358. {
  359.      /* 初始化 */
  360.      GUI_Init();
  361.    
  362.      /*
  363.       关于多缓冲和窗口内存设备的设置说明
  364.         1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
  365.            WM_MULTIBUF_Enable(1);
  366.         2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
  367.         3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
  368.            STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
  369.            感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
  370.         4. 所有emWin例子默认是开启三缓冲。
  371.      */
  372.      WM_MULTIBUF_Enable(1);
  373.    
  374.      /*
  375.        触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
  376.         此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
  377.      */
  378.     //TOUCH_Calibration();
  379.    
  380.      /* 创建对话框 */
  381.      CreateFramewin1();
  382.         
  383.      while(1)
  384.      {
  385.          GUI_Delay(50);
  386.      }
  387. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-4-2 15:22:44 | 显示全部楼层
64.5 实验例程说明(裸机)


配套例子:
        V6-606_STemWin实验_多窗口之间切换实例(裸机)
实验目的:
        1.     本实验主要学习多窗口切换方法。
        2.     emWin功能的实现在MainTask.c文件里面。
实验内容:
        1.     GUI任务主要创建了三个对话框,分别是对话框1,对话框2和对话框3,相互之间可以任意切换,通过点击当前对话框上面的两个按钮,可以选择切换到其它两个对话框。切换方法是通过在按钮的释放消息里面调用函数GUI_EndDialog关闭自己,然后调用函数
GUI_CreateDialogBox创建新的对话框。
STemWin界面显示效果:
        800*480分辨率界面效果,对话框1:
64.9.png


对话框2:
64.10.png


对话框3:
64.11.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文件中配置:
64.12.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. WM_HWIN CreateFramewin1(void);
  9. WM_HWIN CreateFramewin2(void);
  10. WM_HWIN CreateFramewin3(void);
  11. /*
  12. *********************************************************************************************************
  13. *                                         宏定义
  14. *********************************************************************************************************
  15. */
  16. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
  17. #define ID_BUTTON_0   (GUI_ID_USER + 0x01)
  18. #define ID_BUTTON_1   (GUI_ID_USER + 0x02)
  19. #define ID_CHECKBOX_0 (GUI_ID_USER + 0x03)
  20. #define ID_SLIDER_0   (GUI_ID_USER + 0x04)
  21. #define ID_PROGBAR_0  (GUI_ID_USER + 0x05)
  22. /*
  23. *********************************************************************************************************
  24. *                           GUI_WIDGET_CREATE_INFO类型数组
  25. *********************************************************************************************************
  26. */
  27. static const GUI_WIDGET_CREATE_INFO _aDialogCreate1[] =
  28. {
  29.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  30.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 34, 35, 177, 52, 0, 0x0, 0 },
  31.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 34, 130, 177, 52, 0, 0x0, 0 },
  32.      { CHECKBOX_CreateIndirect, "Checkbox", ID_CHECKBOX_0, 345, 138, 104, 40, 0, 0x0, 0},
  33.    
  34. };
  35. /*
  36. *********************************************************************************************************
  37. *    函 数 名: _cbDialog1
  38. *    功能说明: 对话框回调函数        
  39. *    形    参: pMsg  回调参数
  40. *    返 回 值: 无
  41. *********************************************************************************************************
  42. */
  43. static void _cbDialog1(WM_MESSAGE * pMsg)
  44. {
  45.      WM_HWIN hItem;
  46.      int     NCode;
  47.      int     Id;
  48.    
  49.      switch (pMsg->MsgId)
  50.      {
  51.          case WM_INIT_DIALOG:
  52.               //
  53.               // 初始化框架窗口
  54.               //
  55.               hItem = pMsg->hWin;
  56.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  57.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  58.               FRAMEWIN_SetText(hItem, "Screen 1");
  59.         
  60.               //
  61.               // 初始按钮控件
  62.               //
  63.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  64.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  65.               BUTTON_SetText(hItem, "Screen 2");
  66.         
  67.               //
  68.               // 初始化按钮控件
  69.               //
  70.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  71.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  72.               BUTTON_SetText(hItem, "Screen 3");
  73.             
  74.               //
  75.               // 初始化复选框控件
  76.               //
  77.               hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0);
  78.               CHECKBOX_SetText(hItem, "Check");
  79.               CHECKBOX_SetFont(hItem, GUI_FONT_16_1);
  80.               break;
  81.         
  82.          case WM_NOTIFY_PARENT:
  83.               Id    = WM_GetId(pMsg->hWinSrc);
  84.               NCode = pMsg->Data.v;
  85.               switch(Id)
  86.               {
  87.                    case ID_BUTTON_0:
  88.                        switch(NCode)
  89.                        {
  90.                             case WM_NOTIFICATION_CLICKED:
  91.                                  break;
  92.                            
  93.                             /* 关闭当前对话框, 创建对话框2 */
  94.                             case WM_NOTIFICATION_RELEASED:
  95.                                  GUI_EndDialog(pMsg->hWin, 0);
  96.                                  CreateFramewin2();
  97.                                  break;
  98.                        }
  99.                        break;
  100.                      
  101.                  case ID_BUTTON_1:
  102.                        switch(NCode)
  103.                        {
  104.                             case WM_NOTIFICATION_CLICKED:
  105.                                  break;
  106.                            
  107.                             /* 关闭当前对话框, 创建对话框3 */
  108.                             case WM_NOTIFICATION_RELEASED:
  109.                                  GUI_EndDialog(pMsg->hWin, 0);
  110.                                  CreateFramewin3();
  111.                                  break;
  112.                        }
  113.                        break;
  114.               }
  115.               break;
  116.             
  117.          default:
  118.               WM_DefaultProc(pMsg);
  119.               break;
  120.      }
  121. }
  122. /*
  123. *********************************************************************************************************
  124. *    函 数 名: CreateFramewin1
  125. *    功能说明: 创建对话框      
  126. *    形    参: 无
  127. *    返 回 值: 返回对话框句柄
  128. *********************************************************************************************************
  129. */
  130. WM_HWIN CreateFramewin1(void)
  131. {
  132.      WM_HWIN hWin;
  133.      hWin = GUI_CreateDialogBox(_aDialogCreate1, GUI_COUNTOF(_aDialogCreate1), _cbDialog1, WM_HBKWIN, 0, 0);
  134.      return hWin;
  135. }
  136. /*
  137. *********************************************************************************************************
  138. *                           GUI_WIDGET_CREATE_INFO类型数组
  139. *********************************************************************************************************
  140. */
  141. static const GUI_WIDGET_CREATE_INFO _aDialogCreate2[] =
  142. {
  143.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  144.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 34, 35, 177, 52, 0, 0x0, 0 },
  145.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 34, 130, 177, 52, 0, 0x0, 0 },
  146.      { SLIDER_CreateIndirect, "Slider", ID_SLIDER_0, 285, 230, 189, 37, 0, 0x0, 0 },
  147.    
  148. };
  149. /*
  150. *********************************************************************************************************
  151. *    函 数 名: _cbDialog2
  152. *    功能说明: 对话框回调函数        
  153. *    形    参: pMsg  回调参数
  154. *    返 回 值: 无
  155. *********************************************************************************************************
  156. */
  157. static void _cbDialog2(WM_MESSAGE * pMsg)
  158. {
  159.      WM_HWIN hItem;
  160.      int     NCode;
  161.      int     Id;
  162.    
  163.      switch (pMsg->MsgId)
  164.      {
  165.          case WM_INIT_DIALOG:
  166.               //
  167.               // 初始化框架窗口
  168.               //
  169.               hItem = pMsg->hWin;
  170.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  171.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  172.               FRAMEWIN_SetText(hItem, "Screen 2");
  173.         
  174.               //
  175.               // 初始按钮控件
  176.               //
  177.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  178.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  179.               BUTTON_SetText(hItem, "Screen 1");
  180.         
  181.               //
  182.               // 初始化按钮控件
  183.               //
  184.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  185.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  186.               BUTTON_SetText(hItem, "Screen 3");
  187.               break;
  188.         
  189.          case WM_NOTIFY_PARENT:
  190.               Id    = WM_GetId(pMsg->hWinSrc);
  191.               NCode = pMsg->Data.v;
  192.               switch(Id)
  193.               {
  194.                    case ID_BUTTON_0:
  195.                        switch(NCode)
  196.                        {
  197.                             case WM_NOTIFICATION_CLICKED:
  198.                                  break;
  199.                            
  200.                             /* 关闭当前对话框, 创建对话框1 */
  201.                             case WM_NOTIFICATION_RELEASED:
  202.                                  GUI_EndDialog(pMsg->hWin, 0);
  203.                                  CreateFramewin1();
  204.                                  break;
  205.                        }
  206.                        break;
  207.                      
  208.                    case ID_BUTTON_1:
  209.                        switch(NCode)
  210.                        {
  211.                             case WM_NOTIFICATION_CLICKED:
  212.                                  break;
  213.                            
  214.                             /* 关闭当前对话框, 创建对话框3 */
  215.                             case WM_NOTIFICATION_RELEASED:
  216.                                  GUI_EndDialog(pMsg->hWin, 0);
  217.                                  CreateFramewin3();
  218.                                  break;
  219.                        }
  220.                        break;
  221.               }
  222.               break;
  223.             
  224.          default:
  225.               WM_DefaultProc(pMsg);
  226.               break;
  227.      }
  228. }
  229. /*
  230. *********************************************************************************************************
  231. *    函 数 名: CreateFramewin2
  232. *    功能说明: 创建对话框      
  233. *    形    参: 无
  234. *    返 回 值: 返回对话框句柄
  235. *********************************************************************************************************
  236. */
  237. WM_HWIN CreateFramewin2(void)
  238. {
  239.      WM_HWIN hWin;
  240.      hWin = GUI_CreateDialogBox(_aDialogCreate2, GUI_COUNTOF(_aDialogCreate2), _cbDialog2, WM_HBKWIN, 0, 0);
  241.      return hWin;
  242. }
  243. /*
  244. *********************************************************************************************************
  245. *                           GUI_WIDGET_CREATE_INFO类型数组
  246. *********************************************************************************************************
  247. */
  248. static const GUI_WIDGET_CREATE_INFO _aDialogCreate3[] =
  249. {
  250.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },
  251.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 34, 35, 177, 52, 0, 0x0, 0 },
  252.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_1, 34, 130, 177, 52, 0, 0x0, 0 },
  253.     { PROGBAR_CreateIndirect, "Progbar", ID_PROGBAR_0, 264, 213, 251, 39, 0, 0x0, 0},
  254. };
  255. /*
  256. *********************************************************************************************************
  257. *    函 数 名: _cbDialog3
  258. *    功能说明: 对话框回调函数        
  259. *    形    参: pMsg  回调参数
  260. *    返 回 值: 无
  261. *********************************************************************************************************
  262. */
  263. static void _cbDialog3(WM_MESSAGE * pMsg)
  264. {
  265.      WM_HWIN hItem;
  266.      int     NCode;
  267.      int     Id;
  268.    
  269.      switch (pMsg->MsgId)
  270.      {
  271.          case WM_INIT_DIALOG:
  272.               //
  273.               // 初始化框架窗口
  274.               //
  275.               hItem = pMsg->hWin;
  276.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  277.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  278.               FRAMEWIN_SetText(hItem, "Screen 3");
  279.         
  280.               //
  281.               // 初始按钮控件
  282.               //
  283.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  284.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  285.               BUTTON_SetText(hItem, "Screen 1");
  286.         
  287.               //
  288.               // 初始化按钮控件
  289.               //
  290.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
  291.               BUTTON_SetFont(hItem, GUI_FONT_20_1);
  292.               BUTTON_SetText(hItem, "Screen 2");
  293.               break;
  294.         
  295.          case WM_NOTIFY_PARENT:
  296.               Id    = WM_GetId(pMsg->hWinSrc);
  297.               NCode = pMsg->Data.v;
  298.               switch(Id)
  299.               {
  300.                    case ID_BUTTON_0:
  301.                        switch(NCode)
  302.                        {
  303.                             case WM_NOTIFICATION_CLICKED:
  304.                                  break;
  305.                            
  306.                             /* 关闭当前对话框, 创建对话框1 */
  307.                             case WM_NOTIFICATION_RELEASED:
  308.                                  GUI_EndDialog(pMsg->hWin, 0);
  309.                                  CreateFramewin1();
  310.                                  break;
  311.                        }
  312.                        break;
  313.                      
  314.                    case ID_BUTTON_1:
  315.                        switch(NCode)
  316.                        {
  317.                             case WM_NOTIFICATION_CLICKED:
  318.                                  break;
  319.                            
  320.                             /* 关闭当前对话框, 创建对话框2 */
  321.                             case WM_NOTIFICATION_RELEASED:
  322.                                  GUI_EndDialog(pMsg->hWin, 0);
  323.                                  CreateFramewin2();
  324.                                  break;
  325.                        }
  326.                        break;
  327.               }
  328.               break;
  329.             
  330.          default:
  331.               WM_DefaultProc(pMsg);
  332.               break;
  333.      }
  334. }
  335. /*
  336. *********************************************************************************************************
  337. *    函 数 名: CreateFramewin3
  338. *    功能说明: 创建对话框      
  339. *    形    参: 无
  340. *    返 回 值: 返回对话框句柄
  341. *********************************************************************************************************
  342. */
  343. WM_HWIN CreateFramewin3(void)
  344. {
  345.      WM_HWIN hWin;
  346.      hWin = GUI_CreateDialogBox(_aDialogCreate3, GUI_COUNTOF(_aDialogCreate3), _cbDialog3, WM_HBKWIN, 0, 0);
  347.      return hWin;
  348. }
  349. /*
  350. *********************************************************************************************************
  351. *    函 数 名: MainTask
  352. *    功能说明: GUI主函数
  353. *    形    参: 无
  354. *    返 回 值: 无
  355. *********************************************************************************************************
  356. */
  357. void MainTask(void)
  358. {
  359.      /* 初始化 */
  360.      GUI_Init();
  361.    
  362.      /*
  363.       关于多缓冲和窗口内存设备的设置说明
  364.         1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
  365.            WM_MULTIBUF_Enable(1);
  366.         2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
  367.         3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
  368.            STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
  369.            感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
  370.         4. 所有emWin例子默认是开启三缓冲。
  371.      */
  372.      WM_MULTIBUF_Enable(1);
  373.    
  374.      /*
  375.        触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
  376.         此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
  377.      */
  378.     //TOUCH_Calibration();
  379.    
  380.      /* 创建对话框 */
  381.      CreateFramewin1();
  382.         
  383.      while(1)
  384.      {
  385.          GUI_Delay(50);
  386.      }
  387. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-4-2 15:23:18 | 显示全部楼层
64.6 总结


        本章节为大家讲解的多个窗口切换是非常重要的一个知识点,初学者不仅仅要把本章节的例子掌握熟练,而且要多做这方面的练习。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

3

主题

22

回帖

31

积分

新手上路

积分
31
发表于 2019-5-16 10:26:17 | 显示全部楼层
很强啊,谢谢楼主的分享
回复

使用道具 举报

5

主题

12

回帖

27

积分

新手上路

积分
27
发表于 2022-5-15 11:24:52 | 显示全部楼层
好东西,正需要!
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-12 07:24 , Processed in 0.246978 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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