IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 单片机---HLK-W801图形框架LVGL下开发(一) -> 正文阅读

[嵌入式]单片机---HLK-W801图形框架LVGL下开发(一)

知识点

《单片机—HLK-W801并口驱动ST7789》
《单片机—HLK-W801驱动触摸屏》
《单片机—HLK-W801图形框架LVGL移植》

简单介绍

根据前面的知识点内容,一步一步走了过来,实现了lvgl在HLK801上的运行,还是挺让人欣慰的,没有遇到让人半途而废的坑,这就和减肥一个道理,坚持下来,以后还能多吃点。
在这里插入图片描述
在前面的基础上,这次来学习一下绘制一个简单的界面,做一个简单的时钟显示。其实市面上很多类似的智能wifi时钟,都是在这个基础上实现的,能够通过网络同步时间,并且能够获得天气信息并显示出来。
今天就做个简单的RTC时钟,学习一下界面的绘制。

界面绘制

代码参考自LVGL8制作简易时钟
在这里插入图片描述
修改了全屏的黑色背景,其他部分没有修改。因为背景太白,有点伤眼。
在这里插入图片描述

界面部分

void lvgl_clock_start()
{
    static lv_style_t date_time_clock_style; // 最外层对象的样式
    lv_style_reset(&date_time_clock_style); // 重置样式
    lv_style_init(&date_time_clock_style); // 初始化样式  
    lv_style_set_radius(&date_time_clock_style, 0); // 设置样式圆角,去掉圆角
    lv_style_set_bg_opa(&date_time_clock_style, LV_OPA_100); // 设置样式背景透明度,完全不透
    lv_style_set_border_width(&date_time_clock_style, 0); // 设置样式边框宽度
    lv_style_set_bg_color(&date_time_clock_style, lv_color_black()); // 设置样式背景颜色,黑色
    lv_style_set_pad_left(&date_time_clock_style, 1); // 设置样式左边padding填充宽度
    lv_style_set_pad_right(&date_time_clock_style, 1); // 设置样式右边padding填充宽度
    lv_style_set_pad_top(&date_time_clock_style, 0); // 设置样式顶部padding填充宽度
    lv_style_set_pad_bottom(&date_time_clock_style, 0); // 设置样式底部padding填充宽度
 
    static lv_style_t time_style; // 时间对象样式
    lv_style_reset(&time_style);
    lv_style_init(&time_style);
    lv_style_set_bg_opa(&time_style, LV_OPA_COVER);
    lv_style_set_border_width(&time_style, 0);
    lv_style_set_radius(&time_style, 5);
    lv_style_set_bg_color(&time_style, lv_palette_main(LV_PALETTE_BLUE));
    lv_style_set_pad_left(&time_style, 0);
    lv_style_set_pad_right(&time_style, 0);
    lv_style_set_pad_top(&time_style, 0);
    lv_style_set_pad_bottom(&time_style, 0);
 
    static lv_style_t date_style; // 日期对象样式
    lv_style_reset(&date_style);
    lv_style_init(&date_style);
    lv_style_set_bg_opa(&date_style, LV_OPA_COVER);
    lv_style_set_border_width(&date_style, 0);
    lv_style_set_radius(&date_style, 5);
    lv_style_set_bg_color(&date_style, lv_palette_main(LV_PALETTE_BLUE));
    lv_style_set_pad_left(&date_style, 0);
    lv_style_set_pad_right(&date_style, 0);
 
	/* Time font */
    static lv_style_t time_label_style; // 时间标签样式
    lv_style_reset(&time_label_style); // 重置样式
    lv_style_init(&time_label_style); // 初始化样式
    lv_style_set_text_color(&time_label_style , lv_color_white()); // 设置标签样式文本颜色
    lv_style_set_text_font(&time_label_style, &lv_font_montserrat_32); // 设置字体风格
    lv_style_set_text_opa(&time_label_style, LV_OPA_COVER); // 设置字体透明度
    lv_style_set_bg_opa(&time_label_style, LV_OPA_0); // 设置样式背景透明度
 
	/* Date font */
    static lv_style_t date_label_style; // 日期标签样式
    lv_style_reset(&date_label_style);
    lv_style_init(&date_label_style);
    lv_style_set_text_opa(&date_label_style, LV_OPA_COVER);
    lv_style_set_bg_opa(&date_label_style, LV_OPA_0);
    lv_style_set_text_color(&date_label_style , lv_color_white());
    lv_style_set_text_font(&date_label_style, &lv_font_montserrat_16);
 
	/* Week font */
    static lv_style_t week_lable_style; // 日期标签样式
    lv_style_reset(&week_lable_style);
    lv_style_init(&week_lable_style);
    lv_style_set_text_opa(&week_lable_style, LV_OPA_COVER);
    lv_style_set_bg_opa(&week_lable_style, LV_OPA_0);
    lv_style_set_text_color(&week_lable_style, lv_color_white());
    lv_style_set_text_font(&week_lable_style, &lv_font_montserrat_16);
 
	/* Time & Date */
    lv_obj_t *time_date_obj = lv_obj_create(lv_scr_act()); // 基于屏幕创建时间日期对象
    if (time_date_obj == NULL)
    {
        printf("[%s:%d] time_date_obj create failed\n", __FUNCTION__, __LINE__);
        return;
    }
 
	lv_obj_set_size(time_date_obj, 320, 240); // 设置对象大小
    lv_obj_center(time_date_obj); // 对象居屏幕中间显示
	lv_obj_add_style(time_date_obj, &date_time_clock_style, LV_STATE_DEFAULT); //给time_date_obj对象添加样式
 
    /*Time display*/
    lv_obj_t *time_obj = lv_obj_create(time_date_obj); // 基于time_date_obj对象创建时间对象
    if (time_obj == NULL)
    {
        printf("[%s:%d] time_obj create failed\n", __FUNCTION__, __LINE__);
        return;
    }
 
    lv_obj_set_size(time_obj, 158, 100); // 设置对象大小
    lv_obj_align_to(time_obj, time_date_obj, LV_ALIGN_LEFT_MID, 0, 0); // 设置time_obj对象基于time_date_obj对象左边中间对齐
    lv_obj_add_style(time_obj, &time_style, LV_STATE_DEFAULT);  // 给time_obj对象添加样式
 
    static lv_clock_t lv_clock = { 0 };
 
    lv_clock.time_label = lv_label_create(time_obj); // 基于time_obj对象创建时间显示标签对象 lv_clock.time_label
    if (lv_clock.time_label == NULL)
    {
        printf("[%s:%d] time_label create failed\n", __FUNCTION__, __LINE__);
        return ;
    }
 
    lv_obj_add_style(lv_clock.time_label, &time_label_style, LV_STATE_DEFAULT); // 给对象 lv_clock.time_label添加样式
 
    /*Date display*/
    lv_obj_t *date_obj = lv_obj_create(time_date_obj); // 基于time_date_obj对象创建date_obj对象
    if (date_obj == NULL)
    {
        printf("[%s:%d] date_obj create failed\n", __FUNCTION__, __LINE__);
        return ;
    }
    lv_obj_set_size(date_obj, 158, 100); // 设置对象大小
    lv_obj_align_to(date_obj, time_date_obj, LV_ALIGN_RIGHT_MID, 0, 0); //设置date_obj对象基于time_date_obj对象右边中部对齐
    lv_obj_add_style(date_obj, &date_style, LV_STATE_DEFAULT); // 给date_obj对象添加样式
 
    lv_clock.date_label = lv_label_create(date_obj); // 基于date_obj对象创建lv_clock.date_label日期显示对象
    if (lv_clock.date_label == NULL)
    {
        printf("[%s:%d] date_label create failed\n", __FUNCTION__, __LINE__);
        return ;
    }
    lv_obj_add_style(lv_clock.date_label, &date_label_style, LV_STATE_DEFAULT); // 给lv_clock.date_label对象添加样式
 
    /*Week display*/
    lv_clock.weekday_label = lv_label_create(date_obj); // 基于date_obj对象创建星期显示lv_clock.weekday_label对象
    if (lv_clock.weekday_label == NULL)
    {
        printf("[%s:%d] weekday_label create failed\n", __FUNCTION__, __LINE__);
        return;
    }
    lv_obj_add_style(lv_clock.weekday_label, &week_lable_style, LV_STATE_DEFAULT); // 给对象lv_clock.weekday_label添加样式
 
    // 设置时间标签lv_clock.time_label对象基于父对象居中对齐
    lv_obj_align_to(lv_clock.time_label, lv_obj_get_parent(lv_clock.time_label), LV_ALIGN_CENTER, 0, 0);
     // 设置时间标签lv_clock.date_label对象基于父对象顶部中间对齐
    lv_obj_align_to(lv_clock.date_label, lv_obj_get_parent(lv_clock.date_label), LV_ALIGN_TOP_MID, 2, 0);
    // 设置时间标签lv_clock.weekday_label对象基于父对象底部中间对齐
    lv_obj_align_to(lv_clock.weekday_label, lv_obj_get_parent(lv_clock.weekday_label), LV_ALIGN_BOTTOM_MID, -2, 0);
 
    lv_timer_t* task_timer = lv_timer_create(clock_date_task_callback, 200, (void *)&lv_clock); // 创建定时任务,200ms刷新一次
    if (task_timer == NULL)
    {
        printf("[%s:%d] lv_timer_create failed\n", __FUNCTION__, __LINE__);
    }
}

RTC部分

前面的代码创建了定时任务,来定时获取时间并显示,这里我们只是简单的使用了一下HLK-W801的RTC模块,用来实时获取时间并显示。
简单也要学习一下,知识源自于demo。

在这里插入图片描述

RTC初始化,这里定义了时钟的初始化,内部初始化了RTC的时间,然后启动了RTC

static void RTC_Init(void)
{
	hpmu.Instance = PMU;
	hpmu.ClkSource = PMU_CLKSOURCE_32RC;
	HAL_PMU_Init(&hpmu);
}

static void CLOCK_Init(void)
{
	RTC_TimeTypeDef time;
	
	RTC_Init();
	time.Year = 122;
	time.Month = 3;
	time.Date = 10;
	time.Hours = 15;
	time.Minutes = 37;
	time.Seconds = 10;
	HAL_PMU_RTC_Start(&hpmu, &time);

}

然后我们在定时任务的回调函数中使用了时间的获取。

static void clock_date_task_callback(lv_timer_t *timer)
{
    static const char *week_day[7] = { "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" };
    static struct tm *time_info;
	RTC_TimeTypeDef time;

	HAL_PMU_RTC_GetTime(&hpmu, &time);
    int year = (time.Year + 1900);
    int month = time.Month;
    int day = time.Date;
    int weekday = CaculateWeekDay(year,month,day);
    int hour =time.Hours;
    int minutes = time.Minutes;
    int second = time.Seconds;
 
    if (timer != NULL && timer->user_data != NULL)
    {
        lv_clock_t * clock = (lv_clock_t *)(timer->user_data);
        if (clock->time_label != NULL)
        {
            lv_label_set_text_fmt(clock->time_label, "%02d:%02d:%02d", hour, minutes, second);
            lv_obj_align_to(clock->time_label, lv_obj_get_parent(clock->time_label), LV_ALIGN_CENTER, 0, 0);
        }
 
        if (clock->date_label != NULL)
        {
            lv_label_set_text_fmt(clock->date_label, "%d-%02d-%02d", year, month, day);
            lv_obj_align_to(clock->date_label, lv_obj_get_parent(clock->date_label), LV_ALIGN_TOP_MID, 2, 0);
        }
 
         if (clock->weekday_label != NULL)
         {
            lv_label_set_text_fmt(clock->weekday_label, "%s", week_day[weekday]);
            lv_obj_align_to(clock->weekday_label, lv_obj_get_parent(clock->weekday_label), LV_ALIGN_BOTTOM_MID, -2, 0);
         }
    }
}

就基本完成了时间的显示。

星期???

这里就有一个神奇的知识了,如何知道某年某月某日,是星期几?
有人说很简单,百度一下就行了。
在这里插入图片描述
现在世界各国通用一星期七天的制度。这个制度最早由君士坦丁大帝(Constantine the Great)制定。他在公元321年3月7日正式宣布7天为1周,这个制度一直沿用至今。一周7天的英文名称是Sunday(星期天)、Monday(星期一)、Tuesday(星期二)、Wednesday(星期三)、Thursday(星期四)、Friday(星期五)、Saturday(星期六)。
在这里插入图片描述

可是算了一下,那天是周一……。
试想一下:
大帝:今天开始实行星期制,一周七天,那么今天是第一天实行,就是星期一吧。
大臣:……星期一不是第二天吗?为啥今天不是星期天。
大帝:就你话多,来人呐~
大臣:
在这里插入图片描述
我们现在用的计算星期的算法,是根据一个公式《使用基姆拉尔森计算公式》得出来的,这里有推导过程《C语言根据日期(年,月,日)判断星期几(使用基姆拉尔森计算公式)》
这个公式也是有前提的,就是0年1月1日是星期1。感觉这个定义就比较能接受,比君士坦大帝那个常规 一点。
在这里插入图片描述
那么具体算法的话,

static int CaculateWeekDay(int y, int m, int d) //年月日换算成星期几
{
	int week = 0;
	if (m==1 || m==2) 
	{
		m=(m==1?13:14);
		y=y-1;
		//此处表示把1,2月计算到上一年的13,14月
	}
	week=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
	return week+1;
}

至于为什么1月和2月单独处理,还是去看推导过程吧。一句两句也说不清楚。
在这里插入图片描述

加个背景图

黑乎乎的背景虽然省电,但是也不够美观呢,所以来试着加个图片。
首先是图片要转化为代码中的c数组,用的这个工具。
下载地址
在这里插入图片描述
图片要事先转化好大小。
然后包含到图像当中。为了不被遮挡,再设置一下时间和日期控件的透明度,就可以达到下面的效果了
在这里插入图片描述
可以猜一下是谁啊
在这里插入图片描述

结束语

看到这么一条消息
在这里插入图片描述
这是希望大伙都牺牲在工作岗位上了。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:43:47  更:2022-03-12 17:43:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:33:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码