当前位置: 首页 > news >正文

手把手教你用ST7789V驱动点亮ST7735S屏幕(Linux 5.10内核,附完整设备树配置)

手把手教你用ST7789V驱动点亮ST7735S屏幕(Linux 5.10内核,附完整设备树配置)

在嵌入式开发中,遇到屏幕驱动不完善的情况并不少见。最近我在一个项目中就碰到了这样的问题:手头有一块ST7735S屏幕,但内核中的原生驱动支持有限。经过一番探索,我发现通过修改ST7789V驱动来适配ST7735S屏幕是个不错的解决方案。这种方法不仅解决了驱动问题,还让我对Linux的FBTFT驱动框架有了更深入的理解。下面就把这个过程中的关键步骤和注意事项分享给大家。

1. 驱动适配原理与准备工作

ST7735S和ST7789V虽然属于不同系列,但它们都是基于SPI接口的小型TFT液晶屏,且寄存器结构有一定相似性。这就是为什么我们可以利用ST7789V的驱动框架来驱动ST7735S屏幕。

需要准备的环境和工具:

  • 运行Linux 5.10内核的开发板
  • 已连接好的ST7735S屏幕(SPI接口)
  • 交叉编译工具链
  • 内核源码树

提示:在开始修改前,建议先备份原始驱动文件,以便出现问题时可以快速恢复。

2. 修改ST7789V驱动文件

驱动适配的核心在于修改fb_st7789v.c文件,这个文件通常位于内核源码的drivers/staging/fbtft目录下。我们需要修改两个关键部分:初始化序列和屏幕参数定义。

2.1 调整初始化序列

ST7735S的初始化序列与ST7789V有所不同,我们需要在init_display函数中替换为正确的寄存器设置:

static int init_display(struct fbtft_par *par) { par->fbtftops.reset(par); // 硬件复位 mdelay(50); write_reg(par, 0x11); // 软件复位 mdelay(100); // ST7735S帧率控制 write_reg(par, 0xB1, 0x05, 0x3C, 0x3C); write_reg(par, 0xB2, 0x05, 0x3C, 0x3C); write_reg(par, 0xB3, 0x05, 0x3C, 0x3C, 0x05, 0x3C, 0x3C); // 电源控制序列 write_reg(par, 0xC0, 0x28, 0x08, 0x04); write_reg(par, 0xC1, 0xC0); write_reg(par, 0xC2, 0x0D, 0x00); write_reg(par, 0xC3, 0x8D, 0x2A); // VCOM设置 write_reg(par, 0xC4, 0x8D, 0xEE); // MX, MY, RGB模式 // Gamma校正设置 write_reg(par, 0xE0, 0x04, 0x22, 0x07, 0x0A, 0x2E, 0x30, 0x25, 0x2A, 0x28, 0x26, 0x2E, 0x3A, 0x00, 0x01, 0x03, 0x13); write_reg(par, 0xE1, 0x04, 0x16, 0x06, 0x0D, 0x2D, 0x26, 0x23, 0x27, 0x27, 0x25, 0x2D, 0x3B, 0x00, 0x01, 0x04, 0x13); write_reg(par, 0x3A, 0x05); // 65K色彩模式 write_reg(par, 0x29); // 开启显示 mdelay(100); return 0; }

2.2 修改屏幕参数结构体

接下来需要调整fbtft_display结构体中的屏幕参数,确保它们与ST7735S的实际规格匹配:

static struct fbtft_display display = { .regwidth = 8, .width = 128, // ST7735S的实际宽度 .height = 160, // ST7735S的实际高度 .gamma_num = 2, .gamma_len = 14, .gamma = HSD20_IPS_GAMMA, .fbtftops = { .init_display = init_display, .set_var = set_var, .set_gamma = set_gamma, .blank = blank, }, };

注意:对于ST7735S屏幕,可能需要注释掉set_gamma函数中的for循环部分,具体取决于屏幕型号和版本。

3. 设备树配置详解

正确的设备树配置是驱动能够正常工作的关键。下面是一个完整的SPI屏幕节点配置示例:

&spi0 { status = "okay"; st7789v@0 { status = "okay"; compatible = "sitronix,st7789v"; reg = <0>; spi-max-frequency = <48000000>; // SPI时钟频率 rotate = <90>; // 屏幕旋转角度 spi-cpol; // SPI时钟极性 spi-cpha; // SPI时钟相位 rgb; // 颜色格式为RGB fps = <30>; // 刷新率 buswidth = <8>; // 数据总线宽度 dc-gpios = <&pio 1 6 GPIO_ACTIVE_LOW>; // 数据/命令选择引脚 reset-gpios = <&pio 1 5 GPIO_ACTIVE_LOW>; // 复位引脚 debug = <0>; // 调试信息关闭 }; };

关键参数说明:

参数说明典型值
spi-max-frequencySPI通信最大频率48000000 (48MHz)
rotate屏幕旋转角度0, 90, 180, 270
fps屏幕刷新率30-60
dc-gpios数据/命令选择引脚根据硬件连接确定
reset-gpios复位控制引脚根据硬件连接确定

4. 内核配置与编译

完成驱动修改后,需要配置内核以包含我们修改后的FBTFT驱动:

  1. 进入内核配置界面:
make ARCH=arm menuconfig
  1. 确保以下选项已启用:

    • Device Drivers → Staging drivers → Support for small TFT LCD display modules → FB driver for ST7789V displays
  2. 编译内核和设备树:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs
  1. 安装模块(如果需要):
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=out modules_install

5. 测试与验证

将编译好的内核和设备树文件部署到开发板后,可以通过以下方法测试屏幕是否正常工作:

  1. 检查设备节点:
ls /dev/fb*
  1. 显示测试图案:
cat /dev/urandom > /dev/fb0

如果屏幕出现随机噪点(雪花效果),说明驱动已成功加载。

  1. 启用控制台显示(可选): 修改u-boot环境变量,添加console=tty0参数:
setenv bootargs "console=tty0 console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 earlyprintk rw vt.global_cursor_default=0" saveenv

6. 常见问题排查

在实际操作中可能会遇到各种问题,这里列出几个常见问题及解决方法:

问题1:屏幕无任何反应

  • 检查电源连接是否正常
  • 确认SPI总线是否已启用(检查/dev/spidev*是否存在)
  • 验证复位信号是否正确

问题2:显示内容错乱

  • 检查屏幕旋转参数是否正确
  • 确认SPI时钟极性和相位设置(spi-cpol/spi-cpha)
  • 验证色彩模式设置(rgb参数)

问题3:显示颜色异常

  • 检查Gamma校正设置
  • 确认色彩深度设置(65K色模式)
  • 验证初始化序列中的色彩相关寄存器

7. 性能优化技巧

为了让屏幕表现更好,可以考虑以下优化措施:

  1. 调整SPI时钟频率

    • 逐步提高spi-max-frequency值,直到出现显示异常,然后回退到稳定值
    • 典型值在30-50MHz之间
  2. 优化刷新率

    • 适当提高fps值,但要注意CPU负载
    • 对于静态内容,可以降低刷新率以节省功耗
  3. 使用DMA传输

    • 在内核配置中启用SPI DMA支持
    • 可以减少CPU占用,提高整体性能
  4. 双缓冲技术

    • 实现帧缓冲的双缓冲切换
    • 可以避免屏幕刷新时的撕裂现象

通过这次ST7789V驱动适配ST7735S屏幕的经历,我深刻体会到Linux驱动框架的灵活性。虽然过程有些曲折,但最终能够看到屏幕正常点亮的那一刻,所有的努力都值得了。建议大家在修改驱动时保持耐心,仔细对照数据手册检查每个寄存器设置,这样能少走很多弯路。

http://www.jsqmd.com/news/668023/

相关文章:

  • 如何用嘎嘎降AI同时处理多篇论文:批量操作效率提升教程
  • 保姆级教程:在ARM服务器上配置GICv3虚拟中断,手把手教你玩转List寄存器
  • 如何创建包含ROWID的物化视图日志_WITH ROWID参数支持复杂关联视图的刷新
  • FPGA--Verilog 实现乒乓操作:从原理到工程实践(附完整代码)
  • WPF—Style样式
  • CREST:分子构象采样的终极指南,快速探索化学空间
  • STM32 FSMC驱动TFTLCD:从点阵到任意尺寸字体的高效显示方案
  • Windows 10专业版用户必看:用组策略彻底关掉Defender的保姆级教程(附防篡改设置)
  • mysql数据量过亿时索引如何优化_mysql分库分表索引设计
  • 联想小新Air14 AMD版装Ubuntu 20.04,升级内核到5.11解决触控板和亮度问题(附详细步骤)
  • Bootstrap Gutters间距用法 Bootstrap 5中g-,gx-,gy--如何使用
  • 2026届最火的五大降重复率助手推荐
  • Nacos2.x核心源码深度剖析:从通信到业务
  • 股票行情核心指标与形态解析
  • winodws下cpolar 公网穿透保姆级安装使用教程
  • 2026电压力锅哪个牌子质量好?高口碑品牌推荐 - 品牌排行榜
  • 告别虚拟机!在Win11的WSL2里从源码编译安装Madagascar(保姆级避坑指南)
  • Nexys A7 实战入门:从流水灯到硬件描述语言
  • Chrome DevTools MCP:让 AI 编码助手拥有浏览器调试超能力
  • 2026最权威的十大降重复率助手推荐
  • 从共享单车需求预测看ST-Norm:为什么你的时序模型总忽略局部特征?
  • 告别Three.js!用3Dmol.js在Web端5分钟搞定分子3D可视化(附完整代码)
  • java的学习之路
  • Rust的匹配中的进展编译器
  • HDMI 2.1高速信号PCB设计避坑指南:从4层板布线到SI仿真验证
  • 告别ArcGIS依赖:用Python+GDAL的OpenFileGDB驱动,5分钟搞定GDB数据读取
  • OriginPro 2023保姆级教程:用自带示例数据5步搞定带正态分布曲线的多因子分组箱线图
  • 从RobotStudio到Eigen库:手把手教你用C++验证ABB机器人正逆解(IRB 1600-6/1.45型号)
  • COMSOL模拟环偶极子增强磁光克尔效应
  • 从‘有状态’到实战:用iptables为你的Ubuntu服务器打造企业级安全策略