一、前言
最近在移植一个手表项目到自己的开发板上,视频如下
STM32自制智能手表 60FPS动画
这个项目是LVGL6的,我自己打算用LVGL8,本身自己对LVGL也算新手,记录下学习心得。
二、记录
我将用到的lvgl的组件做了全局变量,方便使用
/*背景图片*/
static lv_obj_t * imgBg;
/*气压计信息*/
static lv_obj_t * labelBMP;
/*时间信息*/
static lv_obj_t * labelDate;
/*秒指示灯LED*/
static lv_obj_t * ledSec[2];
/*运动图标*/
static lv_obj_t * imgRun;
/*计步次数标签*/
static lv_obj_t * labelStepCnt;
2.1 显示图片
这篇文章讲了显示图片的一些基本步骤https://blog.csdn.net/jf_52001760/article/details/123981424
我的代码如下:
void ImgBg_Create()
{
LV_IMG_DECLARE(ImgBg);
imgBg = lv_img_create(lv_scr_act());
lv_img_set_src(imgBg, &ImgBg);
lv_obj_align(imgBg,LV_ALIGN_CENTER, 0, 0);
}
需要注意点:
LV_IMG_DECLARE(xxxxx);这个xxxxx是按生成的上面教程里生成的你自己定的.c文件的名字
2.2 创建样式和标签
static void LabelTopBar_Create()
{
labelBMP = lv_label_create(lv_scr_act());
static lv_style_t bmp_style;
lv_style_init(&bmp_style);
lv_style_set_text_color(&bmp_style,lv_color_hex(0xFFFFFF));
lv_style_set_text_font(&bmp_style,&lv_font_montserrat_10);
lv_style_set_text_opa(&bmp_style,LV_OPA_COVER);
lv_obj_add_style(labelBMP,&bmp_style,0);
lv_label_set_text(labelBMP, "-- C -- kPa");
lv_obj_align(labelBMP,LV_ALIGN_TOP_LEFT, 0, 0);
lv_timer_t * timer = lv_timer_create(Task_TopBarUpdate, 500, NULL);
}
需要注意点:
1、可以在设置标签的文本时直接设置单独设置标签的颜色,代码如下:
lv_label_set_recolor(labelDate, true);//这行必须要,不然改变不了颜色
lv_label_set_text(labelDate, "12#FF0000 /#21 MON");
效果如下,中间的 “/”变红了,颜色是由 #FF000 ,决定的
2、像中间时钟这种每个标签都需要改变,也可用下面这种方式逐个定义
先定义成数组
static lv_obj_t * labelTime_Grp[4];
#define __Sizeof(arr) (sizeof(arr)/sizeof(arr[0]))
for(int i = 0; i < __Sizeof(labelTime_Grp); i++)
{
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_obj_add_style(label,&time_style,0);
lv_label_set_text(label, "0");
lv_obj_align(label,LV_ALIGN_CENTER, x_mod[i], 0);
labelTime_Grp[i] = label;
}
然后就可以单独更改
lv_label_set_text_fmt(labelTime_Grp[3],"%d",RTC_Time.RTC_Minutes%10);
lv_label_set_text_fmt(labelTime_Grp[2],"%d",RTC_Time.RTC_Minutes/10);
lv_label_set_text_fmt(labelTime_Grp[1],"%d",RTC_Time.RTC_Hours%10);
lv_label_set_text_fmt(labelTime_Grp[0],"%d",RTC_Time.RTC_Hours/10);
2.3 lvgl定时器
标签有的时候需要刷新,我这里用定时器,定时的去刷新,上面程序的最后一行就是创建了一个定时器任务。我在里面指定了函数和执行周期,最后一个参数是可以传参进定时器任务里,实例如下。
void my_timer(lv_timer_t * timer)
{
/*Use the user_data*/
uint32_t * user_data = timer->user_data;
printf("my_timer called with user data: %d\n", *user_data);
/*Do something with LVGL*/
if(something_happened) {
something_happened = false;
lv_btn_create(lv_scr_act(), NULL);
}
}
...
static uint32_t user_data = 10;
lv_timer_t * timer = lv_timer_create(my_timer, 500, &user_data);
回到我自己的函数,如下:
void Task_TopBarUpdate(lv_timer_t * timer)
{
/*Parameter Configuration*/
float BMP_Pressure,BMP_Temperature;
float altitude;
/*气压计状态更新*/
while(BMP280_GetStatus(BMP280_MEASURING) != RESET);
while(BMP280_GetStatus(BMP280_IM_UPDATE) != RESET);
BMP_Temperature = (float)BMP280_Get_Temperature();
BMP_Pressure = (float)BMP280_Get_Pressure();
altitude = ((pow(101.325f/(BMP_Pressure/1000.0f),(float)0.1902f)-1.0f)*(BMP_Temperature+273.15f))/0.0065f;
//altitude =((8.51f*(BMP_Temperature+273.15f))/(9.8f*28.959f))*(log(101.325f/(BMP_Pressure/1000.0f))) ;
lv_label_set_text_fmt(labelBMP,"% 2dC"LV_SYMBOL_DEGREE_SIGN"% 2dm", (int)BMP_Temperature,(int)altitude);
}
主要是获取海拔和气温, lv_label_set_text_fmt是可以格式化输出,有点像 printf。