第30章 ThreadX GUIX炫酷實用的時鐘表盤設計,結合硬體RTC實時時鐘
本章節為大家講解漂亮實用的時鐘表盤設計,并且結合STM32的硬體RTC實時時鐘。
30.1初學者重要提示
30.2 第1步,GUIX Studio建立空白視窗
30.3 第2步,GUIX Studio設定視窗回調
30.4 第3步,添加圖檔
30.5 第5步,視窗回調函數裡面設定局部Dirty
30.6 第6步,視窗繪制回調裡面繪制時鐘表盤
30.7 實驗例程
30.8 總結
30.1 初學者重要提示
1、 務必看第16章局部重新整理的實作。
2、 GUIX實作時鐘表盤的關鍵是實時圖示旋轉,即函數gx_canvas_pixelmap_draw的實作。
30.2 第1步,GUIX Studio建立空白視窗
GUIX Studio的設定方法與第11章一樣。建立的界面效果如下:

30.3 第2步,GUIX Studio設定視窗回調
30.3.1 視窗事件回調設定
下面我們為視窗控件設定一個Event Function,此功能是視窗的事件回調函數。在這個回調函數裡面,大家可以處理各種事件。
這裡為Event Function設定的回調函數名為_cbEventWindow0,然後就可以使用GUIX Studio生成新的代碼。生成的代碼移植到硬體平台的方法看第12章即可。
30.3.2 視窗繪制回調設定
下面我們為視窗設定一個Draw Function,此功能是視窗的繪制回調函數。在這個回調函數裡面,大家可以實作各種2D繪制。
這裡為Draw Function設定的回調函數名為_cbWindow0,然後就可以使用GUIX Studio生成新的代碼。
30.4 第3步,添加圖檔
将時鐘表盤背景圖檔,時針,分針和秒針都添加進來:
時鐘圖檔都放在了clock檔案夾中(本章教程配套例子的檔案裡面)
四個添加的圖檔都要如下方式逐一設定:
這個compress output對鈎一定要去掉,否則無法正常旋轉。
通過前面這三步就完了GUIX Studio的設定工作,剩下就是實際程式的配置。
30.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、第1個參數是大家要更新的視窗句柄。
2、第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;
30.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用于繪制旋轉的時分秒指針。
30.7 實驗例程
(注,如果是電阻屏,需要做觸摸校準,校準方法看本教程附件章節A)
配套例子:
本章節配套了如下兩個例子供大家移植參考:
V7-2045_GUIX炫酷時鐘表盤設計,結合硬體RTC
V7-2046_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:
30.8 總結
本章節主要為大家講解了時鐘表盤在GUIX中的顯示方法,大家也可以嘗試其它方式實作時鐘表盤設計。