1. 程式人生 > 實用技巧 >【STM32F429】第15章 ThreadX GUIX定時器更新功能

【STM32F429】第15章 ThreadX GUIX定時器更新功能

最新教程下載: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定時器相關的幾個巨集定義如下:

#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)

配套例子:

本章節配套了如下兩個例子供大家移植參考:

  • V6-2015_GUIX Timer Update

GUIX Studio生成的程式碼在硬體平臺實際執行的工程,含有GCC,IAR,MDK AC5和AC6四個版本工程。

  • V6-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定時器更新功能,推薦大家設定不同的引數看效果,熟練掌握這些函式的用法。