背景
在我们使用树莓派做开发的时候,有些场景下需要屏幕显示,可以选择HDMI屏幕,也可以选择SPI接口的屏幕。HDMI屏幕驱动简单,即插即用,但是成本高,相比较SPI屏幕硬件成本低,GPIO插座连接方便,安装好相应的驱动,使用起来性价比最高。
我是在使用zero制作游戏掌机retropie过程中学习和实现了SPI TFT驱动,现在记录下来,希望给喜欢折腾的童鞋们参考。
树莓派SPI接口介绍
树莓派40 pin GPIO接口中有硬件的SPI接口(19,21,23,24),我们可以用来连接SPI TFT屏幕,我手里一块2.8寸ili9341驱动的TFT屏幕。
fbtft驱动应用
fbtft驱动使用的是SPI硬件资源进行显示framebuffer输出,稳定但是FPS相对偏低,因为树莓派本身SPI的频率限制在30Mhz左右,驱动效果大约20fps左右,所以用来显示静态图片或者适用刷新率不高的场合。
参考Git教程https://github.com/goodtft/LCD-show
1.raspberry官方镜像在2021/11后的版本默认自带fbtft驱动了,但是需要手动开启加载
2.检查/boot/overlays/,如果没有,复制进去fbtft.dtbo(文件会放文章末尾)
3.检查/etc/modules 是否有以下模块,没有的话添加进去
spi-bcm2835
flexfb
fbtft_device
4.添加自启动配置,在boot config文件配置/boot/config.txt增加以下行加载TFT驱动,相同的配置不需要重复添加,需要确定TFT屏幕的正确的reset pin, dc pin,不然点不亮
hdmi_force_hotplug=1
dtparam=i2c_arm=on
dtparam=spi=on
enable_uart=1
dtoverlay=fbtft,spi0-0,ili9341,reset_pin=27,dc_pin=22,rotate=270,fps=15,speed=32000000,txbuflen=32768
hdmi_group=2
hdmi_mode=1
hdmi_mode=87
hdmi_cvt 480 360 60 6 0 0 0
hdmi_drive=2
5.所有设置好后,重启后,所连接的TFT屏幕会先黑一下,说明驱动成功了,
如果接着没有正确显示正常UI界面,那么需要安装fbcp来映射display framebuffer
1.安装rpi-fbcp
sudo git clone https://github.com/tasanakorn/rpi-fbcpsudo
mkdir ./rpi-fbcp/build
cd ./rpi-fbcp/build/
sudo cmake ..
sudo make
2.测试视频输出
fbcp &
3.如果没问题,安装进系统
sudo install fbcp /usr/local/bin/fbcp
4.可以选择添加自启动,这样开机就可以作为显示器使用
在/etc/rc.local 的exit 0之前添加以下内容
sleep 7
fbcp &
fbcp-ili9341驱动应用
由于我的应用是开发游戏掌机,发现fbtft驱动掉帧严重,体验很差,于是寻找另外的方法,果然,Git的大神已经实现了SPI接口下实现60fps的驱动,只是应用起来需要一定的编程基础
参考Git链接:https://github.com/juj/fbcp-ili9341.git
这个驱动名字是fbcp-ili9341,实际作者有说支持很多驱动,不限ili9341,虽然是使用硬件SPI接口,但是没有用到SPI的驱动,所以需要清理fbtft方案的配置,最好是重新做一个干净的系统进行验证。
作者提供的安装步骤:
sudo apt-get install cmake
cd ~
git clone https://github.com/juj/fbcp-ili9341.git
cd fbcp-ili9341
mkdir build
cd build
cmake [options] ..
make -j
sudo ./fbcp-ili9341这其中[options]是一些配置选项,根据自己手里树莓派类型,以及TFT硬件进行配置,这是我用zero和2.8寸屏使用的配置
sudo cmake -DSPI_BUS_CLOCK_DIVISOR=6 -DILI9341=ON -DGPIO_TFT_DATA_CONTROL=22 -DGPIO_TFT_RESET_PIN=27 -DSINGLE_CORE_BOARD=ON -DARMV6Z=ON -DSTATISTICS=0 -DUSE_DMA_TRANSFERS=ON ..
有些不熟悉编程的童鞋到这里可能会有疑问,其实我也是研究了一段时间,各种尝试之后理解了部分配置,英语好的建议去看作者的README文档,这里我整理了部分关键的配置说明和异常处理办法。
如果运行过fbcp,要先结束进程,sudo pkill fbcp
如果/etc/rc.local
or /etc/init.d
包含启动‘fbcp &',要删除掉
参数说明:
-DILI9341=ON 定义TFT驱动型号
-DGPIO_TFT_DATA_CONTROL=22 定义TFT DC pin, 对应的是BCM pin number, 如果是3-wire SPI,值是-1
-DGPIO_TFT_RESET_PIN=27 定义TFT RESET pin, 对应BCM pin number
-DGPIO_TFT_BACKLIGHT=number 定义TFT背光pin, 对应BCM pin number,如果没有就是常亮,可以忽略
定义刷新速率,SPI_frequency = core_freq/divisor,通过-DSPI_BUS_CLOCK_DIVISOR=6和core_freq=400(/boot/config.txt)
-DSPI_BUS_CLOCK_DIVISOR=6, core_freq=400MHz
-DSTATISTICS=2 测试统计数据,0-disable,1-enabled,2-enabled,显示刷新率
-DUSE_DMA_TRANSFERS=OFF DMA传输使能
-DDMA_TX_CHANNEL=
-DDMA_RX_CHANNEL= 定义DMA传输TX,RX通道,发现有冲突的时候改变
-DDISPLAY_INVERT_COLORS=ON 反显使能
-DDISPLAY_ROTATE_180_DEGREES=ON 显示翻转使能
-DSINGLE_CORE_BOARD=ON for Zero W
-DARMV6Z=ON for Zero W
build完成后:
添加开机启动,/etc/rc.local
sleep 7
sudo /home/pi/fbcp-ili9341/build/fbcp-ili9341 &
设置SPI Diasplay分辨率,HDMI会没有显示
/boot/config.txt 增加这些内容
hdmi_group=2
hdmi_mode=87
hdmi_cvt=320 240 60 1 0 0 0
hdmi_force_hotplug=1
问题
1.如果一直白屏,检查reset pin是否正确
2.如果黑屏一下后白屏,降低刷新率,-DSPI_BUS_CLOCK_DIVISOR=8或10或更大
或者关闭使用DMA通道,-DUSE_DMA_TRANSFERS=OFF,看是否是DMA有冲突
3.显示图像后卡在那里,检查/boot/config.txt
里面不能有其他SPI设备dtoverlay
更不能有dtparam=spi=on
去打开SPI,因为此驱动不是使用的Linux内核SPI driver
4.正常使用几秒后白屏,检查/boot/config.txt
里面不能有avoid_warnings=2
或avoid_warnings=1
5.如果显示错乱,检查TFT DC pin, 应该对应连接的BCM pin number, 或者降低刷新率,-DSPI_BUS_CLOCK_DIVISOR=8或10或更大
6.颜色显示不正常,调整颜色显示-DDISPLAY_SWAP_BGR=ON
,或者设置反色-DDISPLAY_INVERT_COLORS=ON
7.分配GPU内存失败,这种情况一般是因为HDMI外接了1080P高清显示器,Pi默认GPU memory 64Mb,此驱动在DMA打开情况下使用一部分
,可以增大GPU memory,在/boot/config.txt
增加gpu_mem=128
8.最好选用四线制(MOSI,CE,DC,RST)的ILI9341 320x240 TFT,3线制(没有DC)有许多限制
总结
以上是两种不同的方案实现树莓派SPI驱动TFT屏幕,fbtft驱动使用树莓派spi接口的驱动,应用和理解起来简单一些,fbcp-ili9341驱动虽然也是SPI接口连接屏幕,但是没有使用SPI的接口,而是通过映射GPU的framebuffer,再通过DMA高速buffer输出到SPI的,实现了60hz的高刷新率,低资源占有率,性能优异。
树莓派SPI TFT相关的介绍就到这里,另一篇文章会说明整个树莓派zero制作掌机retropie的过程。
调试视频:
树莓派SPI驱动TFT游戏视频
树莓派SPI驱动TFT屏幕视频二
附件
链接:https://pan.baidu.com/s/1uhKVG5hOIbH6wt6bVHjDbQ?pwd=h94p
提取码:h94p