【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 初學者重要提示
- 務必看第16章區域性重新整理的實現。
- 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設計時鐘錶盤
實驗目的:
- 本章主要學習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中的顯示方法,大家也可以嘗試其它方式實現時鐘錶盤設計。