ESP32 使用 LovyanGFX 点亮1.54寸IPS全视角TFT屏幕(ST7789系列 240×240)
目录
实验效果
凌顺实验室(lingshunlab.com)在本示例中,主要运行LovyanGFX库的2_user_settiing.ino程序,对1.54寸的ST7789屏幕进行测试。
LovyanGFX 特性
LovyanGFX是一个图形库,可与 ESP32 和 SPI、I2C、8 位并联显示器/ESP8266 和 SPI 连接显示器/ATSAMD51 和 SPI 连接显示器组合使用。
目标是拥有更高的功能和更快的操作,同时保持与AdafruitGFX和TFT_eSPI的某种程度的兼容性。该库模仿AdafruitGFX和TFT_eSPI API,同时旨在实现更高的功能覆盖和性能。
与现有库相比,它具有以下优点:
- Arduino ESP32 / ESP-IDF 兼容
- 支持 16bit / 24bit 颜色模式(实际颜色数取决于显示器规格)
- 在使用 DMA 传输的通信期间执行另一个进程
- 屏幕外缓冲区(sprite)的快速旋转/缩放绘图
- 同时使用多个显示器
- 自动处理单色显示器的还原显色性
- OpenCV、SDL2可作为绘图目的地,可在PC上操作
- 可输出复合视频信号(NTSC、PAL)(仅限ESP32)
该库具有以下优点。
- 支持 Arduino ESP32 和 ESP-IDF。
- 支持 16 位和 24 位颜色模式。
- 在使用 DMA 传输的通信操作期间执行另一个进程。
- 屏幕外缓冲区(精灵)的快速旋转/扩展。
- 同时使用多个显示器。
- 单色显示器减色图自动处理。
- OpenCV、SDL2可作为绘图目标,可在PC上运行。
- 复合视频信号(NTSC、PAL)输出(仅限ESP32)
SPI | I2C | 8bit Para | 16bit Para | RGB | CVBS | |
---|---|---|---|---|---|---|
ESP32 | HW | HW | HW (I2S) | --- | --- | HW(I2SDAC) |
ESP32-S2 | HW | HW | HW (I2S) | HW (I2S) | --- | --- |
ESP32-S3 | HW | HW | HW(LCD/CAM) | HW(LCD/CAM) | HW(LCD/CAM) | --- |
ESP32-C3 | HW | HW | SW | --- | --- | --- |
ESP8266 | HW | SW | --- | --- | --- | --- |
SAMD51 | HW | HW | --- | --- | --- | --- |
SAMD21 | HW | HW | --- | --- | --- | --- |
RP2040 | HW | --- | --- | --- | --- | --- |
※ HW = HardWare Peripheral / SW = SoftWare implementation
TouchScreens | |
---|---|
ESP32 | supported |
ESP32-S2 | supported |
ESP32-S3 | supported |
ESP32-C3 | supported |
ESP8266 | supported |
SAMD51 | supported |
SAMD21 | supported |
RP2040 | --- |
支持的环境
- 平台平台
- ESP-IDF
- Arduino ESP32
- Arduino ATSAMD51(种子)
- Arduino RP2040
- 显示
- GC9107 (M5AtomS3)
- GC9A01
- GDEW0154M09 (M5Stack CoreInk)
- HX8357
- ILI9163
- ILI9225
- ILI9341 (WioTerminal, ESP-WROVER-KIT, ODROID-GO, LoLin D32 Pro, WiFiBoy Pro)
- ILI9342 (M5Stack, M5Stack Core2, ESP32-S3-BOX)
- ILI9481
- ILI9486
- ILI9488 (Makerfabs Touch with Camera)
- IT8951(M5纸)
- NT35510/OTM8009A
- R61529
- RA8875
- RM68120
- SH110x(SH1106、SH1107、M5堆叠单元OLED)
- S6D04K1
- 固态硬盘1306 (固态硬盘1309)
- SSD1327
- SSD1331
- SSD1351 (SSD1357)
- SSD1963
- ST7735 (M5StickC, TTGO T-Wristband, TTGO TS, LoLin D32 Pro, WiFiBoy mini, ESPboy, PyBadge)
- ST7789(M5StickCPlus、TTGO T-Watch、ESP-WROVER-KIT、Makerfabs MakePython、DSTIKE D-duino-32 XS)
- ST7796 (WT32-SC01)
- M5堆叠单元LCD
- M5Stack 原子显示器
- 触摸屏
- I2C FT5x06(FT5206、FT5306、FT5406、FT6206、FT6236、FT6336、FT6436)
- I2C GSLx680 (GSL1680)
- I2C GT911
- I2C NS2009
- I2C TT21xxx (TT21100)
- SPI XPT2046
- SPI STMPE610
如何配置的示例在src/lgfx_user中。
凡是与上述兼容机型命令系统相似的显示器均可支持,但官方只支持已拿到并确认可用的显示器。
我们将优先支持我们收到支持请求的模型。
setting examples is src/lgfx_user
这个库也兼容上面的模型和显示面板,具有类似的命令系统,但只有那些已经获得并确认可以工作的才被官方支持。
ST7789屏幕引脚说明
模块引脚 | 引脚说明 |
---|---|
GND | 液晶屏电源地 |
VCC | 液晶屏电源正(3.3V) |
SCL | 液晶屏SPI总线时钟信号 |
SDA | 液晶屏SPI总线写数据信号 |
RES | 液晶屏复位控制信号(低电平复位) |
DC | 液晶屏寄存器/数据选择控制信号(低电平:寄存器,高电平:数据) |
CS | 液晶屏片选控制信号(低电平使能) |
BLK | 液晶屏背光控制信号(高电平点亮,如不需要控制,请接3.3V) |
BOM
名称 | 数量 |
---|---|
ESP32 开发板 | x1 |
ST7789 1.54' | x1 |
跳线(杜邦线) | 若干 |
接线
LovyanGFX库的安装
方法一:通过Arduino IDE 2 的安装方法
1,点击Library
2,搜索框输入「LovyanGFX」
3,点击「INSTALL」进行安装
4,安装完成后,该库的名称旁边会显示「INSTALLED」
方法二:GITHUB 仓库下载安装方法
1,首先到GITHUB下载「LovyanGFX」:https://github.com/lovyan03/LovyanGFX
2,解压
3,把解压的文件放进Arduino IDE的libraries文件夹
测试代码程序
以下代码是根据接线图,适配ESP32+ST7789(240x240分辨率)的配置方式。
// welcome to www.lingshunlab.com
#include <LovyanGFX.hpp>
// 使用LovyanGFX对ESP32进行配置的例子
/// 为你自己的配置创建一个类,派生自LGFX_Device。
class LGFX : public lgfx::LGFX_Device
{
/*
该类的名称可以从 "LGFX "改为其他名称。
当与AUTODETECT一起使用时,"LGFX "已经被使用了,所以要把名字改为LGFX以外的名字。
如果同时使用多个面板,给每个面板一个不同的名字。
如果改变了类的名称,构造函数的名称也必须改成相同的名称。
命名方案可以自由决定,但万一配置的数量增加,请将构造函数的名称改为与面板的名称相同。
例如,如果你在ESP32 DevKit-C中设置了一个ILI9341 SPI连接,你可以使用
LGFX_DevKitC_SPI_ILI9341
并将文件名与类名相匹配,这样在使用时就不容易混淆了。
//*/
// 为要连接的屏幕类型准备一个实例。
//lgfx::Panel_GC9A01 _panel_instance;
//lgfx::Panel_GDEW0154M09 _panel_instance;
//lgfx::Panel_HX8357B _panel_instance;
//lgfx::Panel_HX8357D _panel_instance;
//lgfx::Panel_ILI9163 _panel_instance;
// lgfx::Panel_ILI9341 _panel_instance;
//lgfx::Panel_ILI9342 _panel_instance;
//lgfx::Panel_ILI9481 _panel_instance;
//lgfx::Panel_ILI9486 _panel_instance;
//lgfx::Panel_ILI9488 _panel_instance;
//lgfx::Panel_IT8951 _panel_instance;
//lgfx::Panel_RA8875 _panel_instance;
//lgfx::Panel_SH110x _panel_instance; // SH1106, SH1107
//lgfx::Panel_SSD1306 _panel_instance;
//lgfx::Panel_SSD1327 _panel_instance;
//lgfx::Panel_SSD1331 _panel_instance;
//lgfx::Panel_SSD1351 _panel_instance; // SSD1351, SSD1357
//lgfx::Panel_SSD1963 _panel_instance;
//lgfx::Panel_ST7735 _panel_instance;
//lgfx::Panel_ST7735S _panel_instance;
lgfx::Panel_ST7789 _panel_instance;
//lgfx::Panel_ST7796 _panel_instance;
// 为屏幕所连接的总线类型准备一个实例。
lgfx::Bus_SPI _bus_instance; // SPI
//lgfx::Bus_I2C _bus_instance; // I2C
//lgfx::Bus_Parallel8 _bus_instance; // 8 Parallel
// 如果进行背光控制,请提供一个实例。 (如果不需要则删除)。
// lgfx::Light_PWM _light_instance;
// 为触摸屏类型准备一个实例。 (如果不需要则删除)。
// lgfx::Touch_FT5x06 _touch_instance; // FT5206, FT5306, FT5406, FT6206, FT6236, FT6336, FT6436
//lgfx::Touch_GSL1680E_800x480 _touch_instance; // GSL_1680E, 1688E, 2681B, 2682B
//lgfx::Touch_GSL1680F_800x480 _touch_instance;
//lgfx::Touch_GSL1680F_480x272 _touch_instance;
//lgfx::Touch_GSLx680_320x320 _touch_instance;
//lgfx::Touch_GT911 _touch_instance;
//lgfx::Touch_STMPE610 _touch_instance;
//lgfx::Touch_TT21xxx _touch_instance; // TT21100
//lgfx::Touch_XPT2046 _touch_instance;
public:
// 创建一个构造函数并在这里配置各种设置。
// 如果你改变了类的名称,请为构造函数指定相同的名称。
LGFX(void)
{
{ // 配置总线控制设置。
auto cfg = _bus_instance.config(); // 获得总线配置的结构。
// SPI设定
cfg.spi_host = VSPI_HOST; // 选择要使用的SPI ESP32-S2,C3 : SPI2_HOST 或 SPI3_HOST / ESP32 : VSPI_HOST 或 HSPI_HOST
// * 随着ESP-IDF版本的升级,VSPI_HOST , HSPI_HOST的描述被废弃了,所以如果发生错误,请使用SPI2_HOST ,
cfg.spi_mode = 0; //设置SPI通信模式(0 ~ 3)
cfg.freq_write = 40000000; // 发送时的SPI时钟(最大80MHz,四舍五入为80MHz的整数)。
cfg.freq_read = 6000000; // 接收时的SPI时钟
cfg.spi_3wire = true; // 如果用MOSI引脚进行接收,则设置为true
cfg.use_lock = true; //如果使用交易锁则设置为true
cfg.dma_channel = 0; // 设置要使用的DMA通道(0=不使用DMA/1=1ch/2=ch/SPI_DMA_CH_AUTO=auto设置)。
// *随着ESP-IDF版本的升级,现在推荐使用SPI_DMA_CH_AUTO(自动设置)作为DMA通道,1ch和2ch被弃用。
cfg.pin_sclk = 18; // 设置SPI SCLK引脚编号
cfg.pin_mosi = 23; // 设置SPI的MOSI引脚编号
cfg.pin_miso = -1; // 设置SPI的MISO针脚编号(-1 = 禁用)。
cfg.pin_dc = 13; // 设置SPI的D/C针脚编号(-1 = 禁用)。
// 当与SD卡共同使用SPI总线时,必须无遗漏地设置MISO。
_bus_instance.config(cfg); // //反映总线上的配置值。
_panel_instance.setBus(&_bus_instance); /// 设置屏幕总线。
}
{ // 配置显示面板控制设置。
auto cfg = _panel_instance.config(); // 获取屏幕配置的结构。。
cfg.pin_cs = 5; // 连接CS的引脚编号(-1 = 禁用)。
cfg.pin_rst = 14; // 连接RST的引脚编号 (-1 = 禁用)
cfg.pin_busy = -1; // 连接BUSY的引脚编号 (-1 = 禁用)
// * 下面的设置对每个面板都有一般的默认值,如果你对某个项目不确定,可以把它注释出来并试一试。
cfg.panel_width = 240; // 实际可显示的宽度
cfg.panel_height = 240; // 实际可显示的高度
cfg.offset_x = 0; // 在屏幕的X方向上的偏移量
cfg.offset_y = 0; // 在屏幕的Y方向上的偏移量
cfg.offset_rotation = 0; // 旋转方向的偏移量为0~7(4~7为倒置)。
cfg.dummy_read_pixel = 8; // 读取像素前的假读位数量
cfg.dummy_read_bits = 1; // 读取非像素数据前的虚拟读取位数
cfg.readable = true; // 如果可以读取数据,则设置为true。
cfg.invert = true; // 设定 是否反色,有些屏幕需要设置这个值才能获取正确的颜色
cfg.rgb_order = false; // true 为 RGB false 为 BGR
cfg.dlen_16bit = false; // 如果面板在16位并行或SPI中以16位单位传输数据长度,则设置为true。
cfg.bus_shared = false; // SDカー如果与SD卡共享总线,则设置为true(总线控制由drawJpgFile等执行)。
_panel_instance.config(cfg);
}
setPanel(&_panel_instance); // 设置要使用的面板。
}
};
// 创建一个准备好的类的实例。
LGFX display;
LGFX_Sprite sprite(&display);
void setup(void)
{
// 在使用之前可以进行SPI总线和面板的初始化。
display.init();
display.setColorDepth(1);
sprite.setColorDepth(1); // RGB888的24色設定
display.setTextSize((std::max(display.width(), display.height()) + 255) >> 8);
display.fillScreen(TFT_BLACK);
}
uint32_t count = ~0;
void loop(void)
{
display.startWrite();
display.setRotation(++count & 7);
display.setColorDepth((count & 8) ? 16 : 24);
display.setTextColor(TFT_BLACK);
display.drawNumber(display.getRotation(), 16, 0);
display.setTextColor(0xFF0000U);
display.drawString("R", 25, 16);
display.setTextColor(0x00FF00U);
display.drawString("G", 32, 16);
display.setTextColor(0x0000FFU);
display.drawString("B", 39, 16);
display.setTextColor(0x0467FFU);
display.drawString("LingShunLAB.com !", 25, 3);
display.drawRect(30,30,display.width()-60,display.height()-60,count*7);
display.drawFastHLine(0, 0, 10);
display.endWrite();
int32_t x, y;
if (display.getTouch(&x, &y)) {
display.fillRect(x-2, y-2, 5, 5, count*7);
}
}