• 【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中的显示方法,大家也可以尝试其它方式实现时钟表盘设计。

     

  • 相关阅读:
    leetcode 48. Rotate Image
    leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点) 、26/80. Remove Duplicates from Sorted ArrayI、II
    leetcode 263. Ugly Number 、264. Ugly Number II 、313. Super Ugly Number 、204. Count Primes
    leetcode 58. Length of Last Word
    安卓操作的一些问题解决
    leetcode 378. Kth Smallest Element in a Sorted Matrix
    android studio Gradle Build速度加快方法
    禁用gridview,listview回弹或下拉悬停
    Android Studio找不到FragmentActivity类
    安卓获取ListView、GridView等滚动的距离(高度)
  • 原文地址:https://www.cnblogs.com/armfly/p/16118681.html
Copyright © 2020-2023  润新知