本次分享的主题是GUI设计,开发板上NXP最新的MCXN947,GUI设计工具是NXP主推的GUI GUIDER.
一、Gui Guider简介
GUI Guider 是由恩智浦(NXP Semiconductors)开发的一款嵌入式人机交互应用开发工具。它主要用于设计图形用户界面(GUI),支持多种操作系统和处理器架构。以下是它的一些主要特点:
1. 用户友好 :提供直观的拖放界面,允许用户无需编程经验即可快速上手设计。
2. 跨平台 :支持不同的操作系统,如Windows 10和Ubuntu 20.04。
3. 多语言支持 :能够支持中文和英文等多种语言。
4. 基于LVGL :基于开源的LVGL(Light and Versatile Graphics Library)图形库,提供可视化所见即所得的设计器。
5. 拖放设计器 :用户可以通过拖放组件来构建界面,无需编写复杂的代码。
6. 实时操作系统支持 :新版本增加了对QNX实时操作系统的支持,允许用户将设计好的HMI应用集成到QNX系统中。
7. 代码生成 :设计完成的GUI页面可以在PC上仿真运行,并生成C代码,以便整合到MCU项目中。
GUI Guider旨在简化嵌入式系统中人机交互图形界面的开发流程,提高开发效率,并帮助开发者创建出高性能、美观的用户界面。
二、启动GUI GUIDER开始GUI设计
快速开始一个空白项目,首先选择LVGL版本。
点击下一步,选择开发板:
点击确认进入GUI设计界面。注意悬浮的“组件”最下面的图标可以展开所有的组件。
下面添加标签TEXT,并设置个性化字体与大小。
针对两个按键,分别添加相应的代码:
之后点击生成代码:
点击编译,目标选择Keil。
用Keil打开工程,查看main函数入口:
static void AppTask(void *param) { #if LV_USE_LOG lv_log_register_print_cb(print_cb); #endif lv_timer_register_get_idle_cb(get_idle_time_cb); lv_timer_register_reset_idle_cb(reset_idle_time_cb); lv_port_pre_init(); lv_init(); lv_port_disp_init(); lv_port_indev_init(); s_lvgl_initialized = true; setup_ui(&guider_ui); events_init(&guider_ui); custom_init(&guider_ui); for (;;) { lv_task_handler(); vTaskDelay(5); } } int main(void) { BaseType_t stat; /* Init board hardware. */ /* attach FRO 12M to FLEXCOMM4 (debug console) */ CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); /* attach FRO 12M to FLEXCOMM2 */ CLOCK_SetClkDiv(kCLOCK_DivFlexcom2Clk, 1u); CLOCK_AttachClk(kFRO12M_to_FLEXCOMM2); CLOCK_SetClkDiv(kCLOCK_DivFlexioClk, 1u); CLOCK_AttachClk(kPLL0_to_FLEXIO); BOARD_InitBootClocks(); BOARD_I2C_ReleaseBus(); BOARD_InitBootPins(); BOARD_InitDebugConsole(); DEMO_InitUsTimer(); /* Init smartdma. */ BOARD_InitSmartDMA(); stat = xTaskCreate(AppTask, "lvgl", configMINIMAL_STACK_SIZE + 800, NULL, tskIDLE_PRIORITY + 2, NULL); if (pdPASS != stat) { PRINTF("Failed to create lvgl task"); while (1) ; } vTaskStartScheduler(); for (;;) { } /* should never get here */ }
查看UI上面的按键对应的代码,其调用结构如下所示:
查看按键对应的回调函数:
static unsigned int counter = 0; static char buf[4]; static void blueCounter_plus_event_handler (lv_event_t *e) { lv_event_code_t code = lv_event_get_code(e); switch (code) { case LV_EVENT_CLICKED: { counter++; sprintf(buf, "%d" , counter); lv_label_set_text(guider_ui.blueCounter_counter, buf); break; } case LV_EVENT_LONG_PRESSED_REPEAT: { counter++; sprintf(buf, "%d" , counter); lv_label_set_text(guider_ui.blueCounter_counter, buf); break; } default: break; } } static void blueCounter_minus_event_handler (lv_event_t *e) { lv_event_code_t code = lv_event_get_code(e); switch (code) { case LV_EVENT_CLICKED: { if(counter) counter--; sprintf(buf, "%d" , counter); lv_label_set_text(guider_ui.blueCounter_counter, buf); break; } case LV_EVENT_LONG_PRESSED_REPEAT: { if(counter) counter--; sprintf(buf, "%d" , counter); lv_label_set_text(guider_ui.blueCounter_counter, buf); break; } default: break; } } void events_init_blueCounter(lv_ui *ui) { lv_obj_add_event_cb(ui->blueCounter_plus, blueCounter_plus_event_handler, LV_EVENT_ALL, ui); lv_obj_add_event_cb(ui->blueCounter_minus, blueCounter_minus_event_handler, LV_EVENT_ALL, ui); } void events_init(lv_ui *ui) { }
三、编译,烧录:
四、实物展示: