【STM32H7】第15章 ThreadX GUIX定时器更新功能

2020-12-29 11:39:14 浏览数 (1)

最新教程下载: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 初学者重要提示

  1. 务必看第11章学习GUIX Studio的使用方法和第12章学习GUIX Studio生成的代码移植到硬件平台的方法。
  2. 使用文本控件prompt做动态更新,要勾选GUIX Studio中的Private Text Copy,详解本章2.2.2小节。
  3. 本章节教程的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定时器相关的几个宏定义如下:

代码语言:javascript复制
#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的定时器组件使用:

代码语言:javascript复制
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,用于启动定时器。函数原型如下:

代码语言:javascript复制
#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事件回调函数实现框架如下:

代码语言:javascript复制
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 窗口里面定时器更新功能实例(重要)

实例代码如下,本章教程配套例子也是用的这个代码:

代码语言:javascript复制
/*
*********************************************************************************************************
*    函 数 名: _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软件平台使用。

实验目的:

  1. 本章主要学习GUIX的定时器更新功能。

实验内容:

  1. 共创建了如下几个任务,通过按下按键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定时器更新功能,推荐大家设置不同的参数看效果,熟练掌握这些函数的用法。

0 人点赞