1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
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(); } } |
|
|
|
|
|
29.1.3 主程序
在文件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 #include #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(); } } |
|
|
|
|
|
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 demon", 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中的内容:
复制代码 #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); } } } |
|
|
|
|
|
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创建裸机或者多任务系统有个整体认识,具体工程中用那种方式要根据实际的需求来决定。 评分 收藏 新鲜事 |
|
|
|
|
|
205 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1253 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
848 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
853 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
1073 浏览 2 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12009 浏览 31 评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 13:10 , Processed in 0.850273 second(s), Total 102, Slave 83 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号