开源UI框架LVGL——实现页面切换例程

本文介绍如何使用开源UI库LVGL创建和切换页面。通过create_page1()和create_page2()函数创建页面内容及绑定事件回调,利用lv_scr_load_anim()进行动画效果的页面切换。在main()函数中初始化LVGL并展示页面,同时循环处理LVGL任务,以适应不同应用场景的交互逻辑需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "lvgl.h"

static lv_obj_t * page1;
static lv_obj_t * page2;

static void page1_gesture_event_handler(lv_event_t event)
{
    if (event.code == LV_EVENT_CLICKED) {
       lv_scr_load_anim(page2, LV_SCR_LOAD_ANIM_OVER_LEFT, 300, 0, false);
    }
}


void create_page1(void)
{
    // 创建页面1的内容,例如按钮、标签等
    page1 = lv_obj_create(NULL, NULL);
    lv_obj_set_size(page1, LV_HOR_RES, LV_VER_RES);

    lv_obj_t * btn1 = lv_btn_create(page1, NULL);
    lv_obj_set_pos(btn1, (LV_HOR_RES - 100) / 2, (LV_VER_RES - 50) / 2);
    lv_obj_set_size(btn1, 100, 50);

    lv_obj_t * label1 = lv_label_create(btn1, NULL);
    lv_label_set_text(label1, "Page 2");

    lv_obj_add_event_cb(btn1, page1_gesture_event_handler, LV_EVENT_ALL, NULL);
}


static void page2_gesture_eve
### FreeRTOS与LVGL的关系 FreeRTOS是一款轻量级的操作系统,强大的多任务管理能力确保了程序的高效执行。开发者可以在多个任务间灵活切换,处理不同的优先级事件,大大提升了系统的响应速度和可靠性[^4]。 LVGL(LittlevGL)是一个用于创建嵌入式图形用户界面开源库。它提供了丰富的控件和动画效果,使得在资源受限的微控制器上构建现代感十足的UI成为可能。然而,在嵌入式环境中部署这样的GUI应用通常需要一个稳定可靠的任务调度机制来支持复杂的交互逻辑以及后台数据更新操作。此时引入像FreeRTOS这样成熟稳定的实时操作系统就显得尤为重要了[^3]。 两者结合不仅能让应用程序拥有更流畅自然的人机对话体验,同时也简化了许多底层驱动编程工作;通过合理配置还可以有效降低功耗延长电池寿命等优点。 ### 集成方法概述 为了使这两个组件协同工作,主要涉及以下几个方面: - **初始化**: 创建必要的线程/任务用来运行LVGL框架内部循环; - **定时器服务**: 利用FreeRTOS提供的周期性回调接口给LVGL传递时间脉冲信号(即所谓的心跳),这对于触发屏幕刷新至关重要; - **输入处理**: 设计专门负责读取触摸屏或其他形式输入装置状态变化的消息队列或直接调用API的方式通知GUI层做出相应反应; - **内存分配策略调整**: 考虑到不同平台对于动态申请释放空间有不同的要求,有时需定制化适配malloc/free函数行为以适应目标环境特点。 具体来说,在实际编码过程中会涉及到如下几个关键环节: #### 初始化 LVGL 和 FreeRTOS 任务 ```c // 定义全局变量保存显示缓冲区指针 static lv_disp_buf_t disp_buf; static lv_color_t buf[LV_HOR_RES_MAX * 10]; // 假设水平分辨率为最大值乘以十行高 void app_main(void){ /* ...其他初始化代码... */ // 设置显示器参数并注册至系统 static lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = my_display_flush; // 自定义绘制完成后的回调函数 disp_drv.buffer = &disp_buf; // 将上述设置好的结构体加入到lvgl中去 lv_disp_drv_register(&disp_drv); // 启动一个新的RTOS任务专司于Lvgl相关事务 BaseType_t res = xTaskCreate(lvgl_task, "LVGL", configMINIMAL_STACK_SIZE*8, NULL, tskIDLE_PRIORITY+2, NULL); } ``` 这段C语言片段展示了如何建立好基本的画面呈现设施之后开启独立的工作单元专注于图形渲染流程控制[^1]。 #### 实现心跳功能 为了让图形引擎知道何时应该重绘画面内容,必须定期向其发送指令告知当前时刻已过。这一步骤往往借助于RTOS内建的时间片轮转特性得以实现——每当到达指定间隔就会自动激活关联着特定动作的一段小程序段落。 ```c void vApplicationTickHook(void){ // 提供给lvgl做为帧同步依据 lv_tick_inc(portTICK_PERIOD_MS); // 如果存在未决触碰事件,则立即唤醒gui线程重新计算布局位置关系 if(touch_data_available()){ BaseType_t xHigherPriorityTaskWoken = pdFALSE; xQueueSendToBackFromISR(gTouchEventQueueHandle, &(touch_event),&xHigherPriorityTaskWoken ); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } ``` 此部分实现了每经过一次滴答中断便增加一次计数值供后续判断使用,并且当检测到有新的手指按压坐标到来时及时提醒处于休眠等待状态下的视图解析进程尽快醒来处理最新情况[^2]。 #### 输入设备集成 最后要解决的就是怎样把来自外部传感器的数据转换成交互命令传达给前端展示模块的问题。这里假设采用的是电阻式触摸面板作为主要操控手段之一的话,那么就需要编写相应的采集例程并将获取的结果封装进消息对象里头再推送到之前提到过的共享管道上去。 ```c bool touch_read(lv_indev_drv_t *drv, lv_indev_data_t *data){ uint16_t touch_x=0,touch_y=0; // 这里的read_touch_point()是针对具体硬件编写的辅助工具包所提供的接口 bool touched = read_touch_point(&touch_x,&touch_y); data->state = (touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL); data->point.x = touch_x; data->point.y = touch_y; return false; // 返回false表示我们只报告了一次点击信息而非连续拖拽轨迹 } /* 注册该驱动 */ static lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = touch_read; lv_indev_drv_register(&indev_drv); ``` 以上就是关于如何在一个基于ARM Cortex-M系列MCU平台上搭建起一套完整的图形界面解决方案的大致思路和技术要点说明。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式软硬件叶玄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值