教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第30章,emWin更新至第57章(2022-04-04) - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz!

第57章       emWin6.x的炫酷时钟表盘设计,结合硬件RTC

本章节为大家讲解emWin中炫酷时钟,结合硬件RTC。

57.1 初学者重要提示

57.2 第1步,相关图标生成位图

57.3 第2步,开辟存储设备

57.4 第3步,初始化存储设备

57.5 第4步,创建时钟表盘窗口

57.6 第5步,最关键的窗口回调函数实现

57.7 实验例程说明(RTOS)

57.8 实验例程说明(裸机)

57.9 总结

57.1 初学者重要提示

1、 emWin实现时钟表盘的关键是实时图标旋转,即函数GUI_MEMDEV_RotateHQ的实现。

57.2 第1步,相关图标生成位图

位图的原始图片已经存到本章教程配套例子的Doc文件夹中,位图的生成方法详见本章教程的第15章,这里我们选择如下格式,时钟表盘,时针,分针和秒针都是同样的设置:

57.3 第2步,开辟存储设备

我们这里要开辟五个存储设备,大小都是250*250。特别注意开辟的存储设备格式要带alpha通道的8888颜色格式。

   /* 时钟表盘所需存储设备 */
hMemBK = GUI_MEMDEV_CreateFixed(0,0, bmclock_classic_background.XSize, bmclock_classic_background.YSize,GUI_MEMDEV_HASTRANS, GUI_MEMDEV_APILIST_32, GUI_COLOR_CONV_8888);/* 时钟秒针所需存储设备 */
hMemSec = GUI_MEMDEV_CreateFixed(0,0, bmclock_classic_background.XSize, bmclock_classic_background.YSize,GUI_MEMDEV_NOTRANS, GUI_MEMDEV_APILIST_32, GUI_COLOR_CONV_8888);/* 时钟分针所需存储设备 */
hMemMin = GUI_MEMDEV_CreateFixed(0, 0, bmclock_classic_background.XSize,
bmclock_classic_background.YSize,GUI_MEMDEV_NOTRANS, GUI_MEMDEV_APILIST_32, GUI_COLOR_CONV_8888);/* 时钟小时所需存储设备 */
hMemHour = GUI_MEMDEV_CreateFixed(0, 0, bmclock_classic_background.XSize,
bmclock_classic_background.YSize,
GUI_MEMDEV_NOTRANS, GUI_MEMDEV_APILIST_32, GUI_COLOR_CONV_8888);/* 时钟目的存储所需存储设备 */hMemDST =GUI_MEMDEV_Cr

57.4 第3步,初始化存储设备

我们这里要给存储设备初始化一个数值,方便我们后面旋转指针使用:

/* 将时钟表盘绘制到存储设备 */GUI_MEMDEV_Select(hMemBK);GUI_SetBkColor(GUI_TRANSPARENT);GUI_Clear();GUI_DrawBitmap(&bmclock_classic_background, 0, 0); GUI_MEMDEV_Select(0);/* 将秒针绘制到存储设备 */GUI_MEMDEV_Select(hMemSec);GUI_SetBkColor(GUI_TRANSPARENT);GUI_Clear();GUI_DrawBitmap(&bmclock_standard_second_hand, 0, 0); GUI_MEMDEV_Select(0);/* 将分针绘制到存储设备 */GUI_MEMDEV_Select(hMemMin);GUI_SetBkColor(GUI_TRANSPARENT);GUI_Clear();GUI_DrawBitmap(&bmclock_standard_minute_hand, 0, 0);              GUI_MEMDEV_Select(0);/* 将时针绘制到存储设备 */GUI_MEMDEV_Select(hMemHour);GUI_SetBkColor(GUI_TRANSPARENT);GUI_Clear();GUI_DrawBitmap(&bmclock_standard_hour_hand, 0, 0); GUI_MEMDEV_Select(0);
  • 特别注意,我们这里的绘制是有技巧的,由于我们是带alpha通道的透明图片,所以这里绘制到存储设备,需要调用函数GUI_SetBkColor(GUI_TRANSPARENT),GUI_Clear(),否则绘制的图片是带黑色背景的。

57.5 第4步,创建时钟表盘窗口

为例方便移植和管理,我们把时钟表盘创建到一个独立的窗口上:

    /* 创建一个窗口,用于绘制时钟 */WM_CreateWindowAsChild((xSize - bmclock_classic_background.XSize)/2 , (ySize - bmclock_classic_background.YSize)/2, bmclock_classic_background.XSize,bmclock_classic_background.YSize, WM_HBKWIN, WM_CF_SHOW, _cbClock, 0);

57.6 第5步,最关键的窗口回调函数实现

代码实现如下:

/*
*********************************************************************************************************
*   函 数 名: CAM_Stop
*   功能说明: 停止DMA和DCMI
*   形    参: 无
*   返 回 值: 无
*********************************************************************************************************
*/
#include "MainTask.h"
void CAM_Stop(void)
{HAL_DCMI_Stop(&hdcmi);
}void DMA1_Stream7_IRQHandler(void)
{HAL_DMA_IRQHandler(&hdma_dcmi);
}void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{/* 关闭摄像 */CAM_Stop();WM_SendMessageNoPara(hWinMainTask, MSG_CAMERA);g_tCam.CaptureOk = 1;     /* 表示DMA传输结束 */
}/*
*********************************************************************************************************
*   函 数 名: _cbDialog
*   功能说明: 对话框回调函数
*   形    参: pMsg  回调参数
*   返 回 值: 无
*********************************************************************************************************
*/
static void _cbDialog(WM_MESSAGE * pMsg)
{static  WM_HTIMER hTimerCAMERA;switch (pMsg->MsgId) {/* 接收到摄像头数据 */case MSG_CAMERA:hTimerCAMERA = WM_CreateTimer(pMsg->hWin, ID_TimerCAMERA, 2, 0); break;case WM_TIMER:/* 删除定时器 */WM_DeleteTimer(hTimerCAMERA);/* 选择操作窗口 */WM_SelectWindow(hWinMainTask);/* Cache Clean和无效化 */SCB_CleanInvalidateDCache();/* 绘制到多缓冲里面 */GUI_MULTIBUF_Begin();//g_tCam.CaptureOk = 0;GUI_MEMDEV_WriteAt(hMem, 0, 0);GUI_MULTIBUF_End();WM_SelectWindow(WM_HBKWIN);/* 开始下次绘制 */CAM_Start1(uiDispMemAddr);   break;default:WM_DefaultProc(pMsg);break;}
}/*
*********************************************************************************************************
*   函 数 名: _cbClock
*   功能说明: 时钟回调函数
*   形    参: pMsg 窗口回调消息
*   返 回 值: 无
*********************************************************************************************************
*/
static void _cbClock(WM_MESSAGE * pMsg) {GUI_MEMDEV_Handle ret;int      t0;   /* 用于三个指针的计数 */int      t1;int      t2;switch (pMsg->MsgId) {case WM_CREATE:/* 创建定时器 */WM_CreateTimer(pMsg->hWin, /* 接受信息的窗口的句柄 */0,          /* 用户定义的Id。如果不对同一窗口使用多个定时器,此值可以设置为零。 */10,        /* 周期,此周期过后指定窗口应收到消息*/0);       /* 留待将来使用,应为0 */ break;/* 定时1秒更新一次时间 */case WM_TIMER:WM_RestartTimer(pMsg->Data.v, 1000);RTC_ReadClock();/* 第一个指针计数,用于旋转秒针 */t0 = 360 -  g_tRTC.Sec * 6;/* 第二个指针计数,用于旋转分针 */t1 = 360 - g_tRTC.Min * 6;/* 第三个指针计数,用于旋转时针 */t2 = 360 -   g_tRTC.Hour * 30;/* 将相关内容绘制到存储设备hMemDST里面 */ret = GUI_MEMDEV_Select(hMemDST);GUI_SetBkColor(GUI_RED);GUI_Clear();/* 绘制时钟表盘 */GUI_MEMDEV_WriteAt(hMemBK,0, 0);/* 绘制时针 */GUI_MEMDEV_RotateHQ(hMemHour, hMemDST, 0, 0, t2 * 1000, 1000);/* 绘制分针 */GUI_MEMDEV_RotateHQ(hMemMin, hMemDST, 0, 0, t1 * 1000, 1000);/* 绘制秒针 */GUI_MEMDEV_RotateHQ(hMemSec, hMemDST, 0, 0, t0 * 1000, 1000);GUI_MEMDEV_Select(ret);/* 执行窗口无效化,会触发执行WM_PAINT消息 */WM_InvalidateWindow(pMsg->hWin);break;case WM_PAINT:GUI_MEMDEV_WriteAt(hMemDST, (xSize - bmclock_classic_background.XSize)/2 ,
(ySize - bmclock_classic_background.YSize)/2);break;default:WM_DefaultProc(pMsg);break;}
}
  • WM_CREATE:

创建了一个定时器。

  • WM_TIMER:

1、 函数WM_RestartTimer设置每秒更新1次。

2、 函数RTC_ReadClock用于读取硬件定时器实时时钟。

3、 通过GUI_MEMDEV_Select实现时钟表盘,时针,分针和秒针绘制到存储设备hMemDST里面。

4、 函数GUI_MEMDEV_RotateHQ用于旋转指针。

5、 函数WM_InvalidateWindow实现窗口无效化,从而会触发WM_PAINT消息的执行。

  • WM_PAINT:

通过函数GUI_MEMDEV_WriteAt整体绘制时钟表盘到界面上。

57.7 实验例程说明(RTOS)

配套例子:

V7-579_emWin6.x炫酷时钟表盘设计,结合硬件RTC(裸机)

V7-580_emWin6.x炫酷时钟表盘设计,结合硬件RTC(RTOS)

实验目的:

  1. 学习emWin上动态展示摄像头采集数据。
  2. emWin功能的实现在MainTask.c文件里面。

实验内容:

1、K1按键按下,串口或者RTT打印任务执行情况(串口波特率115200,数据位8,奇偶校验位无,停止位1)。

2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。

(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。

3、默认上电是通过串口打印信息,如果使用RTT打印信息:

MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可

#define Enable_RTTViewer  1

4、各个任务实现的功能如下:

App Task Start   任务 :启动任务,这里用作BSP驱动包处理。

App Task MspPro任务 :消息处理,这里用作LED闪烁。

App Task UserIF  任务 :按键消息处理。

App Task COM   任务 :暂未使用。

App Task GUI    任务 :GUI任务。

μCOS-III任务调试信息(按K1按键,串口打印):

RTT 打印信息方式:

程序设计:

任务栈大小分配:

μCOS-III任务栈大小在app_cfg.h文件中配置:

#define  APP_CFG_TASK_START_STK_SIZE                      512u

#define  APP_CFG_TASK_MsgPro_STK_SIZE                     2048u

#define  APP_CFG_TASK_COM_STK_SIZE                        512u

#define  APP_CFG_TASK_USER_IF_STK_SIZE                    512u

#define  APP_CFG_TASK_GUI_STK_SIZE                        2048u

任务栈大小的单位是4字节,那么每个任务的栈大小如下:

App Task Start   任务 :2048字节。

App Task MspPro任务 :8192字节。

App Task UserIF  任务 :2048字节。

App Task COM   任务 :2048字节。

App Task GUI    任务 :8192字节。

系统栈大小分配:

μCOS-III的系统栈大小在os_cfg_app.h文件中配置:

#define  OS_CFG_ISR_STK_SIZE                      512u

系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB

emWin动态内存配置:

GUIConf.c文件中的配置如下:

#define EX_SRAM   1/*1 used extern sram, 0 used internal sram */#if EX_SRAM
#define GUI_NUMBYTES  (1024*1024*24)
#else
#define GUI_NUMBYTES  (100*1024)
#endif

通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

#define  EX_SRAM     1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

#define  EX_SRAM     0 表示使用内部SRAM作为emWin动态内存,大小100KB。

默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

emWin界面显示效果:

800*480分辨率界面效果。

57.8 实验例程说明(裸机)

配套例子:

V7-579_emWin6.x炫酷时钟表盘设计,结合硬件RTC(裸机)

V7-580_emWin6.x炫酷时钟表盘设计,结合硬件RTC(RTOS)

实验目的:

  1. 学习emWin上动态展示摄像头采集数据。
  2. emWin功能的实现在MainTask.c文件里面。

emWin界面显示效果:

800*480分辨率界面效果。

emWin动态内存配置:

GUIConf.c文件中的配置如下:

#define EX_SRAM   1/*1 used extern sram, 0 used internal sram */#if EX_SRAM
#define GUI_NUMBYTES  (1024*1024*24)
#else
#define GUI_NUMBYTES  (100*1024)
#endif

通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

#define  EX_SRAM     1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

#define  EX_SRAM     0 表示使用内部SRAM作为emWin动态内存,大小100KB。

默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

57.9 总结

本章节主要为大家讲解了炫酷时钟显示方法,大家也可以尝试其它方式实现动态展示。

【第3版emWin教程】第57章 emWin6.x的炫酷时钟表盘设计,结合硬件RTC相关推荐

  1. 【第3版emWin教程】第45章 emWin6.x窗口管理器之定时器使用

    教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI &am ...

  2. 【第3版emWin教程】第50章 emWin6.x的AppWizard使用控件经典回调方式

    教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第50章(2021-10-01) - uCOS & uCGUI &am ...

  3. 【第3版emWin教程】第42章 emWin6.x窗口管理器之回调消息类型

    教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI &am ...

  4. 【第3版emWin教程】第48章 emWin6.x对话框基础知识

    教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI &am ...

  5. 【第3版emWin教程】第49章 emWin6.x的AppWizard创建控件回调消息

    教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第50章(2021-10-01) - uCOS & uCGUI &am ...

  6. 2022版Maven教程 - 第六章 单一架构案例

    2022版Maven教程 - 第六章 单一架构案例 一.创建工程,引入依赖 1.架构 ①架构的概念 ②单一架构 2.创建工程 3.引入依赖 ①搜索依赖信息的网站 [1]到哪儿找? [2]怎么选择? ② ...

  7. 【第3版emWin教程】第55章 emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果

    教程不断更新中:链接 第55章       emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果 本章节为大家讲解按钮控件自定义回调函数,通过其回调函数就可以实现各种按钮效果.这方面的 ...

  8. 【第3版emWin教程】第8章 emWin6.x的带OS方式移植(STM32H7之RGB接口)

    教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429 第8章   emWin6.x的带OS方式移植(STM32H7之R ...

  9. 【第3版emWin教程】第53章 emWin6.x的按钮Button控件

    教程不断更新中:链接 第53章       emWin6.x的按钮Button控件 本章节为大家讲解emWin支持的按钮控件,按钮控件还是非常实用的,实际项目中用到的地方很多,控件的本质就是窗口,或者 ...

  10. 【第3版emWin教程】第34章 emWin6.x的AppWizard界面开发工具使用方法

    教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429 第34章       emWin6.x的AppWizard界面开 ...

最新文章

  1. C++代理类,句柄(智能指针)_C++沉思录笔记
  2. Matlab中的一些小技巧
  3. Java异常面试问题
  4. numpy 归一化_归一化(MinMax)和标准化(Standard)的区别
  5. php只取时间的下士_PHP 获取时间的各种处理方式!
  6. 【C语言天天练(十九)】restrict关键词
  7. 补发 四人小组 组队简单说明
  8. iOS开发系列-ARC浅解
  9. 环形电流计算公式_辨析!环形差模电感饱和电流的计算公式是什么?
  10. Arduino 控制 DS1302 时钟芯片
  11. Java多线程并发笔记01 对象锁 类锁 对象锁的同步和异步 脏读
  12. Android图像处理(五)镜像、倒影、drawBitmapMesh实现旗帜飘扬效果
  13. 【onnx】——since it‘s not constant, please try to make things (e.g., kernel size) static if possible
  14. 新年新气象,努力奋上新时代
  15. 【转载】阿里面试回来,想和Java程序员谈一谈
  16. 演示笔记本重装系统win10教程,笔记本电脑安装win10系统
  17. php卡片式,50+创意卡片式网站欣赏
  18. 旋转拖动验证码解决方案
  19. SD-WAN,让你的组网更灵活
  20. 百度贴吧顶帖软件机器人

热门文章

  1. 为知笔记打不开 ziw 文件问题
  2. 不会英语能学java_不会英语可以学java吗 不会英语怎么学java?
  3. html古风颜色代码,数字报纸HTML版本
  4. 《流畅的Python第二版》读书笔记——文本和字节序列
  5. android 11如何剪裁上传图片
  6. JMM中的happen-before原则你知道么?
  7. Python小白的飞桨之旅
  8. 掠食细菌—蛭弧菌B. bacteriovorus,可以对抗革兰氏阴性感染?
  9. ESP32使用滑动变阻器(ADC)控制舵机(PWM)Micropython编程
  10. http上传文件服务器限制大小,修改Nginx与Apache配置参数解决http状态码:413上传文件大小限制问题...