【第3版emWin教程】第45章 emWin6.x窗口管理器之定时器使用
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz!http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429
第45章 emWin6.x窗口管理器之定时器使用
本期教程为大家讲解窗口管理器之定时器使用方法,这个定时器使用起来比较简单,而且很实用,以后的项目工程中很多时候要用到,不过使用时有些小问题要特别注意,如果不注意的话,定时器将无法正确启动。
目录
45.1 初学者重要提示
45.2 定时器功能介绍
45.3 桌面窗口上使用定时器实例
45.4 对话框上使用定时器实例
45.5 实验例程说明(RTOS)
45.6 实验例程说明(裸机)
45.7 总结
45.1 初学者重要提示
1、 特别注意定时器使用时的注意事项,在本章45.2小节详细讲解了,要不定时器无法正确启动。然后再结合本章教程给出的实例进行学习。
2、 窗口管理器这块的API函数应该是emWin手册所有章节中函数最多的,定时器的API函数也属于这部分。下图是中文版手册里面API函数位置:
下图是英文版手册里面API函数的位置:
45.2 定时器功能介绍
emWin中有四个定时器相关的API函数供用户调用。
这四个函数都是简单易用,不过使用时有些问题还是要注意下,要不无法正确启动,初学者也是经常在这几个点犯错误,导致配置了定时器,却没有效果。
- WM_HTIMER WM_CreateTimer(WM_HWIN hWin, int UserId, int Period, int Mode)
此函数用于创建定时器,注意,这个函数创建的定时器是单次的,也是说定时器时间到后定时器就不再工作了,如果还想继续使用,务必要在窗口回调函数的定时器消息WM_TIMER里面调用函数WM_RestartTimer重启此定时器。
第1个参数 hWin填写窗口的句柄,即给那个窗口创建定时器。这个参数比较关键,很多初学者经常在这个参数上犯错误。如果是给对话框创建定时器,且对话框的主体是框架窗口FrameWin或者直接给框架窗口FrameWin创建定时器,此参数必须要使用函数WM_GetClientWindow获得框架窗口的客户区,这一点非常重要。如果对话框的主体是Windows或者直接给Windows窗口创建定时器,无需使用函数WM_GetClientWindow了,直接填句柄就可以了。
第2个参数UserId填写此定时器的ID,设置ID的目的是方便同一个窗口创建了多个定时器的话,可以用来区分是哪个定时器。
第3个参数Period是定时器周期,确切的说是溢出时间更贴切,因为此定时器不是自动重启的,仅执行一次,时间到后会给定时器所在窗口的回调函数发送WM_TIMER消息,如果要重新启动需要在此消息里面调用函数WM_RestartTimer重新启动。
第4个参数暂时保留,未被使用。
- void WM_DeleteTimer(WM_HTIMER hTimer)
此函数用于定时器删除,参数是定时器句柄(即调用函数WM_CreateTimer的返回值)。
- int WM_GetTimerId(WM_HTIMER hTimer);
此函数用于获得定时器ID,参数是定时器句柄(即调用函数WM_CreateTimer的返回值)。
- void WM_RestartTimer(WM_HTIMER hTimer, int Period)
此函数用于重启定时器。
第1个参数是定时器句柄,即调用函数WM_CreateTimer的返回值。
第2个参数是重新配置定时器的溢出时间。
-----------------
讲解完这些,也许初学者还有些模糊,没有关系,且看下面举的几个例子,看完后基本就都理解了。
45.3 桌面窗口上使用定时器实例
这个Demo主要是实现每隔1000ms改变一次桌面窗口的颜色,源代码如下(可以将其直接的复制到开发板或者模拟器上面运行)。
#include "DIALOG.h"/*
*********************************************************************************************************
* 变量
*********************************************************************************************************
*/
GUI_COLOR _acColor[3] = {GUI_BLUE,GUI_RED,GUI_YELLOW}; //--------------(1)
static char ucBackColor;/*
*********************************************************************************************************
* 函 数 名: _cbBkWindow
* 功能说明: 桌面窗口回调函数
* 形 参: 无
* 返 回 值: 返回对话框句柄
*********************************************************************************************************
*/
static void _cbBkWindow(WM_MESSAGE * pMsg)
{WM_HWIN hWin = pMsg->hWin;switch (pMsg->MsgId) {/* 重绘消息 */case WM_PAINT: //--------------(2)ucBackColor++;if (ucBackColor == 3){ucBackColor = 0;}GUI_SetBkColor(_acColor[ucBackColor]);GUI_Clear();break;/* 定时器消息 */case WM_TIMER: //--------------(3)WM_InvalidateWindow(hWin);WM_RestartTimer(pMsg->Data.v, 1000);break;default:WM_DefaultProc(pMsg);}
}/*
*********************************************************************************************************
* 函 数 名: MainTask
* 功能说明: GUI主函数
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void MainTask(void)
{WM_HTIMER hTimer;/* 初始emWin */GUI_Init();/* 设置桌面窗口回调函数 */WM_SetCallback(WM_HBKWIN, _cbBkWindow); //--------------(4)/* 为桌面窗口创建定时器,定时器溢出时间1000ms */hTimer = WM_CreateTimer(WM_HBKWIN, 0, 1000, 0); //--------------(5)while (1){GUI_Delay(10);}
}
- 定义一个数组,里面有三种颜色,再定义一个变量,用于三种颜色的切换。
- 桌面窗口回调函数的重绘消息,每执行一次更新一次背景色。
- 定时器消息,这里要特别注意,如果想要定时器周期性执行,而不是只执行一次,必须得调用重启定时器函数WM_RestartTimer()。在这个消息里面将桌面窗口无效,从而会触发窗口管理器去执行WM_PAINT消息,这样就实现了定时修改桌面窗口背景色。
- 设置桌面窗口的回调函数。
- 创建定时器函数,溢出时间是1000ms。
这个Demo的实际显示效果如下:
45.4 对话框上使用定时器实例
这个Demo的主要功能是在对话框上面实现一个计数功能,每100ms更新一次,下面是源码(可以将其直接的复制到开发板或者模拟器上面运行)
#include "DIALOG.h"
#include "stdio.h"/*
*********************************************************************************************************
* 变量
*********************************************************************************************************
*/
static int Count = 0;/*
*********************************************************************************************************
* GUI_WIDGET_CREATE_INFO类型数组
*********************************************************************************************************
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {{ FRAMEWIN_CreateIndirect, "armfly", 0, 0, 0, 320,240,0,0},{ TEXT_CreateIndirect, "0000", GUI_ID_TEXT0, 30,30,300,48, 0,0}
};/*
*********************************************************************************************************
* 函 数 名: _cbCallback
* 功能说明: 对话框回调函数
* 形 参: pMsg 回调参数
* 返 回 值: 无
*********************************************************************************************************
*/
static void _cbCallback(WM_MESSAGE * pMsg)
{int NCode, Id;char buf[10];WM_HWIN hWin = pMsg->hWin;switch (pMsg->MsgId) {case WM_INIT_DIALOG:////初始化框架窗口//FRAMEWIN_SetFont(hWin,&GUI_Font24B_ASCII);FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);FRAMEWIN_SetTitleHeight(hWin,30);////初始化文本控件//TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0), &GUI_FontD36x48);break;/* 定时器消息 */case WM_TIMER: //--------------(1)Count++;sprintf(buf, "%04d", Count);TEXT_SetText(WM_GetDialogItem(hWin,GUI_ID_TEXT0), (const char *)buf);WM_RestartTimer(pMsg->Data.v, 100);break;case WM_KEY:switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) {case GUI_KEY_ESCAPE:GUI_EndDialog(hWin, 1);break;case GUI_KEY_ENTER:GUI_EndDialog(hWin, 0);break;}break;case WM_NOTIFY_PARENT:Id = WM_GetId(pMsg->hWinSrc); NCode = pMsg->Data.v; switch (Id) {case GUI_ID_OK:if(NCode==WM_NOTIFICATION_RELEASED)GUI_EndDialog(hWin, 0);break;case GUI_ID_CANCEL:if(NCode==WM_NOTIFICATION_RELEASED)GUI_EndDialog(hWin, 0);break;}break;default:WM_DefaultProc(pMsg);}
}/*
*********************************************************************************************************
* 函 数 名: MainTask
* 功能说明: GUI主函数
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void MainTask(void)
{WM_HWIN hDlg;WM_HTIMER hTimer;/* 初始emWin */GUI_Init();/* 窗口使能使用内存设备,防止闪烁 */WM_SetCreateFlags(WM_CF_MEMDEV); /* 创建一个对话框 */hDlg = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);/* 给对话框hDlg创建定时器,溢出时间是100ms */hTimer = WM_CreateTimer(WM_GetClientWindow(hDlg), 0, 100, 0); //--------------(2)while (1){GUI_Delay(10);}
}
- 定时器消息,在定时器消息中实现文件控件计数值的更新,每次计数值加1。
- 给对话框创建一个定时器,特别注意,这里需要获取对话框中客户区窗口的句柄才可以使用。
这个例子的实际显示效果如下:
45.5 实验例程说明(RTOS)
配套例子:
V7-558_emWin6.x实验_窗口管理器之定时器使用(RTOS)
实验目的:
- 本实验主要学习窗口管理器之定时器使用方法。
- emWin功能的实现在MainTask.c文件里面。
实验内容:
1、K1按键按下,串口或者RTT打印任务执行情况(串口波特率115200,数据位8,奇偶校验位无,停止位1)。
2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。
(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。
3、默认上电是通过串口打印信息,如果使用RTT打印信息:
MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可
#define Enable_RTTViewer 1
4、各个任务实现的功能如下:
App Task Start 任务 :启动任务,这里用作BSP驱动包处理。
App Task MspPro任务 :消息处理,这里用作LED闪烁。
App Task UserIF 任务 :按键消息处理。
App Task COM 任务 :暂未使用。
App Task GUI 任务 :GUI任务。
μCOS-III任务调试信息(按K1按键,串口打印):
RTT 打印信息方式:
程序设计:
任务栈大小分配:
μCOS-III任务栈大小在app_cfg.h文件中配置:
#define APP_CFG_TASK_START_STK_SIZE 512u
#define APP_CFG_TASK_MsgPro_STK_SIZE 2048u
#define APP_CFG_TASK_COM_STK_SIZE 512u
#define APP_CFG_TASK_USER_IF_STK_SIZE 512u
#define APP_CFG_TASK_GUI_STK_SIZE 2048u
任务栈大小的单位是4字节,那么每个任务的栈大小如下:
App Task Start 任务 :2048字节。
App Task MspPro任务 :8192字节。
App Task UserIF 任务 :2048字节。
App Task COM 任务 :2048字节。
App Task GUI 任务 :8192字节。
系统栈大小分配:
μCOS-III的系统栈大小在os_cfg_app.h文件中配置:
#define OS_CFG_ISR_STK_SIZE 512u
系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB
emWin动态内存配置:
GUIConf.c文件中的配置如下:
#define EX_SRAM 1/*1 used extern sram, 0 used internal sram */#if EX_SRAM
#define GUI_NUMBYTES (1024*1024*24)
#else
#define GUI_NUMBYTES (100*1024)
#endif
通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小24MB。
#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
emWin界面显示效果:
800*480分辨率界面效果。
45.6 实验例程说明(裸机)
配套例子:
V7-557_emWin6.x实验_窗口管理器之定时器使用(裸机)
实验目的:
- 本实验主要学习窗口管理器之定时器使用方法。
- emWin功能的实现在MainTask.c文件里面。
emWin界面显示效果:
800*480分辨率界面效果。
emWin动态内存配置:
GUIConf.c文件中的配置如下:
#define EX_SRAM 1/*1 used extern sram, 0 used internal sram */#if EX_SRAM
#define GUI_NUMBYTES (1024*1024*24)
#else
#define GUI_NUMBYTES (100*1024)
#endif
通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM 1 表示使用外部SDRAM作为emWin动态内存,大小24MB。
#define EX_SRAM 0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
45.7 总结
本章节就为大家讲解这么多,窗口定时器简单实用,望初学者务必掌握,以后用到的地方还是很多的。
【第3版emWin教程】第45章 emWin6.x窗口管理器之定时器使用相关推荐
- 【第3版emWin教程】第50章 emWin6.x的AppWizard使用控件经典回调方式
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第50章(2021-10-01) - uCOS & uCGUI &am ...
- 【第3版emWin教程】第42章 emWin6.x窗口管理器之回调消息类型
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI &am ...
- 【第3版emWin教程】第48章 emWin6.x对话框基础知识
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI &am ...
- 【第3版emWin教程】第49章 emWin6.x的AppWizard创建控件回调消息
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第50章(2021-10-01) - uCOS & uCGUI &am ...
- 2022版Maven教程 - 第六章 单一架构案例
2022版Maven教程 - 第六章 单一架构案例 一.创建工程,引入依赖 1.架构 ①架构的概念 ②单一架构 2.创建工程 3.引入依赖 ①搜索依赖信息的网站 [1]到哪儿找? [2]怎么选择? ② ...
- 【第3版emWin教程】第53章 emWin6.x的按钮Button控件
教程不断更新中:链接 第53章 emWin6.x的按钮Button控件 本章节为大家讲解emWin支持的按钮控件,按钮控件还是非常实用的,实际项目中用到的地方很多,控件的本质就是窗口,或者 ...
- 【第3版emWin教程】第55章 emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果
教程不断更新中:链接 第55章 emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果 本章节为大家讲解按钮控件自定义回调函数,通过其回调函数就可以实现各种按钮效果.这方面的 ...
- 【第3版emWin教程】第8章 emWin6.x的带OS方式移植(STM32H7之RGB接口)
教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429 第8章 emWin6.x的带OS方式移植(STM32H7之R ...
- 【第3版emWin教程】第34章 emWin6.x的AppWizard界面开发工具使用方法
教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429 第34章 emWin6.x的AppWizard界面开 ...
最新文章
- HTMLDOM中三种元素节点、属性节点、文本节点的测试案例
- PMP考前复习题 系列三
- Linux--内核Uevent事件机制 与 Input子系统【转】
- acid四大特性_深入理解MySQL的ACID四大特性原理
- Appointment在SPRO里的date profile配置
- MySQL(五) —— 子查询
- SPS2003升级到MOSS2007相关资料及问题总结
- JavaScript对象中的this属性
- 手机各种JS语法,随时更新
- mysql innodb 间隙锁_Mysql innodb 间隙锁
- 不光是查找值!二分搜索
- java 线程安全集合
- Rainmeter雨滴桌面秀教程
- 计算机外设解决方案,瑞昱在2007 IDF上展出多款计算机外设产品解决方案
- IntelliJ IDEA 2020 如何解决Commit: Local Changes Refresh提交Git代码卡住超级慢(已解决)
- pox控制器学习笔记
- SAP 未审批的采购订单(PO)提交到OA去审批,最后OA审批结果回写到SAP。
- 微信发朋友圈测试用例
- 【深度学习】Mask-RCNN 计算机视觉实例分割模型介绍 Mask分支
- matlab 函数 矩阵参数,MATLAB函数矩阵参数
热门文章
- JS 统计字符串中大小写字母个数
- C语言search函数的作用,C语言lsearch()函数:用于在给定的区域内从头到尾进行线性搜索...
- 学会了C语言/C++能做什么?我们一起来看看吧!
- 中亿物联网代理_北京电信物联网卡服务商,首选中亿物联网!【官方渠道】
- [BZOJ4784][UOJ290][ZJOI017]仙人掌-树形DP
- 《Web全栈工程师的自我修养》读后感
- 逆波兰式求值 —Java
- 伸缩式起重机的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 微信公众平台开发入门:[8]聊天机器人可开发
- mac +xcode 下WebDriverAgent环境配置