【第3版emWin教程】第57章 emWin6.x的炫酷时钟表盘设计,结合硬件RTC
教程不断更新中:第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)
实验目的:
- 学习emWin上动态展示摄像头采集数据。
- 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)
实验目的:
- 学习emWin上动态展示摄像头采集数据。
- 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相关推荐
- 【第3版emWin教程】第45章 emWin6.x窗口管理器之定时器使用
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI &am ...
- 【第3版emWin教程】第50章 emWin6.x的AppWizard使用控件经典回调方式
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第50章(2021-10-01) - uCOS & uCGUI &am ...
- 【第3版emWin教程】第42章 emWin6.x窗口管理器之回调消息类型
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI &am ...
- 【第3版emWin教程】第48章 emWin6.x对话框基础知识
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第48章(2021-09-13) - uCOS & uCGUI &am ...
- 【第3版emWin教程】第49章 emWin6.x的AppWizard创建控件回调消息
教程不断更新中:第3版emWin教程和ThreadX GUIX教程开工,双管齐下,GUIX更新至第28章,emWin更新至第50章(2021-10-01) - uCOS & uCGUI &am ...
- 2022版Maven教程 - 第六章 单一架构案例
2022版Maven教程 - 第六章 单一架构案例 一.创建工程,引入依赖 1.架构 ①架构的概念 ②单一架构 2.创建工程 3.引入依赖 ①搜索依赖信息的网站 [1]到哪儿找? [2]怎么选择? ② ...
- 【第3版emWin教程】第55章 emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果
教程不断更新中:链接 第55章 emWin6.x按钮Button控件自定义回调函数,实现各种按钮效果 本章节为大家讲解按钮控件自定义回调函数,通过其回调函数就可以实现各种按钮效果.这方面的 ...
- 【第3版emWin教程】第8章 emWin6.x的带OS方式移植(STM32H7之RGB接口)
教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429 第8章 emWin6.x的带OS方式移植(STM32H7之R ...
- 【第3版emWin教程】第53章 emWin6.x的按钮Button控件
教程不断更新中:链接 第53章 emWin6.x的按钮Button控件 本章节为大家讲解emWin支持的按钮控件,按钮控件还是非常实用的,实际项目中用到的地方很多,控件的本质就是窗口,或者 ...
- 【第3版emWin教程】第34章 emWin6.x的AppWizard界面开发工具使用方法
教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429 第34章 emWin6.x的AppWizard界面开 ...
最新文章
- C++代理类,句柄(智能指针)_C++沉思录笔记
- Matlab中的一些小技巧
- Java异常面试问题
- numpy 归一化_归一化(MinMax)和标准化(Standard)的区别
- php只取时间的下士_PHP 获取时间的各种处理方式!
- 【C语言天天练(十九)】restrict关键词
- 补发 四人小组 组队简单说明
- iOS开发系列-ARC浅解
- 环形电流计算公式_辨析!环形差模电感饱和电流的计算公式是什么?
- Arduino 控制 DS1302 时钟芯片
- Java多线程并发笔记01 对象锁 类锁 对象锁的同步和异步 脏读
- Android图像处理(五)镜像、倒影、drawBitmapMesh实现旗帜飘扬效果
- 【onnx】——since it‘s not constant, please try to make things (e.g., kernel size) static if possible
- 新年新气象,努力奋上新时代
- 【转载】阿里面试回来,想和Java程序员谈一谈
- 演示笔记本重装系统win10教程,笔记本电脑安装win10系统
- php卡片式,50+创意卡片式网站欣赏
- 旋转拖动验证码解决方案
- SD-WAN,让你的组网更灵活
- 百度贴吧顶帖软件机器人
热门文章
- 为知笔记打不开 ziw 文件问题
- 不会英语能学java_不会英语可以学java吗 不会英语怎么学java?
- html古风颜色代码,数字报纸HTML版本
- 《流畅的Python第二版》读书笔记——文本和字节序列
- android 11如何剪裁上传图片
- JMM中的happen-before原则你知道么?
- Python小白的飞桨之旅
- 掠食细菌—蛭弧菌B. bacteriovorus,可以对抗革兰氏阴性感染?
- ESP32使用滑动变阻器(ADC)控制舵机(PWM)Micropython编程
- http上传文件服务器限制大小,修改Nginx与Apache配置参数解决http状态码:413上传文件大小限制问题...