2597|3

155

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【Luckfox幸狐 RV1106 Linux 开发板测评】十一、SPI驱动LCD [复制链接]

 

本人【Luckfox幸狐 RV1106 Linux 开发板测评】帖子链接:

一、开箱及测试

二、SDK获取与编译镜像

三、GPIO点灯

四、通过PC机共享网络接入Internet和Ubuntu下Python点灯

五、编译Buildroot系统并测试摄像头

六、PWM控制——命令和C方式

七、PWM控制——Python和设备树方式

八、ADC和UART测试

九、Python控制I2C驱动OLED

十、C程序控制I2C驱动OLED

 

本篇记录Luckfox Pro Max板通过SPI0驱动0.96寸TFT LCD(ST7735驱动)的实验过程,以官方提供的C代码进行验证,并以此项目为基础整合LVGL。不过,因为不是基于Linux FrameBuffer接口,而是纯以本人的MCU思维构建的以官方案例提供的LCD驱动作为底层显示接口的方式,所以最终效果不甚理想,仅作为实验参考吧。

1、官方案例验证

官方Wiki之SPI驱动LCD篇(https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-LCD),正好是采用0.96寸LCD且ST7735驱动,符合本人手中的合宙LCD扩展板。

官方案例采用的微雪Pico-LCD-0.96模块,除了屏幕还有五向开关和AB按键,而合宙LCD板只有五向开关,而且接线顺序不同,稍花功夫按着文档的接线图才做好连线。

 

 

图11-1 官方采用的微雪Pico-LCD-0.96

 

 

图11-2 本人采用的合宙0.96寸扩展板

 

 

图11-3 Pro Max和合宙扩展板的最终连线(PA_1~PB_11对应扩展板五向开关)

 

官方提供了测试案例,压缩包中包含不同开发板的项目,这里选择Luckfox_Pico_ProMax目录,其中有程序案例(c文件夹)和设备树文件。

 

 

图11-4 官方案例中的项目和设备树文件

 

首先是需要将设备树文件拷贝到虚拟机中,替换<SDK目录>/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-pro-max.dts,然后回到Luckfox SDK根目录,进行系统镜像编译,即:./build.sh lunch --> ProMax板需要选择8 --> ./build.sh。

将编译后的系统镜像重新下载到开发板中,此时开发板开启了SPI0,以及其它控制LCD用的GPIO(除了SCK和SDA外,其它9个信号都通过GPIO控制,因为官方案例还要驱动AB键,所以实际用到了11个GPIO)。

 

 

图11-5 更新系统后开发板开启的GPIO

 

然后就是将官方案例拷贝到虚拟机中,整个项目比较完善可以测试多款LCD(当然都是微雪家的),也只需要修改Makefile中的CC赋值为Luckfox SDK中的工具链即可。修改后就是make,然后项目根目录生成可执行文件main,接着就是下载本机再adb push到开发板,chmod赋执行权限,最后:“./demo 0.96”进行验证——表示执行0.96寸屏Demo。注:因为Demo有显示图片的功能,所以需要将项目的pic目录也推送到开发板。

 

图11-6 官方LCD测试项目结构

 

 

图11-7 官方LCD测试项目的Makefile修改

 

 

图11-8 至少把pic目录和执行文件main一起推送开发板

 

2、案例项目直接整合LVGL

Linux环境下搞LVGL,当然推荐采用FB接口——无论是LVGL官方的移植案例还是Luckfox官方案例都是如此。不过本人前一段时间刚做过ESP32上的LVGL移植,所以忍不住用MCU的思想搞了一下移植测试。

整合项目的初始阶段,本人计划是修改原案例Makefile,添加LVGL的编译内容,但是LVGL项目结构明显更复杂,再加上自己Makefile不熟悉,搞了一上午也没有成功。于是转向采用lv_port_linux_frame_buffer(LVGL官方提供的Linux移植版本)的Makefile为基础整合Luckfox的LCD案例的方式。

首先,虚拟机中重新拷贝一份Luckfox LCD案例中的“c”文件夹并重命名为pico_lvgl,将examples/main.c移动到根目录。同时,新建文件夹pico_lvgl/src,把examples和lib目录移到src目录下。

接着,在pico_lvgl目录下,执行命令:http://git clone -b v8.1.0 https://github.com/lvgl/lvgl.git,克隆一份LVGL 8.1版源码。拷贝lvgl/lv_conf_template.h到pico_lvgl根目录并重命名为“lv_conf.h”,同时修改其中的“#if 0”为“#if 1”即使能LVGL的各个配置项——这里没有对配置项做修改。

然后,修改pico_lvgl/Makefile,即根目录下的主Makefile。其中代码以lv_port_linux_frame_buffer项目的Makefile为主稍作修改(增加Luckfox案例的编译规则等)。Makefile代码如下,中文注释部分是添加的内容。

#
# Makefile
#

# 请根据实际情况修改gcc路径
CC            = ~/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-gcc
LVGL_DIR_NAME ?= lvgl
LVGL_DIR      ?= .

WARNINGS   := -Wall -Wshadow -Wundef -Wmissing-prototypes -Wno-discarded-qualifiers -Wall -Wextra -Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith \
          -fno-strict-aliasing -Wno-error=cpp -Wuninitialized -Wmaybe-uninitialized -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess \
          -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic \
          -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion -Wclobbered -Wdeprecated -Wempty-body -Wtype-limits -Wshift-negative-value -Wstack-usage=2048 \
          -Wno-unused-value -Wno-unused-parameter -Wno-missing-field-initializers -Wuninitialized -Wmaybe-uninitialized -Wall -Wextra -Wno-unused-parameter \
          -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wpointer-arith -Wno-cast-qual -Wmissing-prototypes \
          -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wno-discarded-qualifiers -Wformat-security -Wno-ignored-qualifiers -Wno-sign-compare -std=c99
CFLAGS      ?= -O3 -g0 -I$(LVGL_DIR)/ $(WARNINGS)
# Pico LCD驱动相关头文件路径
CFLAGS      += -I$(LVGL_DIR)/src/examples -I$(LVGL_DIR)/src/lib/Config -I$(LVGL_DIR)/src/lib/Fonts -I$(LVGL_DIR)/src/lib/GUI -I$(LVGL_DIR)/src/lib/LCD
LDFLAGS     ?= -lm
BIN          = demo
BUILD_DIR     = ./build
BUILD_OBJ_DIR = $(BUILD_DIR)/obj
BUILD_BIN_DIR = $(BUILD_DIR)/bin

prefix      ?= /usr
bindir      ?= $(prefix)/bin

#Collect the files to compile
MAINSRC      = ./main.c
# Pico LCD驱动相关.c文件
DRVSRC       = $(shell find -L $(LVGL_DIR)/src -name \*.c)

include $(LVGL_DIR)/lvgl/lvgl.mk

OBJEXT      ?= .o

AOBJS        = $(ASRCS:.S=$(OBJEXT))
COBJS        = $(CSRCS:.c=$(OBJEXT))
MAINOBJ      = $(MAINSRC:.c=$(OBJEXT))
# Pico LCD驱动相关.o文件
DRVOBJ       = $(DRVSRC:.c=$(OBJEXT))

SRCS         = $(ASRCS) $(CSRCS) $(MAINSRC) $(DRVSRC)
OBJS         = $(AOBJS) $(COBJS) $(MAINOBJ) $(DRVOBJ)
TARGET       = $(addprefix $(BUILD_OBJ_DIR)/, $(patsubst ./%, %, $(OBJS)))

## MAINOBJ -> OBJFILES

all: default

$(BUILD_OBJ_DIR)/%.o: %.c
	@mkdir -p $(dir $@)
	@$(CC)  $(CFLAGS) -c $< -o $@
	[url=home.php?mod=space&uid=43340]@echo[/url] "CC $<"

default: $(TARGET)
	@mkdir -p $(dir $(BUILD_BIN_DIR)/)
	$(CC) -o $(BUILD_BIN_DIR)/$(BIN) $(TARGET) $(LDFLAGS)

clean:
	rm -rf $(BUILD_DIR)

install:
	install -d $(DESTDIR)$(bindir)
	install $(BUILD_BIN_DIR)/$(BIN) $(DESTDIR)$(bindir)

uninstall:
	$(RM) -r $(addprefix $(DESTDIR)$(bindir)/,$(BIN))

# 测试Makefile变量规则
show:
	echo $(CFLAGS)

 

最后,修改pico_lvgl/main.c,即添加LVGL的测试代码——屏幕中间显示一行文本。main.c的代码如下:

#include "DEV_Config.h"
#include "Pico_LCD_0in96.h"
#include "GUI_Paint.h"
#include "GUI_BMP.h"

#include "lvgl/lvgl.h"
#include <signal.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>

// 定义屏幕尺寸
const uint16_t screenWidth  = PICO_LCD_0IN96_WIDTH;
const uint16_t screenHeight = PICO_LCD_0IN96_HEIGHT;
// lvgl专用的显示缓存区定义
lv_disp_draw_buf_t draw_buf;
lv_color_t buf[ PICO_LCD_0IN96_WIDTH * PICO_LCD_0IN96_HEIGHT / 10 ];
// 自定义的显示刷新接口
void my_disp_flush( lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p )
{
// 调用Pico驱动提供的API有Bug
//   PICO_LCD_0IN96_ClearWindow(area->x1, area->y1, area->x2, area->y2, (uint16_t*)color_p);
// 依据LVGL文档逐像素点刷新,很慢
  uint16_t * buf16 = (uint16_t *)&color_p->full; /*Let's say it's a 16 bit (RGB565) display*/
  int32_t x, y;
  for(y = area->y1; y <= area->y2; y++) {
    for(x = area->x1; x <= area->x2; x++) {
      PICO_LCD_0IN96_DrawPaint(x, y, *buf16);
      buf16++;
    }
  }

  lv_disp_flush_ready( disp_drv );
}

int main(int argc, char *argv[]) {
// LVGL初始化
  lv_init();

    // Exception handling:ctrl + c
    signal(SIGINT, Handler_0IN96_LCD);
    /* Module Init */
    if(DEV_ModuleInit() != 0){
        DEV_ModuleExit();
        exit(0);
    }

    /* LCD Init */
    printf("0.96inch LCD demo...\r\n");
    PICO_LCD_0IN96_Init();
    PICO_LCD_0IN96_Clear(WHITE);

// 显示缓存区初始化
  lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth*screenHeight/10);
// 显示初始化
  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init( &disp_drv );
// 横屏设置尺寸
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register( &disp_drv );

  lv_obj_t *label = lv_label_create(lv_scr_act());
  lv_label_set_text(label, "Hello Luckfox LVGL!");
  lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);

  /*Handle LVGL tasks*/
  while(1) {
    lv_timer_handler();
    usleep(5000);
  }

  return 0;
}

 

整合后的项目本人push到Gitee上,有感兴趣的朋友可以下载,因为需要再链接LVGL库(链接地址也是Fork到Gitee上的版本),需要使用命令如下:

git clone --recursive https://gitee.com/sonicfirr/pico_lvgl.git

整个项目还有一个问题就是刷新率非常低,以致没有实用价值。具体原因也没有找到,猜想可能跟编写的LVGL显示回调(my_disp_flush函数)性能不佳有关。由此,也没有做LVGL的输入测试,下一步还是直接采用Linux的FrameBuffer接口——关键官方也给了案例可以参考哈!

 

图11-9 lvgl_pico项目结构

 

最新回复

好的,直接看设备树参考文档,好方法   详情 回复 发表于 2024-2-18 22:26
点赞 关注
 
 

回复
举报

365

帖子

0

TA的资源

版主

沙发
 

我手上有两个spi的屏幕,没资料了可惜了,也不是通用,要不然也可以试试

点评

也是实验中刚学到的:<Luckfox SDK>/sysdrv/source/kernel/Documentation/devicetree/bindings/display,这个路径下有支持的屏幕驱动的说明文档,你可以看看有没有符合自己的。  详情 回复 发表于 2024-2-18 19:32
 
 
 

回复

155

帖子

1

TA的资源

一粒金砂(高级)

板凳
 
LitchiCheng 发表于 2024-2-17 16:21 我手上有两个spi的屏幕,没资料了可惜了,也不是通用,要不然也可以试试

也是实验中刚学到的:<Luckfox SDK>/sysdrv/source/kernel/Documentation/devicetree/bindings/display,这个路径下有支持的屏幕驱动的说明文档,你可以看看有没有符合自己的。

点评

好的,直接看设备树参考文档,好方法  详情 回复 发表于 2024-2-18 22:26
 
 
 

回复

365

帖子

0

TA的资源

版主

4
 
sonicfirr 发表于 2024-2-18 19:32 也是实验中刚学到的:<Luckfox SDK>/sysdrv/source/kernel/Documentation/devicetree/bindings/displ ...

好的,直接看设备树参考文档,好方法

 
 
 

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

随便看看
查找数据手册?

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
快速回复 返回顶部 返回列表