最新教程下载:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429
第15章 ThreadX GUIX定时器更新功能
本章节为大家讲解GUIX定时器更新功能。这个功能用的到地方很多,比如更新文本控件显示RTC时钟,采集数据的动态更新等场合都要用到。
15.1初学者重要提示
15.2 GUIX Studio设置窗口事件回调
15.3 GUIX定时器更新功能
15.4 实验例程设计框架
15.5实验例程
15.6 总结
15.1 初学者重要提示
- 务必看第11章学习GUIX Studio的使用方法和第12章学习GUIX Studio生成的代码移植到硬件平台的方法。
- 使用文本控件prompt做动态更新,要勾选GUIX Studio中的Private Text Copy,详解本章2.2.2小节。
- 本章节教程的3.3.4小节是重点,对定时器更新的使用方法进行了说明。
15.2 GUIX Studio设置窗口事件回调
GUIX Studio的设置方法与第11章一样,我们这里把控件的位置和大小做了调整,并为window窗口创建一个定时器。
新调整的界面效果如下:
15.2.1 窗口事件回调设置
下面我们为窗口控件设置一个Event Function,此功能是窗口的事件回调函数。在这个回调函数里面,大家可以处理各种事件。
这里为Event Function设置的回调函数名为_cbEventWindow0,然后就可以使用GUIX Studio生成新的代码。生成的代码移植到硬件平台的方法看第12章即可。
15.2.2 文本控件prompt动态更新
使用控件prompt做更新,一定要在GUIX Studio上勾选Private Text Copy,否则prompt的内容是无法更新的:
15.3 GUIX定时器更新功能
在GUIX Studio上设置好事件回调函数名后,剩下就是在程序里面实现定时器事件回调的处理,这里把实现方法为大家做个说明。
15.3.1 了解GUIX定时器相关宏定义
GUIX定时器相关的几个宏定义如下:
#ifndef GX_TICKS_SECOND #define GX_TICKS_SECOND 20 #endif /* Set default ThreadX timer tick frequency 100Hz (10ms timer). */ #ifndef TX_TIMER_TICKS_PER_SECOND #define TX_TIMER_TICKS_PER_SECOND ((ULONG)100) #endif /* Default 20ms GUIX system timer. */ #ifndef GX_SYSTEM_TIMER_MS #define GX_SYSTEM_TIMER_MS 20 #endif /* Derive GX_SYSTEM_TIMER_TICKS based on GX_SYSTEM_TIMER_MS value. */ #ifndef GX_SYSTEM_TIMER_TICKS #define GX_SYSTEM_TIMER_TICKS ((GX_SYSTEM_TIMER_MS * TX_TIMER_TICKS_PER_SECOND) / 1000) #endif
以本教程配置的例子为例,仅用到定义GX_SYSTEM_TIMER_TICKS,其它基本都没用到。这个宏定义被ThreadX内核定时器组件的创建函数所调用,以此来供GUIX的定时器组件使用:
tx_timer_create(&_gx_system_timer, "guix timer", _gx_system_timer_expiration, 0, GX_SYSTEM_TIMER_TICKS, GX_SYSTEM_TIMER_TICKS, TX_NO_ACTIVATE);
一般我们都设置ThreadX内核系统时钟节拍为1000Hz,即1ms。因此这里设置GX_SYSTEM_TIMER_TICKS表示GUIX定时器的周期单位是GX_SYSTEM_TIMER_TICKS毫秒。比如GX_SYSTEM_TIMER_TICKS定义为2,表示GUIX的定时器单位是2ms。
15.3.2 了解GUIX定时器API
我们主要用到函数gx_system_timer_start,用于启动定时器。函数原型如下:
#define gx_system_timer_start(a, b, c, d) _gx_system_timer_start((GX_WIDGET *)a, b, c, d) UINT _gx_system_timer_start(GX_WIDGET *owner, UINT timer_id, UINT initial_ticks, UINT reschedule_ticks)
函数形参含义如下:
- owner
控件指针变量,指向控件控制块,表示为那个控件创建定时器。
- timer_id
定时器ID。
- initial_ticks
初始溢出时间,单位由宏定义GX_SYSTEM_TIMER_TICKS决定。
参数范围1到0xFFFFFFFF。
- reschedule_ticks
周期性执行时间,单位由宏定义GX_SYSTEM_TIMER_TICKS决定。
参数范围1到0xFFFFFFFF。
注意事项:
- 宏定义GX_MAX_ACTIVE_TIMERS决定可以创建的最多定时器个数,默认值是32。
- 此函数最后两个时间参数不可以设置为0。
15.3.3 窗口(控件)里事件回调的定时器实现框架
GUIX的定时器调用是在窗口(控件)的事件回调函数里面调用的。以窗口为例,窗口的Event Function事件回调函数实现框架如下:
UINT _cbEventWindow(GX_WINDOW *widget, GX_EVENT *event_ptr) { switch (event_ptr->gx_event_type) { /* 控件显示事件 */ case GX_EVENT_SHOW: break; /* 定时器时间溢出事件*/ case GX_EVENT_TIMER: break; default: return gx_window_event_process(widget, event_ptr); } return 0; }
事件回调函数还有很多其它事件供用户使用,这里仅列出了定时器用到的两个。这个框架基本是固定的,大家直接调用即可,下面举一个实例来说明定时器的使用。
15.3.4 窗口里面定时器更新功能实例(重要)
实例代码如下,本章教程配套例子也是用的这个代码:
/* ********************************************************************************************************* * 函 数 名: _cbEventWindow * 功能说明: 窗口window的事件回调函数 * 形 参: widget 窗口句柄 * event_ptr 事件指针 * 返 回 值: 返回0表示成功 ********************************************************************************************************* */ UINT _cbEventWindow(GX_WINDOW *widget, GX_EVENT *event_ptr) { static uint32_t count = 0; char buf[20] = {0}; switch (event_ptr->gx_event_type) { /* 控件显示事件 */ case GX_EVENT_SHOW: /* 启动一个GUIX定时器 */ gx_system_timer_start((GX_WIDGET *)widget, GUI_ID_Timer0, 1, 50); /* 默认事件处理 */ gx_window_event_process(widget, event_ptr); break; /* 定时器时间溢出事件*/ case GX_EVENT_TIMER: if (event_ptr->gx_event_payload.gx_event_timer_id == GUI_ID_Timer0) { sprintf(buf, "%d", count++); gx_prompt_text_set((GX_PROMPT *)&(window.window_prompt), buf); } break; default: return gx_window_event_process(widget, event_ptr); } return 0; }
- GX_EVENT_SHOW
窗口(控件)显示事件。当窗口(控件)显示时,会产生此消息,既可以附加到一个可见窗口(控件),也可以通过函数gx_widget_show()。窗口(控件)绘制前会产生此消息。
- gx_system_timer_start
启动定时器。
-
- 第1个参数是事件回调函数传递进来的形参。
- 第2个参数是定时器ID,通过此参数可以区分多个定时器。
- 第3个参数是初始溢出时间,默认本教程配套例子设置的时间单位是2ms。这里配置为1,表示2ms后周期性执行。
- 第4个参数是周期执行时间,这里配置为50,表示定时器周期是100ms。特别注意参数这个参数设置为1-5延迟时间都是10ms左右,设置到6以上就正常了。有待后续研究原因。
- gx_window_event_process
用于窗口(控件)的默认事件处理。
- GX_EVENT_TIMER
定时器周期性溢出事件
- gx_prompt_text_set
设置文本控件prompt的内容。
针对这个实例,推荐大家设置不同的参数看效果,熟练掌握这些函数的用法,这样用起GUIX也得心应手。
15.4 实验例程设计框架
本章例程的重点是GUIX定时器更新的实现,任务中专门为窗口设置了一个Event Function事件回调函数。
15.5 实验例程
(注,如果是电阻屏,需要做触摸校准,校准方法看本教程附件章节A)
配套例子:
本章节配套了如下两个例子供大家移植参考:
- V7-2015_GUIX Timer Update
GUIX Studio生成的代码在硬件平台实际运行的工程,含有GCC,IAR,MDK AC5和AC6四个版本工程。
- V7-2016_GUIX Studio Timer Update
GUIX Studio工程模板,设计界面后,生成的文件可直接添加到MDK,IAR和GCC软件平台使用。
实验目的:
- 本章主要学习GUIX的定时器更新功能。
实验内容:
- 共创建了如下几个任务,通过按下按键K1可以通过串口打印任务堆栈使用情况
App Task Start任务 :启动任务,这里用作BSP驱动包处理。
App Task MspPro任务 :消息处理,这里用作LED闪烁。
App Task UserIF任务 :按键消息处理。
App Task GUI任务 :GUI应用任务。
App Task STAT任务 :统计任务。
App Task IDLE任务 :空闲任务。
GUIX System Thread :GUI系统任务。
System Timer Thread任务:系统定时器任务。
实验效果:
GUIX Studio的界面设计如下:
串口打印任务执行情况:
IAR,MDK AC5和AC6工程可以串口打印任务执行情况:按开发板的按键K1可以打印,波特率 115200,数据位 8,奇偶校验位无,停止位 1:
Embedded Studio(GCC)平台的串口打印是通过其调试组件SEGGER RTT做的串口打印,速度也非常快,打印效果如下:
展示里面有乱码是因为Embedded Studio不支持中文。
15.6 总结
本章节主要为大家讲解了GUIX定时器更新功能,推荐大家设置不同的参数看效果,熟练掌握这些函数的用法。