esp32浅试lvgl
lvgl这里就不介绍了 轻量又漂亮的嵌入式gui 这里用最简单步骤跑一个例程
第一步先确保tft-espi可以跑 屏幕正常显示触摸正常
第二部 导入lv-arduino库 这个库虽然不怎么更新了 但是啥都不用配置
第三步 跑例程 库里第一个可以直接跑 第二个需要整合下 我整理的程序是这样
#include <lvgl.h> #include <TFT_eSPI.h> //Ticker tick; /* timer for interrupt handler */ //代码滴答; /* 中断处理程序定时器 */ #define LVGL_TICK_PERIOD 60 TFT_eSPI tft = TFT_eSPI(); /* TFT instance 显示驱动实例化*/ static lv_disp_buf_t disp_buf; static lv_color_t buf[LV_HOR_RES_MAX * 10]; lv_obj_t * slider_label; int screenWidth = 480; int screenHeight = 320; #if USE_LV_LOG != 0 /* Serial debugging 串口debug*/ void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc) { Serial.printf("%s@%d->%s\r\n", file, line, dsc); delay(100); } #endif /* Display flushing 显示内容填充*/ void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { uint16_t c; tft.startWrite(); /* Start new TFT transaction 开始新事务*/ tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window 设置工作窗口*/ for (int y = area->y1; y <= area->y2; y++) { for (int x = area->x1; x <= area->x2; x++) { c = color_p->full; tft.writeColor(c, 1); color_p++; } } tft.endWrite(); /* terminate TFT transaction 结束事务*/ lv_disp_flush_ready(disp); /* tell lvgl that flushing is done 告知填充结束*/ } bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) { uint16_t touchX, touchY; bool touched = tft.getTouch(&touchX, &touchY, 600); if(!touched) { return false; } if(touchX>screenWidth || touchY > screenHeight) { Serial.println("Y or y outside of expected parameters.."); Serial.print("y:"); Serial.print(touchX); Serial.print(" x:"); Serial.print(touchY); } else { data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; /*Save the state and save the pressed coordinate*/ //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y); /*Set the coordinates (if released use the last pressed coordinates)*/ /*保存状态并保存按下的坐标*/ //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y); /*设置坐标(如果松开使用最后按下的坐标)*/ data->point.x = touchX; data->point.y = touchY; Serial.print("Data x"); Serial.println(touchX); Serial.print("Data y"); Serial.println(touchY); } return false; /*Return `false` because we are not buffering and no more data to read返回 `false` 因为我们没有缓冲并且没有更多数据要读取*/ } void printEvent(String Event, lv_event_t event) { Serial.print(Event); printf(" "); switch(event) { case LV_EVENT_PRESSED: printf("Pressed\n"); break; case LV_EVENT_SHORT_CLICKED: printf("Short clicked\n"); break; case LV_EVENT_CLICKED: printf("Clicked\n"); break; case LV_EVENT_LONG_PRESSED: printf("Long press\n"); break; case LV_EVENT_LONG_PRESSED_REPEAT: printf("Long press repeat\n"); break; case LV_EVENT_RELEASED: printf("Released\n"); break; } } void slider_event_cb(lv_obj_t * slider, lv_event_t event) { printEvent("Slider", event); if(event == LV_EVENT_VALUE_CHANGED) { static char buf[4]; /* max 3 bytes for number plus 1 null terminating byte 数字最多 3 个字节加上 1 个空终止字节*/ snprintf(buf, 4, "%u", lv_slider_get_value(slider)); lv_label_set_text(slider_label, buf); /*Refresh the text刷新文字*/ } } void setup() { Serial.begin(9600); /* prepare for possible serial debug 为可能的串行调试做准备*/ lv_init(); #if USE_LV_LOG != 0 lv_log_register_print_cb(my_print); /* register print function for debugging 注册打印功能以进行调试*/ #endif tft.begin(); /* TFT init tft初始化*/ tft.setRotation(1); uint16_t calData[5] = { 275, 3620, 264, 3532, 1 }; tft.setTouch(calData); lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display初始化显示*/ lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.hor_res = screenWidth; disp_drv.ver_res = screenHeight; disp_drv.flush_cb = my_disp_flush; disp_drv.buffer = &disp_buf; lv_disp_drv_register(&disp_drv); /*Initialize the input device driver初始化输入设备*/ lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver输入设备驱动器的描述符*/ indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device触摸板是一种类似指针的设备*/ indev_drv.read_cb = my_touchpad_read; /*Set your driver function设置您的驱动程序功能*/ lv_indev_drv_register(&indev_drv); /*Finally register the driver最终注册驱动*/ //Set the theme..设置主题 lv_theme_t * th = lv_theme_material_init(LV_THEME_DEFAULT_COLOR_PRIMARY, LV_THEME_DEFAULT_COLOR_SECONDARY, LV_THEME_DEFAULT_FLAG, LV_THEME_DEFAULT_FONT_SMALL , LV_THEME_DEFAULT_FONT_NORMAL, LV_THEME_DEFAULT_FONT_SUBTITLE, LV_THEME_DEFAULT_FONT_TITLE); lv_theme_set_act(th); lv_obj_t * scr = lv_cont_create(NULL, NULL); lv_disp_load_scr(scr); //lv_obj_t * tv = lv_tabview_create(scr, NULL); //lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL)); /* Create simple label创建label */ lv_obj_t *label = lv_label_create(lv_scr_act(), NULL); lv_label_set_text(label, "Hello Arduino! (V7.0)"); lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -50); /* Create a slider in the center of the display 创建silder*/ lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL); lv_obj_set_width(slider, screenWidth-50); /*Set the width*/ lv_obj_set_height(slider, 50); lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); /*Align to the center of the parent (screen)与父组件居中对齐*/ lv_obj_set_event_cb(slider, slider_event_cb); /*Assign an event function注册事件*/ /* Create a label below the slider slider下创建一个label*/ slider_label = lv_label_create(lv_scr_act(), NULL); lv_label_set_text(slider_label, "0"); lv_obj_set_auto_realign(slider, true); lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); } void loop() { lv_task_handler(); /* let the GUI do its work gui开始工作*/ }
实际效果 7.69 bAT:/ lvgl示例# esp32 # 单片机开发 https://v.douyin.com/jU7TwcS/ 复制此链接,打开Dou音搜索,直接观看视频!