1. 程式人生 > 其它 >【STM32F429】第27章 ThreadX GUIX炫酷實用的時鐘錶盤設計,結合硬體RTC實時時鐘

【STM32F429】第27章 ThreadX GUIX炫酷實用的時鐘錶盤設計,結合硬體RTC實時時鐘

最新教程下載:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429

第27章       ThreadX GUIX炫酷實用的時鐘錶盤設計,結合硬體RTC實時時鐘

本章節為大家講解漂亮實用的時鐘錶盤設計,並且結合STM32的硬體RTC實時時鐘。

27.1初學者重要提示

27.2 第1步,GUIX Studio建立空白視窗

27.3 第2步,GUIX Studio設定視窗回撥

27.4 第3步,新增圖片

27.5 第5步,視窗回撥函式裡面設定區域性Dirty

27.6 第6步,視窗繪製回撥裡面繪製時鐘錶盤

27.7 實驗例程

27.8 總結

 

 

27.1 初學者重要提示

  1.   務必看第16章區域性重新整理的實現。
  2.   GUIX實現時鐘錶盤的關鍵是實時圖示旋轉,即函式gx_canvas_pixelmap_draw的實現。

27.2 第1步,GUIX Studio建立空白視窗

GUIX Studio的設定方法與第11章一樣。建立的介面效果如下:

 

27.3 第2步,GUIX Studio設定視窗回撥

27.3.1        視窗事件回撥設定

下面我們為視窗控制元件設定一個Event Function,此功能是視窗的事件回撥函式。在這個回撥函式裡面,大家可以處理各種事件。

這裡為Event Function設定的回撥函式名為_cbEventWindow0,然後就可以使用GUIX Studio生成新的程式碼。生成的程式碼移植到硬體平臺的方法看第12章即可。

27.3.2        視窗繪製回撥設定

下面我們為視窗設定一個Draw Function,此功能是視窗的繪製回撥函式。在這個回撥函式裡面,大家可以實現各種2D繪製。

這裡為Draw Function設定的回撥函式名為_cbWindow0,然後就可以使用GUIX Studio生成新的程式碼。

27.4 第3步,新增圖片

將時鐘錶盤背景圖片,時針,分針和秒針都新增進來:

 時鐘圖片都放在了clock資料夾中(本章教程配套例子的檔案裡面)

四個新增的圖片都要如下方式逐一設定:

這個compress output對鉤一定要去掉,否則無法正常旋轉。

通過前面這三步就完了GUIX Studio的設定工作,剩下就是實際程式的配置。

27.5 第5步,視窗回撥函式裡面設定區域性Dirty

通過設定視窗區域性Dirty可以觸發重繪:

/* 影象繪製區 */
GX_RECTANGLE WinPartialDraw =  {0, 0, 0, 0};

/*
*********************************************************************************************************
*    函 數 名: _cbEventWindow
*    功能說明: 視窗window的事件回撥函式
*    形    參: widget     視窗控制代碼 
*             event_ptr  事件指標
*    返 回 值: 返回0表示成功
*********************************************************************************************************
*/
UINT _cbEventWindow(GX_WINDOW *widget, GX_EVENT *event_ptr)
{

    switch (event_ptr->gx_event_type)
    {
      /* 控制元件顯示事件 */
        case GX_EVENT_SHOW:
        
            /* 啟動一個GUIX定時器 */
            gx_system_timer_start((GX_WIDGET *)widget, GUI_ID_Timer0, 1, 1000/6);

            /* 預設事件處理 */
            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)
            {
                /* 設定視窗dirty,這樣會觸發視窗更新 */
                gx_system_dirty_partial_add(widget, &WinPartialDraw);
            }
            break;

        default:
            return gx_window_event_process(widget, event_ptr);
    }

    return 0;
}

視窗區域性更新也比較容易實現,呼叫函式gx_system_dirty_partial_add來標記視窗為dirty,這樣就會觸發GUIX執行繪製回撥函式。

#define gx_system_dirty_partial_add(a, b)   _gxe_system_dirty_partial_add((GX_WIDGET *)a, b)
UINT  _gxe_system_dirty_partial_add(GX_WIDGET *widget, GX_RECTANGLE *dirty_area)

與全域性更新不同的是區域性更新可以設定想更新的區域,這樣可以有效降低CPU和DMA2D的利用率。

  •   第1個引數是大家要更新的視窗控制代碼。
  •   第2個引數是要更新的區域。更新區域是GX_RECTANGLE型別結構體,此結構體定義了矩形區域。我們這裡沒有設定初始值,是在函式MainTask裡面做了配置:
WinPartialDraw.gx_rectangle_right = DISPLAY_1_THEME_1_CLOCK_CLASSIC_BACKGROUND_pixelmap.gx_pixelmap_width;
WinPartialDraw.gx_rectangle_bottom = DISPLAY_1_THEME_1_CLOCK_CLASSIC_BACKGROUND_pixelmap.gx_pixelmap_height;

27.6 第6步,視窗繪製回撥裡面繪製時鐘錶盤

實現程式碼如下:

/*
*********************************************************************************************************
*    函 數 名: _cbWindow0
*    功能說明: 視窗window的繪製回撥函式
*    形    參: widget     視窗控制代碼 
*    返 回 值: 無
*********************************************************************************************************
*/
VOID _cbWindow0(GX_WINDOW *widget)
{
    int      t0;   /* 用於三個指標的計數 */
    int      t1;
    int      t2;
    
    GX_RECTANGLE drawto;  
    GX_CANVAS *mycanvas; 
    
    
    RTC_ReadClock();
        
    /* 第一個指標計數,用於旋轉秒針 */
    t0 = g_tRTC.Sec * 6;

    /* 第二個指標計數,用於旋轉分針 */
    t1 = g_tRTC.Min * 6;

    /* 第三個指標計數,用於旋轉時針 */
    t2 = g_tRTC.Hour * 30;

    /* 預設的視窗繪製回撥函式,即預設介面效果繪製 */
    gx_window_draw(widget);

    /* 定義一個矩形框,後續的2D繪製函式都是在這個矩形範圍內繪製的 */
    gx_utility_rectangle_define(&drawto,
                                WinPartialDraw.gx_rectangle_left, 
                                WinPartialDraw.gx_rectangle_top,
                                WinPartialDraw.gx_rectangle_right, 
                                WinPartialDraw.gx_rectangle_bottom);
 
    /* 返回視窗對應的canvas畫布 */
    gx_widget_canvas_get(widget, &mycanvas);
    
    
    /* 
      在指定的畫布上啟動繪圖。此功能在內部被延遲繪圖演算法呼叫,GUIX在需要畫布時自動執行更新。 
      但是允許應用程式繞過延期繪圖演算法並立即執行。
      首先呼叫gx_canvas_drawing_inititate在畫布上繪畫。
      然後呼叫所需的繪圖函式,然後呼叫gx_canvas_drawing_complete即可。
    */
    gx_canvas_drawing_initiate(mycanvas, widget, &drawto);
    
    /* 錶盤背景繪製 */
    gx_canvas_pixelmap_draw(WinPartialDraw.gx_rectangle_left,  
                            WinPartialDraw.gx_rectangle_top, 
                            (GX_PIXELMAP *)&DISPLAY_1_THEME_1_CLOCK_CLASSIC_BACKGROUND_pixelmap);
       
    /* 繪製時針 */       
    gx_canvas_pixelmap_rotate(WinPartialDraw.gx_rectangle_left, 
                            WinPartialDraw.gx_rectangle_top,
                            (GX_PIXELMAP *)&DISPLAY_1_THEME_1_CLOCK_STANDARD_HOUR_HAND_pixelmap, 
                            t2,
                            DISPLAY_1_THEME_1_CLOCK_STANDARD_HOUR_HAND_pixelmap.gx_pixelmap_width/2, 
                            DISPLAY_1_THEME_1_CLOCK_STANDARD_HOUR_HAND_pixelmap.gx_pixelmap_height/2); 
                            
    /* 繪製分針 */                    
    gx_canvas_pixelmap_rotate(WinPartialDraw.gx_rectangle_left, 
                            WinPartialDraw.gx_rectangle_top,
                            (GX_PIXELMAP *)&DISPLAY_1_THEME_1_CLOCK_STANDARD_MINUTE_HAND_pixelmap, 
                            t1,
                            DISPLAY_1_THEME_1_CLOCK_STANDARD_MINUTE_HAND_pixelmap.gx_pixelmap_width/2, 
                            DISPLAY_1_THEME_1_CLOCK_STANDARD_MINUTE_HAND_pixelmap.gx_pixelmap_height/2);  
     /* 繪製秒針 */                          
    gx_canvas_pixelmap_rotate(
                            WinPartialDraw.gx_rectangle_left, 
                            WinPartialDraw.gx_rectangle_top,
                            (GX_PIXELMAP *)&DISPLAY_1_THEME_1_CLOCK_STANDARD_SECOND_HAND_pixelmap, 
                            t0,
                            DISPLAY_1_THEME_1_CLOCK_STANDARD_SECOND_HAND_pixelmap.gx_pixelmap_width/2, 
                            DISPLAY_1_THEME_1_CLOCK_STANDARD_SECOND_HAND_pixelmap.gx_pixelmap_height/2);  

    /* 用於強制立即繪製,注意,務必和gx_canvas_drawing_initiate成對呼叫 */
    gx_canvas_drawing_complete(mycanvas, GX_TRUE);
    
}
  • 這段程式碼的關鍵是函式gx_canvas_pixelmap_draw和gx_canvas_pixelmap_rotate,函式gx_canvas_pixelmap_draw用於繪製背景,而函式gx_canvas_pixelmap_rotate用於繪製旋轉的時分秒指標。

27.7 實驗例程

(注,如果是電阻屏,需要做觸控校準,校準方法看本教程附件章節A)

配套例子:

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

V6-2037_GUIX炫酷時鐘錶盤設計,結合硬體RTC

V6-2038_GUIX Studio設計時鐘錶盤

實驗目的:

  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任務:系統定時器任務。

實驗效果:

串列埠列印任務執行情況:

IAR,MDK AC5和AC6工程可以串列埠列印任務執行情況:按開發板的按鍵K1可以列印,波特率 115200,資料位 8,奇偶校驗位無,停止位 1:

 

27.8 總結

本章節主要為大家講解了時鐘錶盤在GUIX中的顯示方法,大家也可以嘗試其它方式實現時鐘錶盤設計。