当前位置:网站首页>Lvgl Library Tutorial 01- porting to STM32 (touch screen)

Lvgl Library Tutorial 01- porting to STM32 (touch screen)

2022-06-13 11:38:00 Frozen candle

LVGL Library migration STM32

LVGL Library profile

LVGL(Light and Versatile Graphics Library) It's a free one 、 Open source embedded graphics library , You can create rich 、 Beautiful interface , There are many controls that can be customized , Support key or touch response , Support for Chinese characters , And the memory occupation is low . Can be in https://lvgl.io/demos Use the web side experience LVGL The dynamic effect of , Then decide whether to use LVGL .

LVGL Use C Language writing , It can be used in raspberry pie 、ESP32 、STM32 Wait on the MCU , And support a variety of large and medium-sized screens ( Just provide a drawing of the screen API that will do ).LVGL The address of our website is :https://lvgl.io/ ,GitHub The address is :https://github.com/lvgl/lvgl .

LVGL Many sample programs are provided , It also provides PC The simulator at the end , It's all accelerating LVGL Development efficiency .

transplant LVGL

LVGL Not only for which single-chip and which screen , In fact, it's even PC The machine can also run . complete LVGL You can refer to the official documentation for the migration of https://docs.lvgl.io/master/porting/index.html . Before transplantation , Please understand the usage of the single chip microcomputer and the screen by yourself and provide the interface program .

Building engineering

Next, let's say STM32 Series single chip microcomputer as an example LVGL Transplantation , The transplant process of different single-chip computers can also refer to the following steps . The following table shows LVGL The required configuration , In the use of LVGL Please make sure that the performance of the single chip microcomputer meets the requirements :

NameMinimalRecommended
Architecture16, 32 or 64 bit microcontroller or processor
Clock> 16 MHz> 48 MHz
Flash/ROM> 64 kB> 180 kB
Static RAM> 16 kB> 48 kB
Draw buffer> 1 ×hor. res. pixels> 1/10 screen size
CompilerC99 or newer

Be careful : Use Keil5 Please turn on “C99 Mode”, Otherwise, it will fail to compile . Also in the use of Keil4 Please upgrade or replace the compiler .

First , stay https://github.com/lvgl/lvgl Download or clone the entire project .LVGL The latest version of is LVGL 8.2 , Be careful LVGL 7 It is no longer updated ,LVGL 7 and 8 Great changes have taken place in the library structure , The code is not very compatible , also LVGL 7 The sample code and simulator for seem to be already in GitHub On and off the shelf . This tutorial uses LVGL 8 For example , transplant LVGL 7 You can refer to , But some details need to be adjusted . It is recommended to use the latest version , Otherwise, the complete tool chain support will not be available .

Use Keil Note that ,LVGL 8 It doesn't seem to work in ARM CC v5 Compiled successfully , Please update the compiler version to ARM CC v6 .

Use STM32 Developers of also need to pay attention to ,STM32 The standard library cannot be used ARM CC v6 compile , Please use HAL Library or replace the compilation tool chain ( Such as LLVM-clang or GCC-none-eabi )

Next, prepare a single-chip computer project by yourself , stay User Or other equivalent directory , Then create a new directory lvgl And enter , From cloning LVGL Copy the following files or directories into the project :

demos
examples
src
lvgl.h
lv_conf_template.h

If you don't need to use the official sample code , It can be done without copying demos Catalog .

Next , take lv_conf_template.h Rename it to lv_conf.h , And move it to the upper level directory .

Be careful :LVGL The directory of the library is complex , Header file references are relatively confusing , Before you fully understand what you are doing , Please do not change the folder name or file location .

Go back to the previous Directory , open lv_conf.h , Will start with #if 0 Conditional compilation canceled , Enable the configuration contained in the file :

/* clang-format off */
#if 1 /*Set it to "1" to enable content*/

The configuration file still needs to be adjusted in several places , First, the front ( The first 27 That's ok ) A macro definition of represents the color depth of the display screen , It needs to be adjusted according to different display screens :

/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 16

If the color depth of the screen is inconsistent , Be sure to modify the macro .LVGL An appropriate color definition will be created based on this macro , If it is inconsistent with the actual situation, the color will be disordered in the display .

If set to 8 , On behalf of the use of 8 Bit color , among RBG Chromatic value 3 、3 、2 position ; If set to 16 , be RBG Chromatic value 5 、6 、5 position , This is a lot of TFT The color format of the screen ;32 It is PC Transparent for both mobile and mobile devices 32bit Bitmap ,RGB Color value and transparency occupy one byte each .

The first 52 There is also a macro in the line that represents the maximum memory usage , It can be modified according to the actual situation of single chip microcomputer , As long as it is greater than what is written in the notes 2kB Just go .

    /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
    #define LV_MEM_SIZE (32U * 1024U)          /*[bytes]*/

besides , In the 273 and 280 Line also has two macro definitions , If you set them to 1 , The current memory usage and frame rate can be displayed in the lower left and right corners of the screen , Very suitable for performance analysis :

#define LV_USE_PERF_MONITOR 0
#define LV_USE_MEM_MONITOR 0

Other settings can be modified by comparing notes and documents .

Next, import the project file , This step requires that lvgl/src In addition to draw Import all files in the directory , and draw In the directory except the root directory .c The documents , Import only sw Source files in the directory .LVGL 8 The directory depth of is large , Please be patient to add , Check carefully , Don't miss the document .

Use STM32 If the single-chip microcomputer is used, you also need to pay attention to modifying the heap in the startup file 、 Stack size , At least each setting 8kB Space :

Stack_Size      EQU     0x00002000
Heap_Size       EQU     0x00002000

After adding all , Try to compile the entire project , It should be zero error Passed .

Use ARM CC v6 It could happen __aeabi_assert Problems with undefined symbols , Macros can be defined in advance throughout project management NDEBUG Disable the symbol .

Displays the of the device API docking

LVGL Only the algorithm of drawing is provided , Other contents need to be prepared by ourselves .LVGL The interface provided is in lvgl/examples/porting Directory , This directory contains the following files :

  • lv_port_disp : Display device interface
  • lv_port_indev : Input device interface
  • lv_port_fs : File system interface

End each file name with template Remove . Next, write the interface of the display device , At least make sure you can show something to .


stay lv_port_disp.c And its header file , First, you need to remove conditional compilation , Enable this section :

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

Because the file was renamed before , Therefore, you need to modify the corresponding name in the source file :

#include "lv_port_disp.h"

The source file has two macro definitions in the macro definition area , It needs to be modified to the actual display size . Remember to change after #warning Preprocessing statements remove :

#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    320
#endif
/* ... same as above ... */

lv_port_disp_init() Is a top-level function to initialize the display device , In the main function, you need to call it to initialize the function of the display device at one time . The modification method of this function has been clearly stated in the notes , Next, a modification example is provided .

First of all, will 91~102 The two statements of the line that provide the display cache are all commented or deleted , Only keep /* Example for 1) */ . And then modify 114~115 The two values of the line are the actual screen sharpness .

    /* 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*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = 320;
    disp_drv.ver_res = 240;

There are also two functions in this file disp_init() and disp_flush() , The interface of the actual display device shall be provided .

disp_init() in , You need to provide the initialization code of the screen , If it has been initialized externally, it can be ignored .

disp_flush() in , You need to draw a pixel at the position of the annotation according to the provided parameters ,. This process can also be faster using padding functions , You can even use GPU And so on , For details on how to write code, please refer to the notes . for example , The test screen draws pixels one by one , So as to fill an area :

/* ... */
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
            ILI9341_SetFrontColor(&ili9341, color_p->full);
            ILI9341_DrawPixel(&ili9341, x, y);
            color_p++;
        }
    }
/* ... */

thus ,API The transplant is over . Next, you can write program tests LVGL The effect has been achieved. .

LVGL The initialization

In the use of LVGL front , You need to call the following two functions to complete LVGL Library initialization and LVGL Display the initialization of the device interface :

lv_init();
lv_port_disp_init();

Then you can draw the graph . Here is a simple code , You can draw a button :

lv_obj_t* btn = lv_btn_create(lv_scr_act()); 
lv_obj_set_pos(btn, 10, 10);
lv_obj_set_size(btn, 120, 50);
lv_obj_t* label = lv_label_create(btn);
lv_label_set_text(label, "Button");
lv_obj_center(label);

After drawing , You also need to call... In the main loop lv_task_handler() function , In this way, the drawn content can be updated to the screen in real time :

while (1) {
    /* ... */
    lv_task_handler();
}

Then download the compiled results to the MCU , You can see a button on the screen :

image

LVGL Import device migration

The above describes how to migrate display devices . however LVGL Is a user interface library , Light has a display device , It's not enough to do some user interaction , So you need to use an input device .

LVGL Support 5 Types of input devices :

  • Touchpad : Touch screen
  • Mouse : mouse
  • Keypad : keyboard
  • Encoder : Encoder
  • Button : Key

At the time of transplantation , Don't get the type of input device wrong , otherwise LVGL Unable to respond to input .

LVGL All interfaces to input devices are stored in lv_port_indev.c And its header file . Next, take the touch screen as an example to introduce the transplantation of input devices , Different equipment API There's a difference , Please use the official documents for migration .

First , You need to remove... From both files #if 0 Conditional compilation , Enable two files .

stay lv_port_indev.c in , Contains 5 Of a device API , But they can't all be used , So you need to cut out useless functions and definitions . Especially when initializing functions lv_port_indev_init() in , If you do not remove the initialization statements of useless devices , Then there may be problems when calling .

The source code has highlighted the differences in the comments API The partition , Just keep the required code according to the partition .

According to the idea of the code ( The simplified source code is not long , And a high degree of abstraction , You can read it completely ), Next, implement the functions of the three functions .

First of all touchpad_init() , Here, you need to initialize the input device , Just like initializing the touch screen above .

stay touchpad_is_pressed() in , A display screen touch function is required , Determine whether a touch event has occurred :

static bool touchpad_is_pressed(void) {
    if (XPT2046_TouchDetect() == TOUCH_PRESSED)
        return true;
    return false;
}

If a touch event occurs , Then it will enter touchpad_get_xy() Function , Get touch point coordinates :

static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) {
    static XPT2046_Coordinate coord = { -1, -1, -1, -1 };
    XPT2046_Get_TouchedPoint(&xpt2046, &coord);
    (*x) = coord.x;
    (*y) = coord.y;
}

If these functions are written correctly , In theory, the input function can be realized . But before that , There is another key step :LVGL Use one tick The system manages global events , It's like LVGL My heart beats like , Without this heartbeat, events cannot be detected .

To give LVGL Provide heartbeat , Need to constantly call lv_tick_inc() function , The parameter of this function is the millisecond interval of each heartbeat :

while (1)
{
    lv_tick_inc(1);
    lv_task_handler();
    delay_ms(1);
}

It is more recommended to use the timer to complete the function call when using the single chip microcomputer , Set the timer overflow time to 1 Call it in the timer interrupt function after milliseconds .


Here is an example , It can detect whether the input device can be used normally . First, in the main The initialization of the input device is performed at the beginning of the function :

lv_port_indev_init();

Then write the following functions :

static void btn_event_cb(lv_event_t* e) {
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t* btn = lv_event_get_target(e);
    if (code == LV_EVENT_CLICKED) {
        static uint8_t cnt = 0;
        cnt++;
        lv_obj_t* label = lv_obj_get_child(btn, 0);
        lv_label_set_text_fmt(label, "Button: %d", cnt);
    }
}

void lv_example(void) {
    lv_obj_t* btn = lv_btn_create(lv_scr_act());
    lv_obj_set_pos(btn, 10, 10);
    lv_obj_set_size(btn, 120, 50);
    lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL, NULL);
    lv_obj_t* label = lv_label_create(btn);
    lv_label_set_text(label, "Button");
    lv_obj_center(label);
}

Call in main function lv_example() , Compile and download to the MCU , You can get the same button as the previous example , But after each click , The text of the button will change :

image

The rest of the content will be updated as soon as possible :http://frozencandles.fun/archives/307

Use LVGL Simulator

LVGL It's a graphics library , So when drawing graphics, it is inevitable to make some fine adjustments to the drawing results . So it is obviously a troublesome choice to download the program to the MCU for each fine-tuning , But fortunately, LVGL A simulator is provided , Can be in PC Directly generate an interactive interface on the end , You don't need to download to view the painting effect .

LVGL It can be simulated on various platforms , For a complete guide to using the simulator, please refer to https://docs.lvgl.io/master/get-started/platforms/pc-simulator.html . Next, let's say Windows The platform is based on Visual Studio As an example, this paper introduces the general use method .

First , stay https://github.com/lvgl/lv_port_win_visual_studio Download Visual Studio Engineering source . Be careful , stay LVGL.Simulator The catalog contains 3 An external warehouse , You need to download them together and put them in the right place .

then , Use Visual Studio open LVGL.Simulator.sln engineering , Click compile to get GUI Executable file .

image

It should be noted that ,Visual Studio The provided simulator uses C++ Compiling , If you need a custom function , You need to use... In the header file

#ifdef __cplusplus
extern "C" {
#endif
/* ... function prototypes ... */
#ifdef __cplusplus
}
#endif

Surround the function prototype , Otherwise, it is in use C There will be errors when using language symbols .

原网站

版权声明
本文为[Frozen candle]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/164/202206131121515529.html