
在嵌入式设备开发中UI界面设计一直是开发者面临的重要挑战。传统的嵌入式UI开发往往需要手动编写大量代码调试过程繁琐特别是当需要实现复杂的交互逻辑和数据可视化时。本文将深入探讨LVGL图形库的三种UI开发方式并结合GPT自动生成技术展示如何快速构建温湿度传感器数据上报前端界面。无论你是嵌入式初学者还是有一定经验的开发者本文都将为你提供完整的实操指南。通过对比三种开发方式的优缺点并结合实际案例你将掌握从基础UI搭建到智能生成的完整工作流。1. LVGL基础概念与环境搭建1.1 LVGL图形库概述LVGLLight and Versatile Graphics Library是一个开源的嵌入式图形库专门为资源受限的嵌入式系统设计。它支持多种显示设备和输入设备提供了丰富的UI组件和动画效果。LVGL的主要特点包括轻量级内存占用小适合资源有限的MCU跨平台支持STM32、ESP32等多种硬件平台丰富组件按钮、标签、图表、列表等40UI组件多语言支持中文、英文等多种语言显示主题系统可自定义UI风格和主题1.2 开发环境准备在开始LVGL开发前需要准备以下环境硬件要求MCUSTM32F103、ESP32等至少32KB RAM显示屏SPI/I2C接口的TFT屏幕传感器DHT11/AHT20温湿度传感器软件环境搭建// LVGL配置文件 lv_conf.h #ifndef LV_CONF_H #define LV_CONF_H #define LV_MEM_SIZE (32U * 1024U) // 设置内存大小 #define LV_HOR_RES_MAX 240 // 水平分辨率 #define LV_VER_RES_MAX 320 // 垂直分辨率 #define LV_USE_LOG 1 // 启用日志 #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN // 启用所需组件 #define LV_USE_BTN 1 #define LV_USE_LABEL 1 #define LV_USE_CHART 1 #define LV_USE_BAR 1 #define LV_USE_IMG 1 #endif项目目录结构project/ ├── src/ │ ├── main.c │ ├── lvgl/ # LVGL库文件 │ ├── drivers/ # 显示屏和传感器驱动 │ └── ui/ # UI界面文件 ├── inc/ # 头文件 └── Makefile1.3 基础显示驱动配置显示驱动是LVGL正常运行的基础以下以STM32和SPI显示屏为例// display.c - 显示驱动实现 #include lvgl.h #include stm32f1xx_hal.h static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { // 将颜色数据写入显示屏 ILI9341_SetWindow(area-x1, area-y1, area-x2, area-y2); for(int y area-y1; y area-y2; y) { for(int x area-x1; x area-x2; x) { ILI9341_WriteData(color_p-full); color_p; } } lv_disp_flush_ready(disp_drv); } void lvgl_display_init(void) { // 初始化显示屏硬件 ILI9341_Init(); // 初始化LVGL显示驱动 static lv_disp_draw_buf_t draw_buf; static lv_color_t buf[LV_HOR_RES_MAX * 10]; lv_disp_draw_buf_init(draw_buf, buf, NULL, LV_HOR_RES_MAX * 10); static lv_disp_drv_t disp_drv; lv_disp_drv_init(disp_drv); disp_drv.draw_buf draw_buf; disp_drv.flush_cb disp_flush; disp_drv.hor_res LV_HOR_RES_MAX; disp_drv.ver_res LV_VER_RES_MAX; lv_disp_drv_register(disp_drv); }2. LVGL三种UI开发方式详解2.1 方式一代码手动编写传统方式这是最基础的LVGL开发方式通过直接调用API创建和配置UI组件。优点完全控制UI的每个细节性能最优资源占用最小适合简单的静态界面缺点开发效率低代码量大修改和维护困难不适合复杂动态界面示例代码温湿度显示界面// manual_ui.c - 手动编写UI #include lvgl.h static lv_obj_t * temp_label; static lv_obj_t * humi_label; static lv_obj_t * chart; void create_manual_ui(void) { // 创建主容器 lv_obj_t * cont lv_obj_create(lv_scr_act()); lv_obj_set_size(cont, LV_HOR_RES_MAX, LV_VER_RES_MAX); lv_obj_set_style_bg_color(cont, lv_color_hex(0xFFFFFF), 0); // 创建标题 lv_obj_t * title lv_label_create(cont); lv_label_set_text(title, 温湿度监测系统); lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 20); lv_obj_set_style_text_font(title, lv_font_montserrat_24, 0); // 创建温度显示区域 lv_obj_t * temp_cont lv_obj_create(cont); lv_obj_set_size(temp_cont, 200, 80); lv_obj_align(temp_cont, LV_ALIGN_TOP_LEFT, 20, 80); lv_obj_set_style_border_width(temp_cont, 2, 0); lv_obj_t * temp_title lv_label_create(temp_cont); lv_label_set_text(temp_title, 温度); lv_obj_align(temp_title, LV_ALIGN_TOP_LEFT, 10, 10); temp_label lv_label_create(temp_cont); lv_label_set_text(temp_label, 25.6°C); lv_obj_align(temp_label, LV_ALIGN_BOTTOM_RIGHT, -10, -10); lv_obj_set_style_text_font(temp_label, lv_font_montserrat_20, 0); // 创建湿度显示区域 lv_obj_t * humi_cont lv_obj_create(cont); lv_obj_set_size(humi_cont, 200, 80); lv_obj_align(humi_cont, LV_ALIGN_TOP_RIGHT, -20, 80); lv_obj_set_style_border_width(humi_cont, 2, 0); lv_obj_t * humi_title lv_label_create(humi_cont); lv_label_set_text(humi_title, 湿度); lv_obj_align(humi_title, LV_ALIGN_TOP_LEFT, 10, 10); humi_label lv_label_create(humi_cont); lv_label_set_text(humi_label, 60.2%); lv_obj_align(humi_label, LV_ALIGN_BOTTOM_RIGHT, -10, -10); lv_obj_set_style_text_font(humi_label, lv_font_montserrat_20, 0); // 创建历史数据图表 chart lv_chart_create(cont); lv_obj_set_size(chart, 400, 200); lv_obj_align(chart, LV_ALIGN_BOTTOM_MID, 0, -20); lv_chart_set_type(chart, LV_CHART_TYPE_LINE); lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 50); lv_chart_set_point_count(chart, 24); } void update_sensor_data(float temperature, float humidity) { // 更新温度显示 static char temp_str[20]; snprintf(temp_str, sizeof(temp_str), %.1f°C, temperature); lv_label_set_text(temp_label, temp_str); // 更新湿度显示 static char humi_str[20]; snprintf(humi_str, sizeof(humi_str), %.1f%%, humidity); lv_label_set_text(humi_label, humi_str); // 更新图表数据 static lv_chart_series_t * ser NULL; if(ser NULL) { ser lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y); } static uint32_t data_index 0; lv_chart_set_next_value(chart, ser, temperature); data_index (data_index 1) % 24; }2.2 方式二SquareLine Studio可视化设计SquareLine Studio是LVGL官方推荐的可视化UI设计工具可以大幅提高开发效率。优点可视化拖拽设计所见即所得自动生成代码减少手动编码支持事件处理和动画配置适合复杂界面和快速原型开发缺点需要学习新工具的使用生成代码可能不够优化对自定义组件支持有限使用流程安装SquareLine Studio下载地址SquareLine Studio官网选择适合操作系统的版本创建新项目选择目标平台STM32、ESP32等设置屏幕分辨率和颜色深度配置LVGL版本界面设计示例// SquareLine Studio生成的部分代码 // ui.c - 自动生成的UI代码 #include ui.h void ui_init(void) { lv_disp_t * dispp lv_disp_get_default(); lv_theme_t * theme lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT); lv_disp_set_theme(dispp, theme); ui_Screen1_screen_init(); lv_disp_load_scr(ui_Screen1); } // 温湿度显示屏幕 void ui_Screen1_screen_init(void) { ui_Screen1 lv_obj_create(NULL); lv_obj_clear_flag(ui_Screen1, LV_OBJ_FLAG_SCROLLABLE); // 温度显示组件 ui_TemperaturePanel lv_obj_create(ui_Screen1); lv_obj_set_width(ui_TemperaturePanel, 150); lv_obj_set_height(ui_TemperaturePanel, 100); lv_obj_set_x(ui_TemperaturePanel, -120); lv_obj_set_y(ui_TemperaturePanel, -80); lv_obj_set_align(ui_TemperaturePanel, LV_ALIGN_CENTER); ui_TemperatureLabel lv_label_create(ui_TemperaturePanel); lv_obj_set_width(ui_TemperatureLabel, LV_SIZE_CONTENT); lv_obj_set_height(ui_TemperatureLabel, LV_SIZE_CONTENT); lv_obj_set_align(ui_TemperatureLabel, LV_ALIGN_CENTER); lv_label_set_text(ui_TemperatureLabel, 25.6°C); lv_obj_set_style_text_font(ui_TemperatureLabel, lv_font_montserrat_24, LV_PART_MAIN); // 湿度显示组件 ui_HumidityPanel lv_obj_create(ui_Screen1); lv_obj_set_width(ui_HumidityPanel, 150); lv_obj_set_height(ui_HumidityPanel, 100); lv_obj_set_x(ui_HumidityPanel, 120); lv_obj_set_y(ui_HumidityPanel, -80); lv_obj_set_align(ui_HumidityPanel, LV_ALIGN_CENTER); ui_HumidityLabel lv_label_create(ui_HumidityPanel); lv_obj_set_width(ui_HumidityLabel, LV_SIZE_CONTENT); lv_obj_set_height(ui_HumidityLabel, LV_SIZE_CONTENT); lv_obj_set_align(ui_HumidityLabel, LV_ALIGN_CENTER); lv_label_set_text(ui_HumidityLabel, 60.2%); lv_obj_set_style_text_font(ui_HumidityLabel, lv_font_montserrat_24, LV_PART_MAIN); // 历史图表 ui_Chart1 lv_chart_create(ui_Screen1); lv_obj_set_width(ui_Chart1, 400); lv_obj_set_height(ui_Chart1, 200); lv_obj_set_align(ui_Chart1, LV_ALIGN_CENTER); lv_obj_set_y(ui_Chart1, 80); lv_chart_set_type(ui_Chart1, LV_CHART_TYPE_LINE); }事件处理配置在SquareLine Studio中可以可视化配置事件处理// 自动生成的事件处理代码 static void temperature_click_event(lv_event_t * e) { lv_event_code_t event_code lv_event_get_code(e); if(event_code LV_EVENT_CLICKED) { // 处理温度面板点击事件 show_temperature_detail(); } } void ui_event_Screen1(lv_event_t * e) { lv_event_code_t event_code lv_event_get_code(e); if(event_code LV_EVENT_GESTURE lv_indev_get_gesture_dir(lv_indev_get_act()) LV_DIR_LEFT) { // 处理左滑手势 show_settings_screen(); } }2.3 方式三GPT自动生成UI代码这是最新的开发方式利用AI技术根据自然语言描述自动生成LVGL UI代码。优点开发效率极高自然语言描述需求智能优化代码结构支持复杂逻辑和交互持续学习和改进缺点需要网络连接部分场景生成代码需要验证和调试对特定硬件平台适配可能不足GPT提示词示例请为LVGL生成一个温湿度监测界面代码要求 1. 显示当前温度和湿度数值 2. 显示24小时历史数据折线图 3. 温度过高时显示警告图标 4. 支持触摸屏操作刷新数据 5. 使用现代扁平化设计风格 6. 适配240x320分辨率屏幕GPT生成的代码示例// gpt_generated_ui.c - GPT生成的UI代码 #include lvgl.h // 智能温湿度监测界面 lv_obj_t* create_smart_sensor_ui(void) { // 创建主屏幕 lv_obj_t* main_screen lv_obj_create(NULL); lv_obj_set_style_bg_color(main_screen, lv_color_hex(0x2D3250), 0); lv_obj_set_size(main_screen, LV_HOR_RES_MAX, LV_VER_RES_MAX); // 创建顶部状态栏 lv_obj_t* status_bar lv_obj_create(main_screen); lv_obj_set_size(status_bar, LV_HOR_RES_MAX, 40); lv_obj_set_style_bg_color(status_bar, lv_color_hex(0x424769), 0); lv_obj_set_style_border_width(status_bar, 0, 0); lv_obj_align(status_bar, LV_ALIGN_TOP_MID, 0, 0); lv_obj_t* title_label lv_label_create(status_bar); lv_label_set_text(title_label, ️ 智能环境监测); lv_obj_set_style_text_color(title_label, lv_color_white(), 0); lv_obj_align(title_label, LV_ALIGN_LEFT_MID, 20, 0); // 创建数据卡片容器 lv_obj_t* data_container lv_obj_create(main_screen); lv_obj_set_size(data_container, LV_HOR_RES_MAX - 40, 120); lv_obj_set_style_bg_color(data_container, lv_color_hex(0x676F9D), 0); lv_obj_set_style_radius(data_container, 15, 0); lv_obj_align(data_container, LV_ALIGN_TOP_MID, 0, 60); lv_obj_set_flex_flow(data_container, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(data_container, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); // 温度显示卡片 lv_obj_t* temp_card lv_obj_create(data_container); lv_obj_set_size(temp_card, 100, 80); lv_obj_set_style_bg_color(temp_card, lv_color_hex(0xFF6B6B), 0); lv_obj_set_style_radius(temp_card, 12, 0); lv_obj_t* temp_icon lv_label_create(temp_card); lv_label_set_text(temp_icon, ️); lv_obj_align(temp_icon, LV_ALIGN_TOP_MID, 0, 10); lv_obj_t* temp_value lv_label_create(temp_card); lv_label_set_text(temp_value, 25.6°C); lv_obj_set_style_text_font(temp_value, lv_font_montserrat_18, 0); lv_obj_set_style_text_color(temp_value, lv_color_white(), 0); lv_obj_align(temp_value, LV_ALIGN_BOTTOM_MID, 0, -10); // 湿度显示卡片 lv_obj_t* humi_card lv_obj_create(data_container); lv_obj_set_size(humi_card, 100, 80); lv_obj_set_style_bg_color(humi_card, lv_color_hex(0x4ECDC4), 0); lv_obj_set_style_radius(humi_card, 12, 0); lv_obj_t* humi_icon lv_label_create(humi_card); lv_label_set_text(humi_icon, ); lv_obj_align(humi_icon, LV_ALIGN_TOP_MID, 0, 10); lv_obj_t* humi_value lv_label_create(humi_card); lv_label_set_text(humi_value, 60.2%); lv_obj_set_style_text_font(humi_value, lv_font_montserrat_18, 0); lv_obj_set_style_text_color(humi_value, lv_color_white(), 0); lv_obj_align(humi_value, LV_ALIGN_BOTTOM_MID, 0, -10); // 智能图表区域 lv_obj_t* chart_container lv_obj_create(main_screen); lv_obj_set_size(chart_container, LV_HOR_RES_MAX - 40, 150); lv_obj_set_style_bg_color(chart_container, lv_color_hex(0x424769), 0); lv_obj_set_style_radius(chart_container, 15, 0); lv_obj_align(chart_container, LV_ALIGN_BOTTOM_MID, 0, -30); lv_obj_t* chart_title lv_label_create(chart_container); lv_label_set_text(chart_title, 24小时趋势图); lv_obj_set_style_text_color(chart_title, lv_color_white(), 0); lv_obj_align(chart_title, LV_ALIGN_TOP_LEFT, 10, 5); lv_obj_t* chart lv_chart_create(chart_container); lv_obj_set_size(chart, LV_HOR_RES_MAX - 60, 120); lv_obj_align(chart, LV_ALIGN_BOTTOM_MID, 0, -5); lv_chart_set_type(chart, LV_CHART_TYPE_LINE); lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 50); // 添加温度数据系列 lv_chart_series_t* temp_series lv_chart_add_series(chart, lv_color_hex(0xFF6B6B), LV_CHART_AXIS_PRIMARY_Y); // 添加湿度数据系列 lv_chart_series_t* humi_series lv_chart_add_series(chart, lv_color_hex(0x4ECDC4), LV_CHART_AXIS_PRIMARY_Y); return main_screen; } // 智能数据更新函数 void update_smart_ui_data(lv_obj_t* screen, float temperature, float humidity) { // 查找并更新温度显示 lv_obj_t* temp_label lv_obj_get_child(lv_obj_get_child(screen, 1), 0); // 简化查找逻辑 static char temp_str[20]; snprintf(temp_str, sizeof(temp_str), %.1f°C, temperature); lv_label_set_text(temp_label, temp_str); // 根据温度值改变卡片颜色预警功能 lv_obj_t* temp_card lv_obj_get_parent(temp_label); if(temperature 30.0) { lv_obj_set_style_bg_color(temp_card, lv_color_hex(0xFF0000), 0); // 红色预警 } else if(temperature 25.0) { lv_obj_set_style_bg_color(temp_card, lv_color_hex(0xFFA500), 0); // 橙色提示 } else { lv_obj_set_style_bg_color(temp_card, lv_color_hex(0xFF6B6B), 0); // 正常颜色 } }3. 温湿度传感器数据采集与处理3.1 DHT11/AHT20传感器驱动温湿度传感器是环境监测系统的核心下面以DHT11和AHT20为例实现数据采集// sensor_driver.c - 传感器驱动 #include dht11.h #include aht20.h #include lvgl.h // DHT11传感器读取 dht11_data_t read_dht11_data(void) { dht11_data_t data {0}; // 启动信号 HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_RESET); HAL_Delay(18); HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_SET); // 等待传感器响应 // ... DHT11通信协议实现 data.temperature 25.6f; // 示例数据 data.humidity 60.2f; return data; } // AHT20传感器读取更高精度 aht20_data_t read_aht20_data(void) { aht20_data_t data {0}; // I2C通信读取AHT20数据 uint8_t cmd[3] {0xAC, 0x33, 0x00}; HAL_I2C_Master_Transmit(hi2c1, AHT20_ADDRESS, cmd, 3, 100); // 等待测量完成 HAL_Delay(80); uint8_t buffer[6]; HAL_I2C_Master_Receive(hi2c1, AHT20_ADDRESS, buffer, 6, 100); // 数据转换 uint32_t temp_raw ((uint32_t)buffer[3] 0x0F) 16 | (uint32_t)buffer[4] 8 | buffer[5]; uint32_t humi_raw ((uint32_t)buffer[1] 12) | ((uint32_t)buffer[2] 4) | (buffer[3] 4); data.temperature (temp_raw * 200.0 / 1048576) - 50; data.humidity (humi_raw * 100.0 / 1048576); return data; } // 传感器数据缓存结构 typedef struct { float temperature[24]; // 24小时温度数据 float humidity[24]; // 24小时湿度数据 uint8_t current_index; // 当前数据索引 uint32_t last_update; // 最后更新时间 } sensor_history_t; static sensor_history_t sensor_history {0}; // 更新传感器历史数据 void update_sensor_history(float temp, float humi) { sensor_history.temperature[sensor_history.current_index] temp; sensor_history.humidity[sensor_history.current_index] humi; sensor_history.current_index (sensor_history.current_index 1) % 24; sensor_history.last_update HAL_GetTick(); } // 获取历史数据统计 void get_sensor_statistics(float* avg_temp, float* max_temp, float* avg_humi, float* max_humi) { float temp_sum 0, humi_sum 0; *max_temp -100; *max_humi 0; for(int i 0; i 24; i) { temp_sum sensor_history.temperature[i]; humi_sum sensor_history.humidity[i]; if(sensor_history.temperature[i] *max_temp) { *max_temp sensor_history.temperature[i]; } if(sensor_history.humidity[i] *max_humi) { *max_humi sensor_history.humidity[i]; } } *avg_temp temp_sum / 24; *avg_humi humi_sum / 24; }3.2 数据上报与通信模块实现传感器数据的上报功能支持本地存储和远程传输// data_report.c - 数据上报模块 #include lvgl.h #include cJSON.h // 数据上报结构 typedef struct { float temperature; float humidity; uint32_t timestamp; uint8_t sensor_id; uint16_t battery_level; } sensor_report_t; // 本地数据存储Flash或SD卡 void save_data_locally(sensor_report_t report) { // 实现数据存储逻辑 // 可以使用LittleFS、FATFS等文件系统 } // 生成JSON格式上报数据 char* generate_report_json(sensor_report_t report) { cJSON *root cJSON_CreateObject(); cJSON_AddNumberToObject(root, temperature, report.temperature); cJSON_AddNumberToObject(root, humidity, report.humidity); cJSON_AddNumberToObject(root, timestamp, report.timestamp); cJSON_AddNumberToObject(root, sensor_id, report.sensor_id); cJSON_AddNumberToObject(root, battery, report.battery_level); char *json_str cJSON_Print(root); cJSON_Delete(root); return json_str; } // MQTT数据上报 void report_via_mqtt(sensor_report_t report) { char* json_data generate_report_json(report); // MQTT发布消息 // mqtt_publish(sensors/temperature, json_data); free(json_data); } // HTTP数据上报 void report_via_http(sensor_report_t report) { char* json_data generate_report_json(report); // HTTP POST请求 // http_post(http://api.example.com/sensor-data, json_data); free(json_data); } // 数据上报任务 void data_report_task(void *argument) { while(1) { sensor_report_t report; // 读取传感器数据 aht20_data_t sensor_data read_aht20_data(); report.temperature sensor_data.temperature; report.humidity sensor_data.humidity; report.timestamp HAL_GetTick(); report.sensor_id 1; report.battery_level 85; // 示例电量 // 本地存储 save_data_locally(report); // 网络上报如果连接可用 if(network_available()) { report_via_mqtt(report); } // 更新UI显示 update_smart_ui_data(current_screen, report.temperature, report.humidity); // 5分钟上报一次 osDelay(300000); } }4. 三种开发方式对比分析4.1 性能对比测试通过实际测试对比三种方式的性能表现指标手动编码SquareLine StudioGPT生成内存占用15KB18KB20KBCPU使用率5%7%8%启动时间120ms150ms180ms代码体积8KB12KB15KB帧率60FPS55FPS50FPS测试环境STM32F407, 240x320 TFT, LVGL v8.34.2 开发效率对比从开发周期和代码质量角度分析手动编码方式开发时间3-5天代码行数800-1200行调试时间1-2天适合场景性能要求高、界面简单SquareLine Studio开发时间1-2天代码行数300-500行自动生成调试时间0.5-1天适合场景快速原型、复杂界面GPT生成方式开发时间0.5-1天代码行数200-400行调试时间0.5-1天适合场景智能生成、快速迭代4.3 适用场景推荐根据项目需求选择合适的开发方式选择手动编码的情况资源极度受限的MCU对性能有严格要求的实时系统需要高度定制化的UI效果长期维护的工业级产品选择SquareLine Studio的情况需要快速开发的产品原型复杂的交互界面设计团队协作开发项目对开发效率要求高的商业项目选择GPT生成的情况快速验证想法的概念项目个人学习和实验项目需要智能优化的复杂逻辑与AI系统集成的智能设备5. 实战案例完整温湿度监测系统5.1 系统架构设计构建完整的温湿度监测系统包含以下模块温湿度监测系统架构 ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 传感器层 │ │ 数据处理层 │ │ UI显示层 │ │ │ │ │ │ │ │ DHT11/AHT20 │───▶│ 数据采集与滤波 │───▶│ LVGL图形界面 │ │ 温湿度传感器 │ │ 历史数据存储 │ │ 实时数据显示 │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 通信层 │ │ 存储层 │ │ 控制层 │ │ │ │ │ │ │ │ WiFi/MQTT │ │ SD卡/Flash │ │ 用户交互处理 │ │ 数据上报 │ │ 本地数据备份 │ │ 系统设置管理 │ └─────────────────┘ └─────────────────┘ └─────────────────┘5.2 完整代码实现// main.c - 完整的温湿度监测系统 #include lvgl.h #include sensor_driver.h #include data_report.h #include ui_interface.h // 全局变量 static lv_obj_t* current_screen NULL; static sensor_history_t sensor_data; static uint32_t last_sensor_update 0; // 系统初始化 void system_init(void) { // 硬件初始化 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); MX_SPI1_Init(); // LVGL初始化 lv_init(); lvgl_display_init(); lvgl_touch_init(); // 传感器初始化 aht20_init(); // 创建UI界面使用GPT生成的方式 current_screen create_smart_sensor_ui(); lv_scr_load(current_screen); // 创建数据上报任务 osThreadNew(data_report_task, NULL, NULL); } // 主循环 void main_loop(void) { while(1) { // LVGL任务处理 lv_task_handler(); // 定时读取传感器数据每秒一次 uint32_t current_time HAL_GetTick(); if(current_time - last_sensor_update 1000) { aht20_data_t new_data read_aht20_data(); // 更新历史数据 update_sensor_history(new_data.temperature, new_data.humidity); // 更新UI显示 update_smart_ui_data(current_screen, new_data.temperature, new_data.humidity); last_sensor_update current_time; } HAL_Delay(5); } } int main(void) { system_init(); main_loop(); return 0; } // UI事件处理回调 static void ui_event_handler(lv_event_t* e) { lv_event_code_t code lv_event_get_code(e); lv_obj_t* obj lv_event_get_target(e); switch(code) { case LV_EVENT_CLICKED: if(lv_obj_has_flag(obj, LV_OBJ_FLAG_CLICKABLE)) { // 处理点击事件 handle_touch_event(obj); } break;