998|1

107

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【兆易GD32H759I-EVAL】 LVGL 实验 跑Guider实例 [复制链接]

  本帖最后由 尹小舟 于 2024-6-26 08:45 编辑

LVGL(Light and Versatile Graphics Library)是一个开源的嵌入式图形库,专为资源有限的微控制器和显示器设计。要在MCU中使用LVGL中要实现定时器心跳函数、LCD填充函数和触摸屏驱动。需要遵循几个步骤。下面是一个简化的方法:

LVGL(Light and Versatile Graphics Library)是一个开源的嵌入式图形库,专为资源有限的微控制器和显示器设计。要在LVGL中实现定时器心跳函数、LCD填充函数和触摸屏驱动,你需要遵循几个步骤。下面是一个简化的指南:

1. 定时器心跳函数

LVGL 需要一个心跳函数(通常是一个定时器中断服务程序)来定期调用 lv_task_handler()。这个函数处理所有与LVGL相关的任务,如动画、事件处理等。

步骤

  1. 设置定时器:使用你的微控制器的定时器功能来设置一个周期性的中断。
  2. 中断服务程序:在中断服务程序中,调用 lv_task_handler()。这个函数会处理LVGL的所有任务。
  3. 调整周期:根据你的应用需求调整定时器的周期。较短的周期可以提供更平滑的动画效果,但也会增加CPU负载。

2. LCD填充函数

LVGL 需要一个用于在LCD上显示像素的函数。这通常是一个硬件相关的函数,它知道如何将像素数据发送到LCD控制器。

步骤

  1. 定义填充函数:创建一个函数,它接受一个矩形区域(由x、y坐标、宽度和高度定义)和一个颜色值作为参数。
  2. 实现填充逻辑:在这个函数中,编写代码来将颜色值写入到LCD控制器的帧缓冲区中,对应于指定的矩形区域。这通常涉及设置LCD控制器的地址指针、写入颜色数据等。
  3. 注册填充函数:使用LVGL的API( lv_disp_drv_register())来注册你的填充函数。当LVGL需要更新屏幕时,它就会调用你的函数。

3. 触摸屏驱动

为了使用触摸屏输入,你需要编写一个驱动程序来读取触摸屏控制器的数据,并将其转换为LVGL可以理解的坐标和触摸事件。

步骤

  1. 初始化触摸屏:配置触摸屏控制器的寄存器,使其处于正常工作状态。
  2. 读取触摸数据:编写一个函数来从触摸屏控制器的寄存器中读取触摸数据(如X和Y坐标、触摸状态等)。
  3. 转换数据:将读取到的原始数据转换为LVGL可以理解的坐标和事件。例如,你可能需要将触摸坐标从触摸屏控制器的分辨率缩放到LVGL的坐标系统。
  4. 注册驱动程序:使用LVGL的API(如lv_indev_drv_register())来注册你的触摸屏驱动程序。这样,当LVGL需要处理触摸事件时,它就会调用你的驱动程序来读取触摸数据。
  5. 处理触摸事件:在驱动程序中,除了读取触摸数据外,你还需要编写代码来处理触摸事件(如按下、移动、释放等)。这些事件可以通过LVGL的API(如 lv_event_send())发送到LVGL的事件队列中,以便LVGL的控件可以响应它们。

 

定时器心跳函数移植

 

 


#include "./BSP/TIMER/timer.h"
#include "lvgl.h"

/**
 * @brief        定时器TIMERX定时中断初始化函数
 * @note
 *              定时器的时钟来自APB1或APB2,如果CK_APBx = CK_AHB或CK_APBx = CK_AHB/2,
 *              则定时器的时钟等于CK_AHB(CK_TIMERx = CK_AHB),而CK_AHB为300M, 所以定时器时钟 = 300Mhz
 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定时器工作频率,单位:Mhz
 *
 * @param       arr: 自动重装值
 * @param       psc: 时钟预分频数
 * @retval      无
 */
void timerx_int_init(uint64_t arr, uint16_t psc)
{
    timer_parameter_struct timer_initpara;                 /* timer_initpara用于存放定时器的参数 */

    /* 使能外设定时器时钟 */ 
    rcu_periph_clock_enable(TIMERX_INT_CLK);               /* 使能TIMERX的时钟 */

    /* 复位定时器 */
    timer_deinit(TIMERX_INT);                              /* 复位TIMERX */
    timer_struct_para_init(&timer_initpara);               /* 初始化timer_initpara为默认值 */

    /* 配置定时器参数 */
    timer_initpara.prescaler         = psc;                /* 设置预分频值 */
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE; /* 设置对齐模式为边沿对齐模式 */
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;   /* 设置向上计数模式 */
    timer_initpara.period            = arr;                /* 设置自动重装载值 */
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;   /* 设置时钟分频因子 */
    timer_initpara.repetitioncounter = 0;                  /* 设置重复计数器值 */
    timer_init(TIMERX_INT, &timer_initpara);               /* 根据参数初始化定时器 */

    /* 使能定时器及其中断 */
    timer_interrupt_flag_clear(TIMERX_INT, TIMER_INT_FLAG_UP);   /* 清除定时器更新中断标志 */
  
    timer_interrupt_enable(TIMERX_INT, TIMER_INT_UP);            /* 使能定时器的更新中断 */
    
    nvic_irq_enable(TIMERX_INT_IRQn, 1, 3);                      /* 配置NVIC设置优先级,抢占优先级1,响应优先级3 */
    
    timer_enable(TIMERX_INT);                                    /* 使能定时器TIMERX */
}

/**
 * @brief       定时器TIMERX中断服务函数
 * @param       无
 * @retval      无
 */
void TIMERX_INT_IRQHandler(void)
{
    if (timer_interrupt_flag_get(TIMERX_INT, TIMER_INT_FLAG_UP) == SET)     /* 判断定时器更新中断是否发生 */
    {
                                          
        lv_tick_inc(1);                                                     /* lvgl的1ms心跳 */
        timer_interrupt_flag_clear(TIMERX_INT, TIMER_INT_FLAG_UP);          /* 清除定时器更新中断标志 */
    }
}



 

 

LCD填充函数

 

/**
 * @File  lv_port_disp_templ.c
 *
 */

/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "gd32h759i_lcd_eval.h"
#include "lv_port_disp_template.h"
#include <stdbool.h>
#include "./BSP/LCD/lcd.h"
/*********************
 *      DEFINES
 *********************/
#ifndef MY_DISP_HOR_RES
    #warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen width, default value 320 is used for now.
    #define MY_DISP_HOR_RES    480
#endif

#ifndef MY_DISP_VER_RES
    #warning Please define or replace the macro MY_DISP_HOR_RES with the actual screen height, default value 240 is used for now.
    #define MY_DISP_VER_RES    272
#endif

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void disp_init(void);

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
//        const lv_area_t * fill_area, lv_color_t color);

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    disp_init();

    /*-----------------------------
     * Create a buffer for drawing
     *----------------------------*/

    /**
     * LVGL requires a buffer where it internally draws the widgets.
     * Later this buffer will passed to your display driver's `flush_cb` to copy its content to your display.
     * The buffer has to be greater than 1 display row
     *
     * There are 3 buffering configurations:
     * 1. Create ONE buffer:
     *      LVGL will draw the display's content here and writes it to your display
     *
     * 2. Create TWO buffer:
     *      LVGL will draw the display's content to a buffer and writes it your display.
     *      You should use DMA to write the buffer's content to the display.
     *      It will enable LVGL to draw the next part of the screen to the other buffer while
     *      the data is being sent form the first buffer. It makes rendering and flushing parallel.
     *
     * 3. Double buffering
     *      Set 2 screens sized buffers and set disp_drv.full_refresh = 1.
     *      This way LVGL will always provide the whole rendered screen in `flush_cb`
     *      and you only need to change the frame buffer's address.
     */

    /* Example for 1) */
//    static lv_disp_draw_buf_t draw_buf_dsc_1;
//    static lv_color_t buf_1[MY_DISP_HOR_RES * 10];                          /*A buffer for 10 rows*/
//    lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /* Example for 2) */
    static lv_disp_draw_buf_t draw_buf_dsc_2;
    static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10];                        /*A buffer for 10 rows*/
    static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10];                        /*An other buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

//    /* Example for 3) also set disp_drv.full_refresh = 1 below*/
//    static lv_disp_draw_buf_t draw_buf_dsc_3;
//    static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*A screen sized buffer*/
//    static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES];            /*Another screen sized buffer*/
//    lv_disp_draw_buf_init(&draw_buf_dsc_3, buf_3_1, buf_3_2,
//                          MY_DISP_VER_RES * LV_VER_RES_MAX);   /*Initialize the display buffer*/

    /*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/

    static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

    /*Set up the functions to access to your display*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = MY_DISP_HOR_RES;
    disp_drv.ver_res = MY_DISP_VER_RES;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_2;

    /*Required for Example 3)*/
    //disp_drv.full_refresh = 1;

    /* Fill a memory array with a color if you have GPU.
     * Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.
     * But if you have a different GPU you can use with this callback.*/
    //disp_drv.gpu_fill_cb = gpu_fill;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/*Initialize your display and the required peripherals.*/
static void disp_init(void)
{
    /*You code here*/
}

volatile bool disp_flush_enabled = true;

/* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
 */
void disp_enable_update(void)
{
    disp_flush_enabled = true;
}

/* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
 */
void disp_disable_update(void)
{
    disp_flush_enabled = false;
}

/*Flush the content of the internal buffer the specific area on the display
 *You can use DMA or any hardware acceleration to do this operation in the background but
 *'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    if(disp_flush_enabled) {
        /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/

        int32_t x;
        int32_t y;
        for(y = area->y1; y <= area->y2; y++) {
            for(x = area->x1; x <= area->x2; x++) {
                /*Put a pixel to the display. For example:*/
                /*put_px(x, y, *color_p)*/
							  lcd_draw_point(x, y, color_p ->full);
                color_p++;
            }
        }
    }

    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

/*OPTIONAL: GPU INTERFACE*/

/*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/
//static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
//                    const lv_area_t * fill_area, lv_color_t color)
//{
//    /*It's an example code which should be done by your GPU*/
//    int32_t x, y;
//    dest_buf += dest_width * fill_area->y1; /*Go to the first line*/
//
//    for(y = fill_area->y1; y <= fill_area->y2; y++) {
//        for(x = fill_area->x1; x <= fill_area->x2; x++) {
//            dest_buf[x] = color;
//        }
//        dest_buf+=dest_width;    /*Go to the next line*/
//    }
//}


#else /*Enable this file at the top*/

/*This dummy typedef exists purely to silence -Wpedantic.*/
typedef int keep_pedantic_happy;
#endif

 

 

画点函数

/**
 * @brief       画点
 * @param       x,y: 坐标
 * @param       color: 点的颜色(32位颜色,方便兼容TLI)
 * @retval      无
 */
void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color)
{
	*(__IO uint16_t*)(current_framebuffer + 2*((LCD_PIXEL_WIDTH*y) + x)) = color;
}

 触摸屏驱动

/**
 * @file lv_port_indev_templ.c
 *
 */

/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "lv_port_indev_template.h"
#include "../../lvgl.h"
#include "./BSP/TOUCH/touch.h"
#include <stdio.h>
/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

static void touchpad_init(void);
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static bool touchpad_is_pressed(void);
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);

//static void mouse_init(void);
//static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
//static bool mouse_is_pressed(void);
//static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);

//static void keypad_init(void);
//static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
//static uint32_t keypad_get_key(void);

//static void encoder_init(void);
//static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
//static void encoder_handler(void);

//static void button_init(void);
//static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
//static int8_t button_get_pressed_id(void);
//static bool button_is_pressed(uint8_t id);

/**********************
 *  STATIC VARIABLES
 **********************/
lv_indev_t * indev_touchpad;
//lv_indev_t * indev_mouse;
//lv_indev_t * indev_keypad;
//lv_indev_t * indev_encoder;
//lv_indev_t * indev_button;

//static int32_t encoder_diff;
//static lv_indev_state_t encoder_state;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_port_indev_init(void)
{
    /**
     * Here you will find example implementation of input devices supported by LittelvGL:
     *  - Touchpad
     *  - Mouse (with cursor support)
     *  - Keypad (supports GUI usage only with key)
     *  - Encoder (supports GUI usage only with: left, right, push)
     *  - Button (external buttons to press points on the screen)
     *
     *  The `..._read()` function are only examples.
     *  You should shape them according to your hardware
     */

    static lv_indev_drv_t indev_drv;

    /*------------------
     * Touchpad
     * -----------------*/

    /*Initialize your touchpad if you have*/
    touchpad_init();

    /*Register a touchpad input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = touchpad_read;
    indev_touchpad = lv_indev_drv_register(&indev_drv);

    /*------------------
     * Mouse
     * -----------------*/

    /*Initialize your mouse if you have*/
//    mouse_init();

//    /*Register a mouse input device*/
//    lv_indev_drv_init(&indev_drv);
//    indev_drv.type = LV_INDEV_TYPE_POINTER;
//    indev_drv.read_cb = mouse_read;
//    indev_mouse = lv_indev_drv_register(&indev_drv);

//    /*Set cursor. For simplicity set a HOME symbol now.*/
//    lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act());
//    lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
//    lv_indev_set_cursor(indev_mouse, mouse_cursor);

//    /*------------------
//     * Keypad
//     * -----------------*/

//    /*Initialize your keypad or keyboard if you have*/
//    keypad_init();

//    /*Register a keypad input device*/
//    lv_indev_drv_init(&indev_drv);
//    indev_drv.type = LV_INDEV_TYPE_KEYPAD;
//    indev_drv.read_cb = keypad_read;
//    indev_keypad = lv_indev_drv_register(&indev_drv);

//    /*Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
//     *add objects to the group with `lv_group_add_obj(group, obj)`
//     *and assign this input device to group to navigate in it:
//     *`lv_indev_set_group(indev_keypad, group);`*/

//    /*------------------
//     * Encoder
//     * -----------------*/

//    /*Initialize your encoder if you have*/
//    encoder_init();

//    /*Register a encoder input device*/
//    lv_indev_drv_init(&indev_drv);
//    indev_drv.type = LV_INDEV_TYPE_ENCODER;
//    indev_drv.read_cb = encoder_read;
//    indev_encoder = lv_indev_drv_register(&indev_drv);

//    /*Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
//     *add objects to the group with `lv_group_add_obj(group, obj)`
//     *and assign this input device to group to navigate in it:
//     *`lv_indev_set_group(indev_encoder, group);`*/

//    /*------------------
//     * Button
//     * -----------------*/

//    /*Initialize your button if you have*/
//    button_init();

//    /*Register a button input device*/
//    lv_indev_drv_init(&indev_drv);
//    indev_drv.type = LV_INDEV_TYPE_BUTTON;
//    indev_drv.read_cb = button_read;
//    indev_button = lv_indev_drv_register(&indev_drv);

//    /*Assign buttons to points on the screen*/
//    static const lv_point_t btn_points[2] = {
//        {10, 10},   /*Button 0 -> x:10; y:10*/
//        {40, 100},  /*Button 1 -> x:40; y:100*/
//    };
//    lv_indev_set_button_points(indev_button, btn_points);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/*------------------
 * Touchpad
 * -----------------*/

/*Initialize your touchpad*/
static void touchpad_init(void)
{
    /*Your code comes here*/
	      /*Your code comes here*/
   
//    /* 电阻屏如果发现显示屏XY镜像现象,需要坐标矫正 */
//    if (0 == (tp_dev.touchtype & 0x80)) {
//        tp_adjust();
//        tp_save_adjust_data();
//    }
}

/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;

    /*Save the pressed coordinates and the state*/
    if(touchpad_is_pressed()) {
        touchpad_get_xy(&last_x, &last_y);
        data->state = LV_INDEV_STATE_PR;
    }
    else {
        data->state = LV_INDEV_STATE_REL;
    }

    /*Set the last pressed coordinates*/
    data->point.x = last_x;
    data->point.y = last_y;
}

/*Return true is the touchpad is pressed*/
static bool touchpad_is_pressed(void)
{
    /*Your code comes here*/
    tp_dev.scan(0);
    
    if (tp_dev.sta & TP_PRES_DOWN)
    {
			  printf("\r\n x = %d y = %d",tp_dev.x[0],tp_dev.y[0]);
        return true;
    }
    return false;
}

/*Get the x and y coordinates if the touchpad is pressed*/
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
{
    /*Your code comes here*/

    (*x) = tp_dev.x[0];
    (*y) = tp_dev.y[0];
}

/*------------------
 * Mouse
 * -----------------*/

/*Initialize your mouse*/
static void mouse_init(void)
{
    /*Your code comes here*/
}

///*Will be called by the library to read the mouse*/
//static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
//{
//    /*Get the current x and y coordinates*/
//    mouse_get_xy(&data->point.x, &data->point.y);

//    /*Get whether the mouse button is pressed or released*/
//    if(mouse_is_pressed()) {
//        data->state = LV_INDEV_STATE_PR;
//    }
//    else {
//        data->state = LV_INDEV_STATE_REL;
//    }
//}

///*Return true is the mouse button is pressed*/
//static bool mouse_is_pressed(void)
//{
//    /*Your code comes here*/

//    return false;
//}

///*Get the x and y coordinates if the mouse is pressed*/
//static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y)
//{
//    /*Your code comes here*/

//    (*x) = 0;
//    (*y) = 0;
//}

///*------------------
// * Keypad
// * -----------------*/

///*Initialize your keypad*/
//static void keypad_init(void)
//{
//    /*Your code comes here*/
//}

///*Will be called by the library to read the mouse*/
//static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
//{
//    static uint32_t last_key = 0;

//    /*Get the current x and y coordinates*/
//    mouse_get_xy(&data->point.x, &data->point.y);

//    /*Get whether the a key is pressed and save the pressed key*/
//    uint32_t act_key = keypad_get_key();
//    if(act_key != 0) {
//        data->state = LV_INDEV_STATE_PR;

//        /*Translate the keys to LVGL control characters according to your key definitions*/
//        switch(act_key) {
//            case 1:
//                act_key = LV_KEY_NEXT;
//                break;
//            case 2:
//                act_key = LV_KEY_PREV;
//                break;
//            case 3:
//                act_key = LV_KEY_LEFT;
//                break;
//            case 4:
//                act_key = LV_KEY_RIGHT;
//                break;
//            case 5:
//                act_key = LV_KEY_ENTER;
//                break;
//        }

//        last_key = act_key;
//    }
//    else {
//        data->state = LV_INDEV_STATE_REL;
//    }

//    data->key = last_key;
//}

///*Get the currently being pressed key.  0 if no key is pressed*/
//static uint32_t keypad_get_key(void)
//{
//    /*Your code comes here*/

//    return 0;
//}

///*------------------
// * Encoder
// * -----------------*/

///*Initialize your keypad*/
//static void encoder_init(void)
//{
//    /*Your code comes here*/
//}

///*Will be called by the library to read the encoder*/
//static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
//{

//    data->enc_diff = encoder_diff;
//    data->state = encoder_state;
//}

///*Call this function in an interrupt to process encoder events (turn, press)*/
//static void encoder_handler(void)
//{
//    /*Your code comes here*/

//    encoder_diff += 0;
//    encoder_state = LV_INDEV_STATE_REL;
//}

///*------------------
// * Button
// * -----------------*/

///*Initialize your buttons*/
//static void button_init(void)
//{
//    /*Your code comes here*/
//}

///*Will be called by the library to read the button*/
//static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
//{

//    static uint8_t last_btn = 0;

//    /*Get the pressed button's ID*/
//    int8_t btn_act = button_get_pressed_id();

//    if(btn_act >= 0) {
//        data->state = LV_INDEV_STATE_PR;
//        last_btn = btn_act;
//    }
//    else {
//        data->state = LV_INDEV_STATE_REL;
//    }

//    /*Save the last pressed button's ID*/
//    data->btn_id = last_btn;
//}

///*Get ID  (0, 1, 2 ..) of the pressed button*/
//static int8_t button_get_pressed_id(void)
//{
//    uint8_t i;

//    /*Check to buttons see which is being pressed (assume there are 2 buttons)*/
//    for(i = 0; i < 2; i++) {
//        /*Return the pressed button's ID*/
//        if(button_is_pressed(i)) {
//            return i;
//        }
//    }

//    /*No button pressed*/
//    return -1;
//}

///*Test if `id` button is pressed or not*/
//static bool button_is_pressed(uint8_t id)
//{

//    /*Your code comes here*/

//    return false;
//}

#else /*Enable this file at the top*/

/*This dummy typedef exists purely to silence -Wpedantic.*/
typedef int keep_pedantic_happy;
#endif


 

跑一个Guider的实例

 

GUI-Guider 是恩智浦(NXP)为 LVGL 开发的一个上位机 GUI 设计工具

  1. 功能特点
    • 拖放控件设计:GUI-Guider 提供了一个直观的拖放编辑器,允许用户通过拖放控件的方式快速设计 LVGL GUI 页面,从而加速 GUI 的设计过程。
    • PC 端仿真运行:设计完成的 GUI 页面可以在 PC 上进行仿真运行,用户可以在没有实际硬件的情况下预览自己设计的 UI 界面。
    • C 代码生成:确认设计完毕后,GUI-Guider 可以生成 C 代码,这些代码可以直接整合到 MCU 项目中,实现嵌入式设备的 GUI 功能。
  2. 兼容性
    • GUI-Guider 支持 Windows 10 和 Ubuntu 20.04 等操作系统。
    • 它与恩智浦的通用和跨界 MCU 兼容,并包括用于多个受支持平台的内置项目模板。
  3. 优势
    • 相比 LVGL 官方推出的 SquareLine Studio(付费工具),GUI-Guider 完全免费,同时提供了类似的功能和界面布局。
    • GUI-Guider 生成的示例工程底层代码全部开源

选择V8.3.5

 

 

选择Simulator

 

 

选择ButtonCounter模版

  输入名称创建

 

 

 

选择模拟器生成编译

 

 

添加文件

 

 

 

添加头文件目录

 

 

 

main.c 添加头文件


#include "gui_guider.h"
#include "events_init.h"

 

定义  guider_ui  全局变量
lv_ui guider_ui;

 

#include "gd32h7xx.h"
#include "systick.h"
#include <stdio.h>
#include "gd32h759i_eval.h"
#include "gd32h759i_lcd_eval.h"
#include "./BSP/LCD/lcd.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"
#include "../../lvgl.h"
#include "lv_demo_stress.h"
#include "lv_demo_music.h"
#include "./BSP/TOUCH/touch.h"   
#include "./BSP/TIMER/timer.h"

#include "gui_guider.h"
#include "events_init.h"

lv_ui guider_ui;
/*!
    \brief      enable the CPU cache
    \param[in]  none
    \param[out] none
    \retval     none
*/
void cache_enable(void)
{
    /* enable i-cache */
    SCB_EnableICache();

    /* enable d-cache */
    SCB_EnableDCache();
}

/**
 * @brief       清空屏幕并在右上角显示"RST"
 * @param       无
 * @retval      无
 */
void load_draw_dialog(void)
{
    lcd_clear(WHITE);                                                /* 清屏 */
    lcd_show_string(lcddev.width - 24, 0, 200, 16, 16, "RST", BLUE); /* 显示清屏区域 */
}

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
    /* enable the CPU cache */
    cache_enable();
    /* configure systick */
     //systick_config();
	  delay_init(600);
    /* initilize the LEDs, USART and key */
    gd_eval_led_init(LED1);
    gd_eval_led_init(LED2);
    gd_eval_com_init(EVAL_COM);
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
    timerx_int_init(10 - 1, 30000 - 1); 
	 
    printf("\r\nCK_SYS is %d", rcu_clock_freq_get(CK_SYS));
	  lcd_init();
	  tp_dev.init();
	  if(RESET == gd_eval_key_scan(KEY_WAKEUP))
		{
					lcd_clear(WHITE);   /* 清屏 */
					tp_adjust();        /* 屏幕校准 */
					tp_save_adjust_data();
		}	
	  lv_init();			                       
		lv_port_disp_init(); 
    lv_port_indev_init();
   
    setup_ui(&guider_ui);
	  events_init(&guider_ui);

    while(1) {
       
			 lv_timer_handler();    
      			
    }
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM, USART_FLAG_TBE));

    return ch;
}

 

实验现象

 

 

 

WeChat_20240625173102

GD32H7_EVAL_ATK_LCD _GUIder.zip (13.82 MB, 下载次数: 16)

 

 

 

 

 

 

 

 

最新回复

能把GUI的工具用得这么好,并分享出来,感谢感谢!   详情 回复 发表于 2024-6-26 06:11
点赞 关注
 
 

回复
举报

7086

帖子

11

TA的资源

版主

沙发
 

能把GUI的工具用得这么好,并分享出来,感谢感谢!

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表