第29章 STemWin多任务(uCOS-III)
本期教程主要是在开发板实现上期教程中所说的三种系统。这里大家重点学习一下官方推荐的设计框架即可,如果有不懂的函数会在后面跟大家讲。
29. 1 单任务系统(超级循环)
29. 2 多任务系统:一个任务调用emWin
29. 3 多任务系统:多个任务调用emWin
29. 4 总结
29.1 单任务系统(超级循环)
工程代码的结构如下:
关于移植的知识已经在前面的第二章详细讲解了,这里重点介绍时间框架和接口函数。
29.1.1 内核接口
内核接口文件GUI_X.C内容如下:
- ----------------------------------------------------------------------
- File : GUI_X.C
- Purpose : Config / System dependent externals for GUI
- ---------------------------END-OF-HEADER------------------------------
- */
-
- #include "GUI.h"
- #include "stm32f4xx.h"
-
-
-
- /*********************************************************************
- *
- * Timing:
- * GUI_X_GetTime()
- * GUI_X_Delay(int)
-
- Some timing dependent routines require a GetTime
- and delay function. Default time unit (tick), normally is
- 1 ms.
- */
- extern __IO int32_t g_iRunTime;(1)
- int GUI_X_GetTime(void)(2)
- {
-
- return g_iRunTime;
- }
-
- void GUI_X_Delay(int ms)(3)
- {
- int tEnd = g_iRunTime + ms;
- while ((tEnd - g_iRunTime) > 0);
- }
-
- /*********************************************************************
- *
- * GUI_X_Init()
- *
- * Note:
- * GUI_X_Init() is called from GUI_Init is a possibility to init
- * some hardware which needs to be up and running before the GUI.
- * If not required, leave this routine blank.
- */
-
- void GUI_X_Init(void) {}
-
-
- /*********************************************************************
- *
- * GUI_X_ExecIdle
- *
- * Note:
- * Called if WM is in idle state
- */
-
- void GUI_X_ExecIdle(void) {}
-
- /*********************************************************************
- *
- * Logging: OS dependent
-
- Note:
- Logging is used in higher debug levels only. The typical target
- build does not use logging and does therefor not require any of
- the logging routines below. For a release build without logging
- the routines below may be eliminated to save some space.
- (If the linker is not function aware and eliminates unreferenced
- functions automatically)
-
- */
-
- void GUI_X_Log (const char *s) { GUI_USE_PARA(s); }
- void GUI_X_Warn (const char *s) { GUI_USE_PARA(s); }
- void GUI_X_ErrorOut(const char *s) { GUI_USE_PARA(s); }
1. 时间基准全局变量,这个变量在bsp_timer.c文件里面进行了定义,由嘀嗒定时器中断进行调用,每1ms调用一次。
-
- /*
- 全局运行时间,单位1ms
- 最长可以表示 24.85天,如果你的产品连续运行时间超过这个数,则必须考虑溢出问题
- */
- __IO int32_t g_iRunTime = 0;
- /*
- *********************************************************************************************************
- * 函 数 名: SysTick_ISR
- * 功能说明: SysTick中断服务程序,每隔1ms进入1次
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void SysTick_ISR(void)
- {
- static uint8_t s_count = 0;
- uint8_t i;
-
- /* 每隔1ms进来1次 (仅用于 bsp_DelayMS) */
- if (s_uiDelayCount > 0)
- {
- if (--s_uiDelayCount == 0)
- {
- s_ucTimeOutFlag = 1;
- }
- }
-
- /* 每隔1ms,对软件定时器的计数器进行减一操作 */
- for (i = 0; i < TMR_COUNT; i++)
- {
- bsp_SoftTimerDec(&s_tTmr[i]);
- }
-
- /* 全局运行时间每1ms增1 */
- g_iRunTime++;
- if (g_iRunTime == 0x7FFFFFFF) /* 这个变量是 int32_t 类型,最大数为 0x7FFFFFFF */
- {
- g_iRunTime = 0;
- }
-
- bsp_RunPer1ms(); /* 每隔1ms调用一次此函数,此函数在 bsp.c */
-
- if (++s_count >= 10)
- {
- s_count = 0;
-
- bsp_RunPer10ms(); /* 每隔10ms调用一次此函数,此函数在 bsp.c */
- }
- }
2. 供STemWin调用的接口函数,用于获取系统时钟基准。
3. 供STemWin调用的接口函数,用于延迟时间设置。
4. 主要设置上面两个函数即可,其余函数根据需要进行配置。
29.1.2 触摸接口
触摸部分由嘀嗒定时器中周期性的调用:
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_RunPer10ms
- * 功能说明: 该函数每隔10ms被调用1次。在bsp_timer.c的定时中断调用。主要用于硬件事件检测
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- extern __IO uint8_t s_ucRA8875BusyNow;
- void bsp_RunPer10ms(void)
- {
- /* RA8875 触摸*/
- if (g_ChipID == IC_8875)
- {
- /* 资源共享标志 */
- if(s_ucRA8875BusyNow == 0)
- {
- GUI_TOUCH_Exec();
- }
- }
- /* XPT2046 */
- else
- {
- GUI_TOUCH_Exec();
- }
- }
在文件main.c
- /*
- *********************************************************************************************************
- * 函 数 名: main
- * 功能说明: c程序入口
- * 形 参:无
- * 返 回 值: 错误代码(无需处理)
- *********************************************************************************************************
- */
- int main(void)
- {
- bsp_Init(); /* 为了是main函数看起来更简洁些,我们将硬件初始化的代码封装到这个函数 */
-
- MainTask();
- }
在文件MainTask.c
- /*
- *********************************************************************************************************
- * 函 数 名: main
- * 功能说明: c程序入口
- * 形 参:无
- * 返 回 值: 错误代码(无需处理)
- *********************************************************************************************************
- */
- void MainTask(void)
- {
- int xPos;
- int yPos;
- int xSize;
- int i;
-
- i = 0;
- /* 初始化 */
- GUI_Init();
- /* 获取要显示的X,Y坐标 */
- xPos = LCD_GetXSize() / 2;
- yPos = LCD_GetYSize() / 3;
- /* 设置文本显示模式 */
- GUI_SetTextMode(GUI_TM_REV);
- /* 设置显示字体 */
- GUI_SetFont(GUI_FONT_20F_ASCII);
- GUI_DispStringHCenterAt("Hello world!", xPos, yPos);
- /* 设置显示数字字体 */
- GUI_SetFont(GUI_FONT_D24X32);
- /* 获取显示0000,在字体GUI_FONT_D24X32下的显示情况 */
- xSize = GUI_GetStringDistX("0000");
- /* 设置显示位置 */
- xPos -= xSize / 2;
- yPos += 24 + 10;
- while (1)
- {
- GUI_DispDecAt( i++, xPos, yPos, 4);
- if (i > 9999)
- {
- i = 0;
- }
- }
- }
功能比较简单,实现效果如下:
29.2 多任务系统:一个任务调用emWin
前面几期教程配套的例子都是采用的这种方式,实现这种方式也是分为三部分
29.2.1 内核接口
内核接口文件GUI_X.C内容如下:
- #include <app_cfg.h>
- #include <includes.h>
- #include "GUI_Private.H"
- #include "stdio.H"
-
- /*
- *********************************************************************************************************
- * GLOBAL VARIABLES
- *********************************************************************************************************
- */
-
- static OS_SEM DispSem;
- static OS_SEM EventSem;
-
- static OS_SEM KeySem;
- static int KeyPressed;
- static char KeyIsInited;
-
-
- /*
- *********************************************************************************************************
- * TIMING FUNCTIONS
- *
- * Notes: Some timing dependent routines of uC/GUI require a GetTime and delay funtion.
- * Default time unit (tick), normally is 1 ms.
- *********************************************************************************************************
- */
-
- int GUI_X_GetTime (void) (1)
- {
- OS_ERR err;
- return OSTimeGet(&err);
- }
-
-
- void GUI_X_Delay (int period) (2)
- {
- OS_ERR err;
- OSTimeDly(period, OS_OPT_TIME_DLY, &err);
- }
-
-
- /*
- *********************************************************************************************************
- * GUI_X_ExecIdle()
- *********************************************************************************************************
- */
- void GUI_X_ExecIdle (void) (3)
- {
- GUI_X_Delay(1);
- }
-
-
- /*
- *********************************************************************************************************
- * MULTITASKING INTERFACE FUNCTIONS
- *
- * Note(1): 1) The following routines are required only if uC/GUI is used in a true multi task environment,
- * which means you have more than one thread using the uC/GUI API. In this case the #define
- * GUI_OS 1 needs to be in GUIConf.h
- *********************************************************************************************************
- */
-
- void GUI_X_InitOS (void)(4)
- {
- OS_ERR err;
-
- /* 用于资源共享 cnt = 1*/
- OSSemCreate((OS_SEM *)&DispSem,
- (CPU_CHAR *)"DispSem",
- (OS_SEM_CTR )1,
- (OS_ERR *)&err);
- /* 用于事件触发 cnt = 0*/
- OSSemCreate((OS_SEM *)&EventSem,
- (CPU_CHAR *)"EventSem",
- (OS_SEM_CTR )0,
- (OS_ERR *)&err);
- }
-
- void GUI_X_Lock (void)(5)
- {
- OS_ERR err;
- OSSemPend((OS_SEM *)&DispSem,
- (OS_TICK )0,
- (OS_OPT )OS_OPT_PEND_BLOCKING,
- (CPU_TS )0,
- (OS_ERR *)&err);
- }
-
- void GUI_X_Unlock (void)(6)
- {
- OS_ERR err;
-
- OSSemPost((OS_SEM *)&DispSem,
- (OS_OPT )OS_OPT_POST_1,
- (OS_ERR *)&err);
- }
-
-
- U32 GUI_X_GetTaskId (void) (7)
- {
- //由于存在同优先级的任务,这里不知道是不是可以
- //uCOS-III中已经没有任务的ID
- return ((U32)(OSTCBCurPtr->Prio));
- }
-
- /*
- *********************************************************************************************************
- * GUI_X_WaitEvent()
- * GUI_X_SignalEvent()
- *********************************************************************************************************
- */
-
-
- void GUI_X_WaitEvent (void) (8)
- {
- OS_ERR err;
- OSSemPend((OS_SEM *)&EventSem,
- (OS_TICK )0,
- (OS_OPT )OS_OPT_PEND_BLOCKING,
- (CPU_TS )0,
- (OS_ERR *)&err);
- }
-
-
- void GUI_X_SignalEvent (void) (9)
- {
- OS_ERR err;
-
- OSSemPost((OS_SEM *)&EventSem,
- (OS_OPT )OS_OPT_POST_1,
- (OS_ERR *)&err);
- }
-
- /*
- *********************************************************************************************************
- * KEYBOARD INTERFACE FUNCTIONS
- *
- * Purpose: The keyboard routines are required only by some widgets.
- * If widgets are not used, they may be eliminated.
- *
- * Note(s): If uC/OS-II is used, characters typed into the log window will be placed in the keyboard buffer.
- * This is a neat feature which allows you to operate your target system without having to use or
- * even to have a keyboard connected to it. (useful for demos !)
- *********************************************************************************************************
- */
-
- void CheckInit (void) (10)
- {
- if (KeyIsInited == DEF_FALSE) {
- KeyIsInited = DEF_TRUE;
- GUI_X_Init();
- }
- }
-
- void GUI_X_Init (void)
- {
- OS_ERR err;
- OSSemCreate((OS_SEM *)&KeySem,
- (CPU_CHAR *)"KeySem",
- (OS_SEM_CTR )0,
- (OS_ERR *)&err);
- }
-
- int GUI_X_GetKey (void)
- {
- int r;
-
- r = KeyPressed;
- CheckInit();
- KeyPressed = 0;
- return (r);
- }
-
- int GUI_X_WaitKey (void)
- {
- int r;
- OS_ERR err;
-
-
- CheckInit();
- if (KeyPressed == 0) {
- OSSemPend((OS_SEM *)&EventSem,
- (OS_TICK )0,
- (OS_OPT )OS_OPT_PEND_BLOCKING,
- (CPU_TS )0,
- (OS_ERR *)&err);
- }
- r = KeyPressed;
- KeyPressed = 0;
- return (r);
- }
-
- void GUI_X_StoreKey (int k)
- {
- OS_ERR err;
- KeyPressed = k;
- OSSemPost((OS_SEM *)&KeySem,
- (OS_OPT )OS_OPT_POST_1,
- (OS_ERR *)&err);
- }
-
- void GUI_X_Log (const char *s) { GUI_USE_PARA(s); }(11)
- void GUI_X_Warn (const char *s) { GUI_USE_PARA(s); }
- void GUI_X_ErrorOut(const char *s) { GUI_USE_PARA(s); }
1. 用于给系统提供时间基准。
2. 用于实现延迟。
3. 用于执行空闲的调用。
4. 创建两个信号量,一个用于资源的共享,另一个用于事件的同步。
5. 这个函数用于锁定GUI,此函数在GUI访问显示器之前或在使用关键内部数据结构之前由GUI调用,它使用资源信号量/互斥体阻止其它线程进入同一临界区,直到GUI_X_Unlock()已被调用。
6. 这个函数用于解锁GUI,此函数在访问显示器之后或在使用关键内部数据结构之后由GUI调用。在使用实时操作系统时,通常必须减量计数资源信号量。
7. 用于返回当前任务的唯一ID。只要返回值对于使用emWin API的每个任务/线程是唯一的,且只要该值对于每个特定线程始终相同,则返回值是多少并不重要。
8. 用于等待事件。
9. 用于释放事件。
10. 这个里面的几个函数用实现按键接口函数。通过创建信号量来实现同步功能。
11. 这三个函数用调试目的。
29.2.2 触摸任务
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskGUIRefresh
- * 功能说明: emWin刷新函数
- * 形 参:p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级:OS_CFG_PRIO_MAX - 3u
- *********************************************************************************************************
- */
-
- extern __IO uint8_t s_ucRA8875BusyNow;
- static void AppTaskGUIRefresh(void *p_arg)
- {
- (void)p_arg; /* 避免编译器告警 */
- while (1)
- {
- /* RA8875 触摸*/
- if (g_ChipID == IC_8875)
- {
- /* 资源共享标志 */
- if(s_ucRA8875BusyNow == 0)
- {
- GUI_TOUCH_Exec();
- }
- }
- /* XPT2046 */
- else
- {
- GUI_TOUCH_Exec();
- }
-
- BSP_OS_TimeDlyMs(20);
- }
- }
29.2.3 STemWin任务
- /*
- *********************************************************************************************************
- * 函 数 名: MainTask
- * 功能说明: GUI主函数
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void MainTask(void)
- {
- GUI_Init();
- GUI_SetTextMode(GUI_TM_TRANS);
- for (i = 0; i < 3; i++)
- {
- GUI_SetColor(GUI_BLUE);
- GUI_FillRectEx(&Rect);
- GUI_SetColor(GUI_WHITE);
- GUI_DispStringInRectWrap(acText, &Rect, GUI_TA_LEFT, aWm[i]);
- Rect.x0 += 60;
- Rect.x1 += 60;
- }
- while (1)
- {
- GUI_Delay(10);
- }
- }
这个例子整体的显示效果如下:
29.3 多任务系统:多个任务调用emWin
这个例子也是分为三部分,内核接口和触摸任务跟上面讲的一样,这里主要说一下创建的三个GUI任务。
29.3.1 uCOS创建三个STemWin任务
这三个任务在main.c函数里面创建,三个任务的优先级看相应注释
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskGUI
- * 功能说明: GUI任务0
- * 形 参:p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级:OS_CFG_PRIO_MAX - 6u
- *********************************************************************************************************
- */
- extern void MainTask(void);
- static void AppTask0GUI(void *p_arg)
- {
- (void)p_arg; /* 避免编译器告警 */
- while (1)
- {
- MainTask();
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskGUI
- * 功能说明: GUI任务1
- * 形 参:p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级:OS_CFG_PRIO_MAX - 5u
- *********************************************************************************************************
- */
- extern void Task_1(void);
- static void AppTask1GUI(void *p_arg)
- {
- (void)p_arg; /* 避免编译器告警 */
- while (1)
- {
- Task_1();
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskGUI
- * 功能说明: GUI任务2
- * 形 参:p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级:OS_CFG_PRIO_MAX - 4u
- *********************************************************************************************************
- */
- extern void Task_2(void);
- static void AppTask2GUI(void *p_arg)
- {
- (void)p_arg; /* 避免编译器告警 */
- while (1)
- {
- Task_2();
- }
- }
29.3.2 STemWin任务
建立的三个任务所在文件夹:
MainTask文件中的任务:
- #include "includes.h"
- #include "MainTask.h"
-
-
- /*
- *********************************************************************************************************
- * 函 数 名: _cbCallbackT0
- * 功能说明: 任务0的回调函数
- * 形 参:pMsg 消息指针
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void _cbCallbackT0(WM_MESSAGE * pMsg)
- {
- switch (pMsg->MsgId)
- {
- case WM_PAINT:
- /* Handle the paint message */
- GUI_SetBkColor(GUI_RED);
- GUI_SetColor(GUI_BLACK);
- GUI_SetFont(&GUI_FontComic24B_ASCII);
- GUI_Clear();
- GUI_DispStringAt("Task0 Moving", 0, 0);
- break;
- default:
- WM_DefaultProc(pMsg);
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: _cbBackgroundWin
- * 功能说明: 背景窗口的回调函数
- * 形 参:pMsg 消息指针
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void _cbBackgroundWin(WM_MESSAGE* pMsg)
- {
- switch (pMsg->MsgId)
- {
- case WM_PAINT:
- /* Handle only the paint message */
- GUI_SetBkColor(0x00CC00);
- GUI_Clear();
- GUI_SetFont(&GUI_Font24_ASCII);
- GUI_DispStringHCenterAt("STemWin - multitasking demo\n", 159, 5);
- GUI_SetFont(&GUI_Font13_1);
- GUI_DispStringAt("Scrolling text and moving windows without flickering", 5, 35);
- default:
- WM_DefaultProc(pMsg);
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: Task_0
- * 功能说明: GUI任务0
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void Task_0(void)
- {
- /* Create frame window */
- FRAMEWIN_Handle hFrameWin = FRAMEWIN_Create("Task 0", NULL, WM_CF_SHOW | WM_CF_STAYONTOP, 0, 230, 200,
- 40);
- /* Create child window */
- WM_HWIN hChildWin = WM_CreateWindowAsChild(0, 0, 0, 0, WM_GetClientWindow(hFrameWin),
- WM_CF_SHOW | WM_CF_MEMDEV, _cbCallbackT0, 0);
- FRAMEWIN_SetActive(hFrameWin, 0);
- /* Make sure the right window is active... */
- WM_SelectWindow(hChildWin);
- /* ...and the right font is selected */
- GUI_SetFont(&GUI_FontComic24B_ASCII);
- while(1)
- {
- int i;
- int nx = 80;
- /* Move window continously */
- for (i = 0; i < nx; i++)
- {
- WM_MoveWindow(hFrameWin, 2, 0);
- GUI_Delay(50);
- }
- for (i = 0; i < nx; i++)
- {
- WM_MoveWindow(hFrameWin, -2, 0);
- GUI_Delay(50);
- }
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: MainTask
- * 功能说明: GUI任务0
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void MainTask(void)
- {
- GUI_Init();
- WM_SetCreateFlags(WM_CF_MEMDEV);
- WM_SetCallback(WM_HBKWIN, _cbBackgroundWin);
- while(1)
- {
- Task_0();
- }
- }
App_Task1中的内容:
- <font color="#000000">#include "includes.h"
- #include "MainTask.h"
-
-
- /*
- *********************************************************************************************************
- * 函 数 名: _cbCallbackT1
- * 功能说明: 任务1的回调函数
- * 形 参:pMsg 消息指针
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void _cbCallbackT1(WM_MESSAGE * pMsg)
- {
- WM_HWIN hWin = (FRAMEWIN_Handle)(pMsg->hWin);
- switch (pMsg->MsgId)
- {
- case WM_PAINT:
- /* Handle the paint message */
- GUI_SetBkColor(GUI_BLUE);
- GUI_SetColor(GUI_WHITE);
- GUI_SetFont(&GUI_FontComic24B_ASCII);
- GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
- GUI_Clear();
- GUI_DispStringHCenterAt("Task1 window...",
- WM_GetWindowSizeX(hWin) / 2,
- WM_GetWindowSizeY(hWin) / 2);
- break;
- default:
- WM_DefaultProc(pMsg);
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: Task_1
- * 功能说明: GUI任务0
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void Task_1(void)
- {
- /* Create frame window */
- FRAMEWIN_Handle hFrameWin = FRAMEWIN_Create("Task 1", NULL, WM_CF_SHOW | WM_CF_STAYONTOP,
- 20, 170, 200, 40);
- /* Create child window */
- WM_HWIN hChildWin = WM_CreateWindowAsChild(0, 0, 0, 0, WM_GetClientWindow(hFrameWin), WM_CF_SHOW |
- WM_CF_MEMDEV,_cbCallbackT1, 0);
- FRAMEWIN_SetActive(hFrameWin, 0);
- while(1)
- {
- int i;
- int nx = 80;
- int ny = 90;
- /* Move window continously */
- for (i = 0; i < ny; i++)
- {
- WM_MoveWindow(hFrameWin, 0, -2);
- GUI_Delay(50);
- }
- for (i = 0; i < nx; i++)
- {
- WM_MoveWindow(hFrameWin, 2, 0);
- GUI_Delay(50);
- }
- for (i = 0; i < ny; i++)
- {
- WM_MoveWindow(hFrameWin, 0, 2);
- GUI_Delay(50);
- }
- for (i = 0; i < nx; i++)
- {
- WM_MoveWindow(hFrameWin, -2, 0);
- GUI_Delay(50);
- }
- }
- }</font>
App_Task2中的内容:
- #include "includes.h"
- #include "MainTask.h"
-
- /*
- *********************************************************************************************************
- * 函 数 名: _cbCallbackT2
- * 功能说明: 任务2的回调函数
- * 形 参:pMsg 消息指针
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void _cbCallbackT2(WM_MESSAGE * pMsg)
- {
- switch (pMsg->MsgId)
- {
- case WM_PAINT:
- /* Handle the paint message */
- GUI_SetBkColor(GUI_YELLOW);
- GUI_SetColor(GUI_BLACK);
- GUI_SetFont(&GUI_FontComic24B_ASCII);
- GUI_Clear();
- GUI_DispStringAt("Task2 Moving", 0, 0);
- break;
- default:
- WM_DefaultProc(pMsg);
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: Task_2
- * 功能说明: GUI任务0
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void Task_2(void)
- {
- /* Create frame window */
- FRAMEWIN_Handle hFrameWin = FRAMEWIN_Create("Task 2", NULL, WM_CF_SHOW | WM_CF_STAYONTOP, 0, 190, 200, 40);
- /* Create child window */
- WM_HWIN hChildWin = WM_CreateWindowAsChild(0, 0, 0, 0, WM_GetClientWindow(hFrameWin),
- WM_CF_SHOW | WM_CF_MEMDEV, _cbCallbackT2, 0);
- FRAMEWIN_SetActive(hFrameWin, 0);
- /* Make sure the right window is active... */
- WM_SelectWindow(hChildWin);
- /* ...and the right font is selected */
- GUI_SetFont(&GUI_FontComic24B_ASCII);
- while(1)
- {
- int i;
- int nx = 80;
- /* Move window continously */
- for (i = 0; i < nx; i++)
- {
- WM_MoveWindow(hFrameWin, 2, 0);
- GUI_Delay(50);
- }
- for (i = 0; i < nx; i++)
- {
- WM_MoveWindow(hFrameWin, -2, 0);
- GUI_Delay(50);
- }
- }
- }
这个例子的整体显示效果如下:
29.4 总结
本期教程就跟大家讲这么多,希望通过创建的这三个DEMO让大家对STemWin创建裸机或者多任务系统有个整体认识,具体工程中用那种方式要根据实际的需求来决定。
主营: 贴片电容全系列.电阻.IC.钽电容.等电子元器件.QQ:2844406506 联系电话:13760223342