【RV1106】基于LVGL的ST7735S驱动移植与图像显示实战

张开发
2026/4/10 11:29:23 15 分钟阅读

分享文章

【RV1106】基于LVGL的ST7735S驱动移植与图像显示实战
1. RV1106开发板与ST7735S屏幕的硬件连接在开始驱动移植之前我们需要先了解硬件连接的基本原理。RV1106开发板的SPI接口与ST7735S屏幕的引脚对应关系是项目成功的关键。根据我的实际项目经验很多初学者最容易犯的错误就是引脚连接不正确。ST7735S是一款常见的1.8寸SPI接口LCD屏幕分辨率为128x160。它需要以下关键信号线SCLSPI时钟线SDASPI数据线CS片选信号DC数据/命令选择RES复位信号BL背光控制在Luckfox RV1106开发板上我建议使用SPI0接口进行连接。具体引脚对应关系如下SPI0_CLK → LCD_SCLSPI0_MOSI → LCD_SDAGPIO1_PC3 → LCD_CSGPIO1_PD0 → LCD_DCGPIO1_PD1 → LCD_RESGPIO2_PB0 → LCD_BL这里有个特别需要注意的地方ST7735S的背光控制(BL)引脚需要特别注意电平逻辑。有些屏幕是低电平点亮背光有些则是高电平点亮。我在项目中遇到过因为背光极性设置错误导致屏幕不亮的问题调试了整整一天才发现是这个原因。2. 设备树配置与驱动修改设备树配置是Linux驱动开发中最关键的环节之一。对于RV1106开发板我们需要修改两个关键文件rv1106g-luckfox-pico-pro-max.dts和rv1106-luckfox-pico-pro-max-ipc.dtsi。2.1 基础设备树配置首先在rv1106g-luckfox-pico-pro-max.dts中添加背光控制节点backlight:backlight { compatible gpio-backlight; pinctrl-names default; pinctrl-0 gpio2_pb0; gpios gpio2 RK_PB0 GPIO_ACTIVE_HIGH; default-on; };然后配置SPI0控制器spi0 { status okay; pinctrl-names default; pinctrl-0 spi0m0_cs0 spi0m0_pins; #address-cells 1; #size-cells 0; spidev0 { status disabled; compatible rockchip,spidev; spi-max-frequency 1000000000; reg 0; }; };2.2 ST7735S驱动配置在rv1106-luckfox-pico-pro-max-ipc.dtsi中修改fbtft节点fbtft0 { status okay; compatible sitronix,st7735r; // 使用st7735r驱动兼容st7735s reg 0; spi-max-frequency 48000000; spi-cpol; spi-cpha; rotate 0; fps 30; rgb; buswidth 8; dc gpio1 RK_PD0 GPIO_ACTIVE_HIGH; reset gpio1 RK_PD1 GPIO_ACTIVE_LOW; debug 0x1; };这里有个重要的经验分享官方内核自带的fbtft驱动可能不完全兼容ST7735S但ST7735R驱动可以完美兼容。我在实际项目中测试发现直接使用st7735r驱动可以避免很多兼容性问题。3. 内核驱动编译与配置要让驱动正常工作我们需要正确配置内核选项并编译内核模块。3.1 内核配置修改修改luckfox_rv1106_linux_defconfig文件添加以下配置CONFIG_BACKLIGHT_GPIOy CONFIG_FB_TFT_ST7735Ry CONFIG_SPI_MASTERy CONFIG_FBy3.2 fbtft驱动修改由于内核版本差异可能需要修改fbtft-core.c文件。主要修改包括添加头文件#include linux/gpio.h #include linux/of_gpio.h修改fbtft_request_one_gpio函数static int fbtft_request_one_gpio(struct fbtft_par *par, const char *name, int index, struct gpio_desc **gpiop) { // 详细实现参考完整代码 flags (of_flags OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; }修改fbtft_reset函数static void fbtft_reset(struct fbtft_par *par) { // 详细实现参考完整代码 gpiod_set_value_cansleep(par-gpio.cs, 0); /* Activate chip */ }这些修改主要是为了正确处理GPIO的激活电平和芯片选择信号。我在实际项目中遇到过因为CS信号处理不当导致屏幕无法正常工作的问题。4. LVGL环境搭建与配置LVGL是一个轻量级的嵌入式图形库非常适合在资源有限的嵌入式设备上使用。4.1 获取LVGL源代码在Ubuntu系统中创建工程目录并获取源代码mkdir -p ~/lvgl_project cd ~/lvgl_project git clone -b v8.1.0 https://github.com/lvgl/lvgl.git git clone -b v8.1.0 https://github.com/lvgl/lv_drivers.git git clone -b v8.1.0 https://github.com/lvgl/lv_demos.git git clone --branch release/v8.2 --single-branch https://github.com/lvgl/lv_port_linux_frame_buffer.git4.2 工程配置创建项目目录并复制必要文件mkdir -p ~/lvgl_project/project_01 cd ~/lvgl_project/project_01 cp -r ~/lvgl_project/lvgl/lvgl ./ cp -r ~/lvgl_project/lvgl/lv_drivers ./ cp ~/lvgl_project/lvgl/lvgl/lv_conf_template.h ./lv_conf.h cp ~/lvgl_project/lvgl/lv_drivers/lv_drv_conf_template.h ./lv_drv_conf.h cp ~/lvgl_project/lv_demos/lv_demo_conf_template.h ./lv_demo_conf.h cp -r ~/lvgl_project/lv_demos ./ cp ~/lvgl_project/lv_port_linux_frame_buffer/main.c ./ cp ~/lvgl_project/lv_port_linux_frame_buffer/Makefile ./4.3 关键配置修改lv_conf.h中的关键修改#define LV_MEM_SIZE (32U * 1024) // 根据设备内存调整 #define LV_DISP_DEF_REFR_PERIOD 30 // 刷新周期 #define LV_INDEV_DEF_READ_PERIOD 30 // 输入设备读取周期 #define LV_USE_LOG 0 // 关闭日志输出lv_drv_conf.h中的关键修改#define USE_FBDEV 1 // 启用framebuffer设备支持5. 图片显示实现与优化5.1 图片转换与集成要在LVGL中显示图片需要先将图片转换为C数组格式。可以使用在线工具如Online Image Converter选择图片并上传输出格式选择C array颜色格式选择CF_TRUE_COLORJPG或CF_TRUE_COLOR_ALPHAPNG下载生成的.c文件并添加到工程中5.2 主程序实现修改main.c实现图片显示#include lvgl/lvgl.h #include lv_drivers/display/fbdev.h #include unistd.h LV_IMG_DECLARE(fll); // 声明外部图片 int main(void) { lv_init(); fbdev_init(); static lv_color_t buf[128 * 160]; // 显示缓冲区 static lv_disp_draw_buf_t disp_buf; lv_disp_draw_buf_init(disp_buf, buf, NULL, 128 * 160); static lv_disp_drv_t disp_drv; lv_disp_drv_init(disp_drv); disp_drv.draw_buf disp_buf; disp_drv.flush_cb fbdev_flush; disp_drv.hor_res 128; disp_drv.ver_res 160; lv_disp_drv_register(disp_drv); lv_obj_t * img1 lv_img_create(lv_scr_act()); lv_img_set_src(img1, fll); lv_obj_align(img1, LV_ALIGN_CENTER, 0, 0); while(1) { lv_timer_handler(); usleep(5000); } return 0; }5.3 性能优化技巧在实际项目中我发现以下几个优化点可以显著提高显示性能使用双缓冲机制减少闪烁根据屏幕分辨率合理设置LVGL的缓冲区大小调整SPI时钟频率到最高稳定值关闭不必要的调试输出使用硬件加速功能如果支持6. 常见问题与解决方案在项目开发过程中我遇到了不少问题这里分享几个典型的案例6.1 屏幕无显示可能原因及解决方案背光未开启检查背光控制引脚电平和极性SPI通信失败用逻辑分析仪检查SPI信号复位时序不正确确保复位信号满足时序要求电源问题检查屏幕供电电压是否稳定6.2 显示花屏可能原因SPI时钟频率过高数据位序设置错误显存与屏幕分辨率不匹配颜色格式设置错误6.3 LVGL运行卡顿优化建议减少同时显示的控件数量使用更简单的图片格式优化刷新策略检查内存是否充足7. 项目部署与测试完成开发后需要将程序部署到开发板上进行测试。7.1 交叉编译使用RV1106的工具链进行交叉编译export CC/path/to/toolchain/bin/arm-rockchip830-linux-uclibcgnueabihf-gcc make7.2 文件传输将编译好的demo程序传输到开发板scp demo root开发板IP:/root/7.3 运行测试在开发板上运行程序chmod x demo ./demo如果一切正常你应该能在屏幕上看到显示的图片。如果遇到权限问题可能需要修改/dev/fb0的设备权限。

更多文章