Skip to main content

连接 RGB 显示屏

难度等级 ★☆☆☆☆
章节提示

本文讲述了如何连接 40Pin RGB 显示屏,并向 fb 设备刷新图像并显示到屏幕上

引言

术语引用表

术语对应解释
fbFrame Buffer
DPIDisplay Parallel Interface
VOPVideo Output Processor
dtbDevice Tree Binary
dtboDTB Overlay
  1. VOP 是 Rockchip 的视频输出模块,负责简单平面叠加、填充、光标、Alpha Blend 等基础 2D 图形功能。

摘要

在我们的圈子里面一直流传着一句金句: 有屏的地方就有坏苹果
年轻人不想来点个屏看看?

选择屏幕型号

Sakura Pi RK3308B 有一个 40Pin 的标准 DPI 接口。
目前我们测试过能用的屏如下表所示,你可以根据自己需要自由选择。由于屏幕多种多样并不能全部收录,所以仅供参考。 一般来说,IPS 面板的屏幕比 TFT 的显示效果更好。

warning

由于体积的限制,板上的背光驱动能力有限,导致无法驱动较大尺寸或较高背光功耗的屏幕。 必要情况下(如遇到画面闪烁、不亮等),请使用外置的背光供电板或更换屏幕。

型号尺寸大约价格
GL043056B0-404.3"@480x27222CNY ~ 45CNY
RFH043X4024-01(EP4307)4.3"@480X27220CNY
RFH043BIVI40A027-V2(EP4306)4.3"@480X27225CNY
KD50G6-40TM-A15.0"@800x48050CNY
MD050NL42-40-12A5.0"@800x48060CNY

上电开机

按照图中屏幕的接法连接屏幕,插入电源开机。默认情况下屏幕会自动被点亮。 photo_2025-05-15_10-13-25.jpg

屏幕的识别与分辨率调整

Sakura Pi RK3308B的设备树默认的分辨率为800x480,但即使是分辨率不匹配,部分屏幕依旧可以工作,例如"RFH043BIVI40A027-V2(EP4306)",可以显示480x272区域的图像,而更大分辨率的屏幕,部分屏幕可以显示,在800x480之外的区域,会有异常的图像显示。

使用 dtbo

该 dtso 位于 Armbian 的主线仓库内,默认会随着发行版自动编译成 dtbo 并放到 /boot/dtb/rockchip/overlay 目录下。如果你想直接使用它,请在 /boot/armbianEnv.txt 的 overlays 行加入 sakurapi-rk3308b-display@480x272 即可 (如果没有这行就添加,分辨率为自己屏幕的分辨率,如果没有支持,需自行配置dtbo)

配置 dtbo

如果你需要自订 dtso,那么对于我们这个开发板需要写成下面这样。其中compatible是对应的屏幕型号。屏幕型号对应分辨率参考panel-simple.yaml或者panel-simple.c

[email protected]
/dts-v1/;
/plugin/;

/ {
fragment@0 {
target = <&display>;
__overlay__ {
compatible = "edt,etm0430g0dh6";
status = "okay";
};
};
};

向屏幕缓冲区写入数据

在shell中,可以使用以下命令向屏幕缓冲区写入随机数据

cat /dev/random > /dev/fb0

在c中,可以使用mmap映射屏幕缓冲区

display_test.c
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <stdint.h>

int main() {
int fb = open("/dev/fb0", O_RDWR);

struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
ioctl(fb, FBIOGET_VSCREENINFO, &vinfo);
ioctl(fb, FBIOGET_FSCREENINFO, &finfo);

int screensize = finfo.line_length * vinfo.yres;
uint32_t *fbp = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);

for (int y = 0; y < vinfo.yres; y++) {
for (int x = 0; x < vinfo.xres; x++) {
int loc = y * (finfo.line_length / 4) + x;
fbp[loc] = 0xFF0000FF; // 红色 RGBA: R=255, G=0, B=0, A=255
}
}

munmap(fbp, screensize);
close(fb);
return 0;
}

播放坏苹果

TODO: 需要补充