一、基本说明
此次使用的开发板为立创·实战派,环境为 MicroPython,屏幕驱动为 st7789-mpy。
二、屏幕显示原理
下面以一个像素为 8×8 的屏幕为例:
显示内容时对应的像素会被填充:
通过以下程序实现“F”的显示:
1 | # 定义一个列表用来存储“F”的信息 |
由于屏幕驱动的不同,所以以上代码不具有普适性,我们可以使用“#”和“ ”(空格)在终端输出验证我们的想法:
1 | # 定义一个列表用来存储“F”的信息 |
输出如下:
图片的显示也是同样的原理,每个像素显示对应的颜色就行了。
实际中,这种显示方式会带来明显的逐行扫描感,显示内容的尺寸越大越明显。比如:
解决办法是帧缓存(Frame Buffer)。
三、RGB565
在帧缓存之前,我需要再对此块屏幕进行一些说明:
此屏幕的颜色格式是 RGB565,生活中一般见到的是 RGB888,比如:
1 | # 红色:(255, 0, 0) 或者 #FF0000 |
RGB888 表示分别用三组 8 位二进制数字来表示红、绿、蓝三种颜色的大小(或者说是光强),进而组合出不同的颜色。
8 位二进制数字等同于 2 位十六进制数字,可以表示的范围是十进制的 0~255,这是容易理解的。一个二进制数字是一个比特(bit,0或1),八个比特是一个字节(byte),那么一个像素需要三个字节来存储。
同样的道理,RGB565 的红、绿、蓝分别采用 5位、6位、5 位二进制数字表示。在十进制中,它们三个各自的范围是:
- 红色:0~31
- 绿色:0~63
- 蓝色:0~31
RGB565 中一个像素需要 16(5+6+5)位二进制数字(bit),也就是需要两个字节(byte)。
下图是一个蓝色像素的例子:
四、帧缓存(Frame Buffer)
在之前我们是得到一个像素,就显示一个像素。逐像素渲染意味着每个像素的渲染和显示是串行进行的,即必须等待前一个像素渲染完成后才能开始下一个像素的渲染。这种串行处理方式会导致显著的渲染延迟。
可以想到一种“空间换时间”的策略:
内存相当于电脑的演算纸,我们可以划分出一块儿区域,让处理器把一张图(一组文字)的所有像素的信息都渲染出来,存到这一块内存。
之后内存一股脑把整块儿信息都给到屏幕,屏幕就可以一次把这些像素都显示出来,不必显示一个像素等一个像素。这其实就是帧缓存(Frame Buffer):
以一张分辨率为 50px*50px 的图片来说,它有 2500 个像素。RGB565 颜色格式下,一个像素 2 个字节,那么帧缓冲区的大小是 5000 bytes,约等于 4.8KB。
下面是一个在 MicroPython 中使用 FrameBuffer 渲染“F”的一个示例:
1 | import framebuf |
五、图片刷新测试
下面是我使用帧缓冲刷新图片的测试视频: