最近转战ESP32,ESP32-D0WDQ6
型号的GPIO只有那么20个左右,且还有几个GPIO只能做输入,非常捉襟见肘。所以如果要驱动LCD液晶屏
,绝大多数都会选择SPI接口的MCU屏
。
为了编写一个通用的ESP32-SPI-LCD驱动
,前前后后买了一小桌液晶屏,用了十几款驱动IC,说下整个过程的选型、体验、注意事项:
驱动IC的重要参数
- 像素点数(如240x320)
- 色彩深度(18Bit-262K,24Bit-16.7M)
时序、接口这类的参数都不会差太多,各厂商的寄存器定义基本都保持一致,使得后期的驱动编写有很好的兼容性。
常说的262K、xx位色是什么意思?
先明确一个概念,大家都知道屏幕的像素点是由于RGB
三种颜色构成的,而为了方便存储颜色信息,比较常用的颜色编码有 RGB888
、RGB666
、RGB565
。其中RGB888
使用8+8+8=24Bit=3Byte,RGB565
使用5+6+5=16Bit=2Byte,由于这两种可以将颜色按照完整的字节顺序排列,又不会造成存储空间的浪费,所以得到广泛使用。
262K
说的是屏幕像素为RGB666
,因为单个像素可以显示 2^18 = 262,144 种颜色,所以便叫 262K。
16.7M
的来源便是RGB888
,2^24 = 16,777,216。
RGB888
相比RGB666
,在每个像素上多出了两位,所以16.7M
的显示效果要比262K
更加细腻。
支持3/4线SPI的驱动IC型号
支持3/4线SPI的驱动IC大致有:(比较常见的)
-
ST7735(132x162,262K)支持SPI-RGB565(2字节)、SPI-RGB666(3字节)
-
ST7735S(132x162,262K)支持SPI-RGB565(2字节)、SPI-RGB666(3字节)
-
ST7789V(240x320,262K)支持SPI-RGB565(2字节)、SPI-RGB666(3字节)
-
ST7796S(320x480,262K)支持SPI-RGB565(2字节)、SPI-RGB666(3字节)
-
ILI9225(176x220,262K)支持SPI-RGB565(2字节)、SPI-RGB666(3字节)
-
ILI9341(240x320,262K)支持SPI-RGB565(2字节)、SPI-RGB666(3字节)
-
ILI9481(320x480,262K)94xx仅支持SPI-RGB666(3字节)
-
ILI9486(320x480,262K)94xx仅支持SPI-RGB666(3字节)
-
ILI9488(320x480,16.7M)94xx仅支持SPI-RGB666(3字节)
-
HX8357(320x480,16.7M)支持SPI-RGB565(2字节)、SPI-RGB666(3字节)
注意:ILI94xx用SPI写GRAM时,仅有3字节的RGB666
可用(这一点巨坑)。而同分辨率的ST7796S、HX8357 同时支持2字节的RGB565
,传输效率更高。相同SPI速率下,刷屏可节约1/3的时间。
【实际过程中快的可不止1/3。因为RGB565
正好占用2个字节,并且ESP32的内存为小端,在内存中的存储顺序与SPI发送顺序一致,可以由uint16_t指针
直接用DMA
发送,中间不需要任何格式转换。而3字节的RGB666
需要将在内存中的2字节RGB565
重新转换,既浪费计算的时间,也浪费发送的时间,还要单独腾出一块内存来存放这并不实用的RGB666
】
注意:由于上面的原因,ESP32的LCD选型非常不建议用 ILI94xx
。不仅仅是刷屏慢,也会造成后期的驱动编写不统一,费时费力。
注意:即使驱动IC支持16.7M
的24位色,用SPI接口写像素也不支持RGB888
,最大只支持到RGB666
,这好像是IC设计厂商一个约定俗成的习惯。
SPI接口写GRAM像素的时序
SPI接口 - 2字节/像素 - RGB565 传输时序:
(ILI9341数据手册配图)
SPI接口 - 3字节/像素 - RGB666 传输时序:
LCD液晶屏的寄存器功能
寄存器 | 功能 |
---|---|
0x36 | 设置扫描方向、设置RGB/BGR像素格式 |
0x3A | 设置像素格式 16/18 Bits/像素 |
0x2A 0x2B | 设置GRAM行列的写入坐标,和写入窗口的大小 |
单字节命令 | 功能 |
---|---|
0x01 | 软复位 |
0x21 | 颜色反显 |
0x11 | 退出睡眠 |
0x29 | 开启显示 |
0x2C | 写GRAM |
上述两个表格为一些常用的寄存器功能。各厂家的IC均保持一致。
电源配置、帧率配置、伽马配置 一般会有很大的不同,详见手册或者厂家例程。
其他注意事项
-
ESP32的
SPI
最大可配置CLK
为80MHz
,但必须使用IOMUX
默认的引脚。使用GPIO矩阵
任意引脚映射的方式,会令SPI
限制在30MHz
。(实际有没有80MHz不清楚,但我用60MHz的速率跑时明显比26MHz刷屏快很多) -
单片机用SPI接口刷LCD,尽量使用
2字节/像素-RGB565
的方式,相较于3字节/像素-RGB666
可以有效提高刷新速率。(ILI94xx就尽量别用SPI了,本来SPI就快不到哪去,3字节/像素更拉跨) -
STxxxx 的GRAM 有偏移量,且改变行列的扫描方向后,偏移量也会跟着改变,更可怕的是不同型号IC的偏移量也不同。而ILIxxxx则完全没有偏移量,驱动写起来更舒服。
-
ILI9481手册中,给出的PCLK最大速率为可怜的9.6MHz,实测为16MHz以上,但再往上上20MHz就上不去了,而其他的IC基本都实测过60MHz,跟其他的一比实在是慢的可怜。并且 ILI9481 在官网找不到,好像停产了,慎用。
一些感慨和吐槽:esp32的IDF开发环境,在国内MCU的SDK中绝对可以称得上是佼佼者,但选型使用起来总觉得差点意思。例如 esp32的io少又没有usb、s2没蓝牙、s3又不知何时能买到。个人感觉可以趁stm32涨价,出一波有蓝牙+USB+改进ADC
的芯片,不需要WIFI,趁机抢占低功耗/通用MCU
市场,类似nrf52832的定位。日常使用中感觉esp32就是功耗大了些、ADC不好用些、缺少IO和并口,其他功能是可以替代stm32这类通用mcu的。而阉割掉WIFI,给功耗降下来,现在价格相差那么悬殊的情况下,必定会吸引一大波低功耗+通用MCU的份额。毕竟有IDF和Arduino那么多库加持,生态才是esp32最大的优势。
ESP32开发板开源计划
现已开源一款ESP32物联网开发板,支持WIFI、蓝牙、以太网、RS485、CAN通信。板载6轴IMU、温湿度传感器、38K红外遥控收/发、独立RTC、TF卡座。USB和18650双电源供电,有2.0寸单点电容屏可用,配套各外设驱动和LVGL源码。Github、立创EDA、CSDN全云端同步更新。
详情可见:
-
ESP32-IOT-KIT 开发板介绍:
ESP32开发板开源啦 ESP32-IOT-KIT全开源物联网开发板
打样免费的时代,速去JLC白嫖PCB。
开源学习交流Q群:827686418