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

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

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

​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开源基础软件社区
相关推荐

2022-04-25 17:30:00

大数据

2011-06-13 11:07:22

QT 移植

2021-12-31 10:00:30

鸿蒙HarmonyOS应用

2009-09-11 11:58:00

C# ListBox多

2024-07-31 20:39:49

前端文本JavaScrip

2020-11-18 11:56:06

鸿蒙Hi3861

2020-12-08 12:36:41

Hi3861 ADC驱动开发
点赞
收藏

51CTO技术栈公众号