峰会下午场的GUI解决方案实训现场,体验正点原子H7RX开发板的GUI解决方案。实操中演示在开发板上运行咖啡机的示例工程。示例的演示效果如下。

工程是基于lvgl开发的,现场实训通过修改原有的示例代码,实现从开机界面到选择界面的跳转。这一过程的实现流程如下。

程序通过定时器回调函数的方式更新页面上的控件属性,并检查是否需要切换页面。在切换页面时,由于当前页面占据很多内存资源,在绘制选择页面前,需要释放掉相关的绘图对象和定时器对象,提升GUI的流畅度。
/* 创建定时器,每5ms调用一次arc_update_cb函数,用来更新圆弧的值和百分百文本 */
arc_timer = lv_timer_create(arc_update_cb, 5, NULL);
/**
* 定时器回调函数,用于更新圆弧的值和百分比文本显示
* @param timer 定时器句柄
*/
static void arc_update_cb(lv_timer_t *timer)
{
char text[10];
if (arc_val < 500) /* 圆弧值小于500 */
{
arc_val += 1; /* 圆弧值自增 */
lv_arc_set_value(arc_active, arc_val); /* 设置圆弧的值 */
int percent = (arc_val * 100) / 500; /* 计算百分比 */
snprintf(text, sizeof(text), "%d%%", percent); /* 格式化文本 */
lv_label_set_text(label_percent, text); /* 更新文本内容 */
}
else if((500 <= arc_val) && (arc_val < 550))
{
arc_val += 1;
snprintf(text, sizeof(text), "Ready"); /* 复制 "Ready" */
lv_label_set_text(label_percent, text); /* 更新文本内容 */
}
else
{
arc_val = 0; /* 当前值清零 */
lv_timer_del(arc_timer); /* 达到最大值,停止定时器 */
lv_obj_del(obj_bottom_bg); /* 达到最大值,删除开机界面 */
lv_selection(); /* 咖啡选择界面 */
}
}
示例程序以演示画面显示为主,绘图部分占据代码的主体。代码中通过调用lv_obj_create
来创建绘图对象句柄,在此基础上,根据屏幕的分辨率(演示使用的显示屏是800x480)对显示的对象的形状、字体、颜色、位置等信息进行设置。开机界面的绘制函数如下,函数实现开机画面的背景刷新、圆弧绘制、进度提示框以及提示信息显示。
void lv_heating_up(void)
{
/* 开机界面底层背景 */
obj_bottom_bg = lv_obj_create(lv_scr_act()); /* 创建底层背景 */
lv_obj_set_size(obj_bottom_bg, 800, 480); /* 设置大小 */
lv_obj_align(obj_bottom_bg, LV_ALIGN_TOP_LEFT, 0, 0); /* 设置位置 */
lv_obj_set_style_border_width(obj_bottom_bg, 0, 0); /* 设置边框宽度 */
lv_obj_set_style_shadow_width(obj_bottom_bg, 0, 0); /* 设置阴影宽度 */
lv_obj_set_style_outline_width(obj_bottom_bg, 0, 0); /* 设置轮廓宽度 */
/* 设置背景颜色 */
lv_obj_set_style_bg_color(obj_bottom_bg, lv_color_hex(0x000000), 0);
lv_obj_set_style_radius(obj_bottom_bg, 0, 0); /* 设置圆角 */
lv_obj_set_style_pad_all(obj_bottom_bg, 0, 0); /* 设置内部填充 */
/* 开机界面上层背景 */
/* 创建上层背景,四个圆角有了弧度 */
lv_obj_t *obj_top_bg = lv_obj_create(obj_bottom_bg);
lv_obj_set_size(obj_top_bg, 800, 480); /* 设置大小 */
lv_obj_align(obj_top_bg, LV_ALIGN_TOP_LEFT, 0, 0); /* 设置位置 */
lv_obj_set_style_border_width(obj_top_bg, 0, 0); /* 设置边框宽度 */
lv_obj_set_style_shadow_width(obj_top_bg, 0, 0); /* 设置阴影宽度 */
lv_obj_set_style_outline_width(obj_top_bg, 0, 0); /* 设置轮廓宽度 */
/* 设置背景颜色 */
lv_obj_set_style_bg_color(obj_top_bg, lv_color_hex(0x2D2227), 0);
lv_obj_set_style_radius(obj_top_bg, 30, 0); /* 设置圆角 */
lv_obj_set_style_pad_all(obj_top_bg, 0, 0); /* 设置内部填充 */
/* 开机界面背景圆弧 */
lv_obj_t *obj_bg_round = lv_obj_create(obj_top_bg); /* 创建背景圆弧 */
lv_obj_set_size(obj_bg_round, 346, 346); /* 设置大小 */
lv_obj_align(obj_bg_round, LV_ALIGN_CENTER, 0, 0); /* 设置位置 */
/* 设置边框颜色 */
lv_obj_set_style_border_color(obj_bg_round, lv_color_hex(0xDDB487), 0);
lv_obj_set_style_border_width(obj_bg_round, 4, 0); /* 设置边框宽度 */
lv_obj_set_style_shadow_width(obj_bg_round, 0, 0); /* 设置阴影宽度 */
lv_obj_set_style_outline_width(obj_bg_round, 0, 0); /* 设置轮廓宽度 */
lv_obj_set_style_bg_opa(obj_bg_round, 0, 0); /* 设置背景透明度 */
lv_obj_set_style_radius(obj_bg_round, 255, 0); /* 设置圆角 */
lv_obj_set_style_pad_all(obj_bg_round, 0, 0); /* 设置内部填充 */
/* 开机界面活动圆弧 */
arc_active = lv_arc_create(obj_bg_round); /* 创建活动圆弧 */
lv_obj_set_size(arc_active, 331, 331); /* 设置圆弧大小 */
lv_obj_align(arc_active, LV_ALIGN_CENTER, 0, 0); /* 设置位置 */
lv_obj_set_style_arc_color(arc_active, lv_color_hex(0xDDB487),LV_PART_INDICATOR); /* 设置圆弧前景颜色 */
lv_obj_set_style_arc_color(arc_active, lv_color_hex(0x423031),LV_PART_MAIN); /* 设置圆弧背景颜色 */
lv_obj_remove_style(arc_active, NULL, LV_PART_KNOB); /* 去除圆弧旋钮 */
lv_obj_clear_flag(arc_active, LV_OBJ_FLAG_CLICKABLE); /* 去除可点击属性 */
lv_obj_set_style_arc_width(arc_active, 14, LV_PART_MAIN); /* 设置背景弧宽度 */
/* 设置前景弧宽度 */
lv_obj_set_style_arc_width(arc_active, 14, LV_PART_INDICATOR);
lv_arc_set_range(arc_active, 0, 500); /* 设置圆弧的范围值 */
lv_arc_set_value(arc_active, 0); /* 初始值设为0 */
lv_arc_set_bg_angles(arc_active, 0, 360); /* 设置背景弧角度 */
lv_arc_set_rotation(arc_active, 270); /* 设置旋转角度 */
/* 创建显示百分比的文本对象 */
label_percent = lv_label_create(obj_bg_round); /* 创建百分比文本 */
lv_obj_align(label_percent, LV_ALIGN_CENTER, 0, 0); /* 设置位置 */
lv_label_set_text(label_percent, "0%"); /* 设置显示的文本 */
lv_obj_set_style_text_font(label_percent, &lv_font_100, 0); /* 设置字体 */
/* 设置文本颜色 */
lv_obj_set_style_text_color(label_percent, lv_color_hex(0xFFFFFF), 0);
/* 创建显示左侧的文本对象 */
lv_obj_t *label_left = lv_label_create(obj_top_bg); /* 创建左侧文本 */
lv_obj_align(label_left, LV_ALIGN_LEFT_MID, 44, 0); /* 设置位置 */
lv_label_set_text(label_left, "Heating up"); /* 设置显示的文本 */
lv_obj_set_style_text_font(label_left, &lv_font_30, 0); /* 设置字体 */
/* 设置文本颜色 */
lv_obj_set_style_text_color(label_left, lv_color_hex(0xDDB487), 0);
/* 创建显示右侧的文本对象 */
lv_obj_t *label_right = lv_label_create(obj_top_bg); /* 创建右侧文本 */
lv_obj_align(label_right, LV_ALIGN_RIGHT_MID, -44, 0); /* 设置位置 */
lv_label_set_text(label_right, "Please wait"); /* 设置显示的文本 */
lv_obj_set_style_text_font(label_right, &lv_font_30, 0); /* 设置字体 */
/* 设置文本颜色 */
lv_obj_set_style_text_color(label_right, lv_color_hex(0xDDB487), 0);
/* 创建定时器,每5ms调用一次arc_update_cb函数,用来更新圆弧的值和百分百文本 */
arc_timer = lv_timer_create(arc_update_cb, 5, NULL);
}
实训演示操作主要是利用定时器回调来实现界面的动态对象的状态更新,显示动态画面的功能。绘制的图形数量多,同时运行流畅,使用STM32H7搭配lvgl实现图形图形界面的效果还是不错的。