4

在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示

 1 year ago
source link: https://www.51cto.com/article/720505.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示

作者:Soon_L 2022-10-12 15:55:45
本文主要分享在开鸿智谷NiobeU4开发板移植lvgl经验,并实现按键按下sw4显示SW4 Pressed松开显示SW4 Release,整理踩坑经验分享如下。
45e968093482c1004321726bc2504e875c9dc3.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

本文主要分享在开鸿智谷NiobeU4开发板移植lvgl经验,并实现按键按下sw4显示SW4 Pressed松开显示SW4 Release,整理踩坑经验分享如下。

1、移植准备

开鸿智谷NiobeU4开发板Openharmony开发环境搭建参考:https://gitee.com/fangye945a/device_board_openvalley/blob/master/niobeu4/README_zh.md。

(1)lvgl源码获取

源码我选择从​​Gitee的littlevGL​​​ 镜像标签页面中下载v8.3.1 链接 ​​https://gitee.com/mirrors/lvgl/tags​​。

#打卡不停更#在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示-开源基础软件社区

下载完成将会有lvgl-v8.3.1.zip(如附件),将lvgl-v8.3.1.zip放到Ubuntu的家目录下,使用以下指令解压。

unzip lvgl-v8.3.1.zip

(2)新建demo目录并拷贝相关文件

在vendor/openvalley/niobeu4/demo/下新建目录302_lvgl,并将下载的lvgl-v8.3.1.zip解压后拷贝到目录下,
参考指令:

cd vendor/openvalley/niobeu4/demo/
cp -rf ~/lvgl-v8.3.1 ./302_lvgl

(3)拷贝LCD驱动

拷贝vendor/openvalley/niobeu4/demo/107_hdf_spi下的所有文件到vendor/openvalley/niobeu4/demo/302_lvgl下,并拷贝显示模版驱动
参考指令:

cd vendor/openvalley/niobeu4/demo/
cp -rf 107_hdf_spi/. 302_lvgl/
cp -f 302_lvgl/examples/porting/lv_port_disp_template.c 302_lvgl/lv_port_disp.c
cp -f 302_lvgl/examples/porting/lv_port_disp_template.h 302_lvgl/lv_port_disp.h

(4)拷贝配置文件

复制vendor/openvalley/niobeu4/demo/302_lvgl/lv_conf_template.h为vendor/openvalley/niobeu4/demo/302_lvgl//lv_conf.h
参考指令:

cd vendor/openvalley/niobeu4/demo/
cp -f 302_lvgl/lv_conf_template.h 302_lvgl/lv_conf.h

完成以上目录结构如图:

#打卡不停更#在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示-开源基础软件社区

2、源码修改

(1)配置make menuconfig相关信息

在vendor/openvalley/niobeu4/demo/Kconfig.liteos_m.applications最后添加。

default "302_lvgl" if NIOBEU4_APPLICATION_302

修改vendor/openvalley/niobeu4/demo/302_lvgl/.application_config如下:

config NIOBEU4_APPLICATION_302
    bool "302_lvgl"
    select DRIVERS
    select DRIVERS_HDF 
    select DRIVERS_HDF_PLATFORM
    select DRIVERS_HDF_CONFIG_MACRO
    select DRIVERS_HDF_PLATFORM_SPI
    select DRIVERS_HDF_PLATFORM_GPIO

(2)显示相关lv_port_disp文件修改

vendor/openvalley/niobeu4/demo/302_lvgl/lv_port_disp.h中。

#if 0
#if 1

DEFINES下添加lv_conf.h所在路径配置和分辨率配置。

/*********************
 *      DEFINES
 *********************/
#define LV_LVGL_H_INCLUDE_SIMPLE 1
#define MY_DISP_HOR_RES 135
#define MY_DISP_VER_RES 130

vendor/openvalley/niobeu4/demo/302_lvgl/lv_port_disp.c中。
将:

#if 0
#include "lv_port_disp_template.h"
#if 1
#include "lv_port_disp.h"
#include "st7735.h"

修改disp_init(void)加入LcdInit()。

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

修改 lv_port_disp_init(void) 注释掉Example for 2)和 Example for 3) also set disp_drv.full_refresh = 1 below对应的代码。

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_1;
    /*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);
}

修改disp_flush()函数加入lcd_draw_point();和LcdPush()。

/*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++;
            }
        }
        LcdPush();
    }
    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

(3)修改lv_tick_inc

此处修改方式与参考文件不同,此处修改如下:
在vendor/openvalley/niobeu4/demo/302_lvgl/src/hal/lv_hal_tick.c中加入LOS_Msleep(tick_period);如下:

/**
 * You have to call this function periodically
 * @param tick_period the call period of this function in milliseconds
 */
LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period)
{
    tick_irq_flag = 0;
    sys_time += tick_period;
    LOS_Msleep(tick_period);
}

(4)修改 lv_conf.h

在vendor/openvalley/niobeu4/demo/302_lvgl/lv_conf.h中.
将:

#if 0
#if 1

另外因为以下编译error。

#打卡不停更#在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示-开源基础软件社区
#define LV_USE_WIN        1
#define LV_USE_WIN        0

(5)编写测代码lvgl_example.c

可以将spi_example.c改成lvgl_example.c,也可直接新建一个lvgl_example.c文件,lvgl_example.c内容如下:

#include <math.h>
#include <stdio.h>
#include "stdint.h"
#include "los_task.h"
#include "ohos_run.h"
#include "lv_port_disp.h"
#include "lvgl.h"
#include "demos/lv_demos.h"
#include "esp_adc_cal.h"
#include "gpio_if.h":
#define PWR_SW_PIN_INDEX    2
void lv_tick_handle(UINT32 arg)
{
    printf("%s start tick\r\n", __FUNCTION__);
    while(1)
    {
        lv_tick_inc(50);
        lv_timer_handler();
    }
}
void lvgl_btn_test(void)
{
    int raw;
    UINT32 g_lv_time_task;
    TSK_INIT_PARAM_S task = { 0 };
    task.pfnTaskEntry = (TSK_ENTRY_FUNC)lv_tick_handle;
    task.pcName = "lv_time_task";
    task.uwStackSize = 0x1000;
    task.usTaskPrio = 25 - 1;
    GpioSetDir(PWR_SW_PIN_INDEX, GPIO_DIR_OUT);
    GpioWrite(PWR_SW_PIN_INDEX, 1);
    adc1_config_width(ADC_WIDTH_12Bit); 
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); 
    printf("[key_led] ADC init\n");
    lv_init();
    lv_port_disp_init();
    //lv_log_register_print_cb(lv_log_print);
    LOS_TaskCreate(&g_lv_time_task, &task);
    lv_obj_t * btn_sw4 = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/
    lv_obj_set_pos(btn_sw4, 10, 10);                            /*Set its position*/
    lv_obj_set_size(btn_sw4, 110, 25);                          /*Set its size*/
    lv_obj_t * label_sw4 = lv_label_create(btn_sw4);          /*Add a label to the button*/
    lv_obj_center(label_sw4);
    lv_obj_t * btn_sw5 = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/
    lv_obj_set_pos(btn_sw5, 10, 60);                            /*Set its position*/
    lv_obj_set_size(btn_sw5, 110, 25);                          /*Set its size*/
    lv_obj_t * label_sw5 = lv_label_create(btn_sw5);          /*Add a label to the button*/
    lv_obj_center(label_sw5);
    while(1)
    {
        LOS_Msleep(200);
        lv_task_handler();
        raw = adc1_get_raw(ADC1_CHANNEL_0); 
        //printf("[key_led] raw: %d\n", raw);
        if (raw < 100)
        {
            printf("[key_led] sw4 pressed raw: %d\n", raw); 
            lv_label_set_text(label_sw4, "SW4 Pressed");                     /*Set the labels text*/
        }
        else if (raw >2000 && raw < 3000)
        {
            printf("[key_led] sw5 pressed raw: %d\n", raw); 
            lv_label_set_text(label_sw5, "SW5 Pressed");                     /*Set the labels text*/
        } 
        else {
            lv_label_set_text(label_sw4, "SW4 Release");                     /*Set the labels text*/
            lv_label_set_text(label_sw5, "SW5 Release");                     /*Set the labels text*/
        }
    }
}
OHOS_APP_RUN(lvgl_btn_test);

(6)编写BUILD.gn

vendor/openvalley/niobeu4/demo/302_lvgl/BUILD.gn。

import("//kernel/liteos_m/liteos.gni")
assert(defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO), "Must Config LOSCFG_DRIVERS_HDF_CONFIG_MACRO in kernel/liteos_m menuconfig!")
assert(defined(LOSCFG_DRIVERS_HDF_PLATFORM_SPI), "Must Config LOSCFG_DRIVERS_HDF_PLATFORM_SPI in kernel/liteos_m menuconfig!")
module_name = get_path_info(rebase_path("."), "name")
kernel_module(module_name){
    sources = [
        "lvgl_example.c",
        "st7735s.c",
        "lv_port_disp.c",
        "src/core/lv_disp.c",
        "src/core/lv_event.c",
        "src/core/lv_group.c",
        "src/core/lv_indev_scroll.c",
        "src/core/lv_indev.c",
        "src/core/lv_obj_class.c",
        "src/core/lv_obj_draw.c",
        "src/core/lv_obj_pos.c",
        "src/core/lv_obj_scroll.c",
        "src/core/lv_obj_style_gen.c",
        "src/core/lv_obj_style.c",
        "src/core/lv_obj_tree.c",
        "src/core/lv_obj.c",
        "src/core/lv_refr.c",
        "src/core/lv_theme.c",
        "src/draw/sw/lv_draw_sw_arc.c",
        "src/draw/sw/lv_draw_sw_blend.c", 
        "src/draw/sw/lv_draw_sw_dither.c",   
        "src/draw/sw/lv_draw_sw_gradient.c",
        "src/draw/sw/lv_draw_sw_img.c",
        "src/draw/sw/lv_draw_sw_layer.c",
        "src/draw/sw/lv_draw_sw_letter.c",
        "src/draw/sw/lv_draw_sw_line.c",
        "src/draw/sw/lv_draw_sw_polygon.c",
        "src/draw/sw/lv_draw_sw_rect.c",
        "src/draw/sw/lv_draw_sw_transform.c",
        "src/draw/sw/lv_draw_sw.c",
        "src/draw/lv_draw_arc.c",
        "src/draw/lv_draw_img.c",   
        "src/draw/lv_draw_label.c",  
        "src/draw/lv_draw_layer.c",
        "src/draw/lv_draw_line.c",
        "src/draw/lv_draw_mask.c",
        "src/draw/lv_draw_rect.c",
        "src/draw/lv_draw_transform.c",
        "src/draw/lv_draw_triangle.c",
        "src/draw/lv_draw.c",
        "src/draw/lv_img_buf.c",
        "src/draw/lv_img_cache.c",
        "src/draw/lv_img_decoder.c",
        "src/font/lv_font_fmt_txt.c",
        "src/font/lv_font.c",
        "src/font/lv_font_montserrat_12.c",
        "src/font/lv_font_montserrat_14.c",
        "src/font/lv_font_montserrat_16.c",
        "src/hal/lv_hal_disp.c",
        "src/hal/lv_hal_indev.c",
        "src/hal/lv_hal_tick.c",
        "src/misc/lv_anim_timeline.c",
        "src/misc/lv_anim.c",
        "src/misc/lv_area.c",
        "src/misc/lv_async.c",
        "src/misc/lv_bidi.c",
        "src/misc/lv_color.c",
        "src/misc/lv_fs.c",
        "src/misc/lv_gc.c",
        "src/misc/lv_ll.c",
        "src/misc/lv_log.c",
        "src/misc/lv_lru.c",
        "src/misc/lv_math.c",
        "src/misc/lv_mem.c",
        "src/misc/lv_printf.c",
        "src/misc/lv_style_gen.c",
        "src/misc/lv_style.c",
        "src/misc/lv_templ.c",
        "src/misc/lv_timer.c",
        "src/misc/lv_tlsf.c",
        "src/misc/lv_txt_ap.c",
        "src/misc/lv_txt.c",
        "src/misc/lv_utils.c",
        "src/widgets/lv_arc.c",
        "src/widgets/lv_bar.c",
        "src/widgets/lv_btn.c",
        "src/widgets/lv_btnmatrix.c",
        "src/widgets/lv_canvas.c",
        "src/widgets/lv_checkbox.c",
        "src/widgets/lv_dropdown.c",
        "src/widgets/lv_img.c",
        "src/widgets/lv_label.c",
        "src/widgets/lv_line.c",
        "src/widgets/lv_objx_templ.c",
        "src/widgets/lv_roller.c",
        "src/widgets/lv_slider.c",  
        "src/widgets/lv_switch.c",           
        "src/widgets/lv_table.c", 
        "src/widgets/lv_textarea.c",
        "src/extra/themes/basic/lv_theme_basic.c",
        "src/extra/themes/default/lv_theme_default.c",
        "src/extra/themes/mono/lv_theme_mono.c",
        "src/extra/widgets/animimg/lv_animimg.c",
        "src/extra/widgets/calendar/lv_calendar_header_arrow.c",
        "src/extra/widgets/calendar/lv_calendar_header_dropdown.c",
        "src/extra/widgets/calendar/lv_calendar.c",
        "src/extra/widgets/chart/lv_chart.c",
        "src/extra/widgets/colorwheel/lv_colorwheel.c",
        "src/extra/widgets/imgbtn/lv_imgbtn.c",
        "src/extra/widgets/keyboard/lv_keyboard.c",
        "src/extra/widgets/led/lv_led.c",
        "src/extra/widgets/list/lv_list.c",
        "src/extra/widgets/menu/lv_menu.c",
        "src/extra/widgets/meter/lv_meter.c",
        "src/extra/widgets/msgbox/lv_msgbox.c",
        "src/extra/widgets/span/lv_span.c",
        "src/extra/widgets/spinbox/lv_spinbox.c",
        "src/extra/widgets/spinner/lv_spinner.c",
        "src/extra/widgets/tabview/lv_tabview.c",
        "src/extra/widgets/tileview/lv_tileview.c",
        "src/extra/widgets/win/lv_win.c",
        "src/extra/layouts/flex/lv_flex.c",
        "src/extra/layouts/grid/lv_grid.c",
        "src/extra/lv_extra.c",
        "src/extra/libs/png/lodepng.c",
        "src/extra/libs/png/lv_png.c",
        "demos/stress/lv_demo_stress.c",
    ]
    include_dirs = [
        "//drivers/hdf_core/framework/include/platform/",
        "//drivers/hdf_core/framework/include/utils/",
        "//drivers/hdf_core/framework/support/platform/include/adc",
        "//drivers/hdf_core/framework/support/platform/include/spi",
        "//drivers/hdf_core/adapter/khdf/liteos_m/osal/include/",
        "//drivers/hdf_core/framework/include/core/",
        "//drivers/hdf_core/framework/include/osal/",
        "//device/soc/esp/esp32/components/esp_adc_cal/include/",
        "//device/soc/esp/esp32/components/driver/esp32/include/",
        "/src",
        "."
    ]
}

3、编译测试

(1)编译

进入//kernel/liteos_m目录, 执行指令。

make menuconfig

在menuconfig配置中进入如下选项:(Top) → Platform → Board Selection → select board niobeu4 → use openvalley niobeu4 application → niobeu4 application choose选择 302_lvgl。

#打卡不停更#在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示-开源基础软件社区

回到sdk根目录,执行​hb build -f​脚本进行编译。编译成功如下:

(2)测试

烧录后正常开机后显示。

#打卡不停更#在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示-开源基础软件社区
按下SW4按键
#打卡不停更#在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示-开源基础软件社区

按下SW5按键。

#打卡不停更#在开鸿智谷NiobeU4移植lvgl并实现ADC按键状态显示-开源基础软件社区

移植后主要代码如附件302_lvgl.zip。

文章相关附件可以点击下面的原文链接前往下载:

https://ost.51cto.com/resource/2327。

https://ost.51cto.com/resource/2328。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 51CTO开源基础软件社区

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK