ESP32 使用TFT_eSPI 点亮1.54寸IPS全视角TFT屏幕(ST7789系列 240×240)
目录
实现效果
凌顺实验室(lingshunlab.com)在本示例中,主要运行TFT_eSPI库的TFT_graphicstest_one_lib程序,对1.54寸的ST7789屏幕进行测试。
TFT_eSPI 特性
github仓库地址:https://github.com/Bodmer/TFT_eSPI
TFT_eSPI是一个功能丰富的Arduino IDE兼容的32位处理器的图形和字体库。该库针对32位处理器,它已经为RP2040、STM32、ESP8266和ESP32类型进行了性能优化,其他32位处理器也可以使用,但会使用较慢的通用Arduino接口调用。该库可以使用Arduino IDE的库管理器加载。直接内存访问(DMA)可用于ESP32、RP2040和STM32处理器的SPI接口显示,以提高渲染性能。只有RP2040支持带有并行接口(8位和16位)的DMA。
对ESP32 S2/C3/S3的更新意味着该库需要ESP32 Arduino板包2.x.x或更高版本。
屏幕控制器、接口引脚和库的配置设置必须在库中定义。它们不能被定义在Arduino草图中。详见User_Setup_Select.h文件。这种方法有很大的优势,它使例子不受冗长的配置选项的影响,一旦设置被定义,任何例子都可以不加修改的运行。PlatformIO用户可以在platformio.ini文件中以每个项目为基础定义这些设置,见库中的Docs文件夹。
TFT_eSPI库 支持的屏幕芯片型号
- GC9A01
- ILI9163
- ILI9225
- ILI9341
- ILI9342
- ILI9481 (DMA not supported with SPI)
- ILI9486 (DMA not supported with SPI)
- ILI9488 (DMA not supported with SPI)
- HX8357B (16 bit parallel tested with RP2040)
- HX8357C (16 bit parallel tested with RP2040)
- HX8357D
- R61581
- RM68120 (support files added but untested)
- RM68140
- S6D02A1
- SSD1351
- SSD1963 (this controller only has a parallel interface option)
- ST7735
- ST7789
- ST7796
TFT_eSPI 支持的开发板和SPI类型
Processor | 4 wire SPI | 8 bit parallel | 16 bit parallel | DMA support |
---|---|---|---|---|
RP2040 | Yes | Yes | Yes | Yes (all) |
ESP32 | Yes | Yes | No | Yes (SPI only) |
ESP32 C3 | Yes | No | No | No |
ESP32 S2 | Yes | No | No | No |
ESP32 S3 | Yes | Yes | No | Yes (SPI only) |
ESP8266 | Yes | No | No | No |
STM32Fxxx | Yes | Yes | No | Yes (SPI only) |
Other | Yes | No | No | No |
凌顺实验室(lingshunlab.cpom)对本文的编辑时间为2023年3月,之后如有更新变化,请访问仓库地址进行查阅 https://github.com/Bodmer/TFT_eSPI
引脚说明
模块引脚 | 引脚说明 |
---|---|
GND | 液晶屏电源地 |
VCC | 液晶屏电源正(3.3V) |
SCL | 液晶屏SPI总线时钟信号 |
SDA | 液晶屏SPI总线写数据信号 |
RES | 液晶屏复位控制信号(低电平复位) |
DC | 液晶屏寄存器/数据选择控制信号(低电平:寄存器,高电平:数据) |
CS | 液晶屏片选控制信号(低电平使能) |
BLK | 液晶屏背光控制信号(高电平点亮,如不需要控制,请接3.3V) |
BOM
名称 | 数量 |
---|---|
ESP32 开发板 | x1 |
ST7789 1.54' | x1 |
跳线(杜邦线) | 若干 |
接线
安装库
方法一:通过Arduino IDE 2 的安装方法
1,点击Library
2,搜索框输入「TFT_eSPI」
3,点击「INSTALL」进行安装
4,安装完成后,该库的名称旁边会显示「INSTALLED」
方法二:GITHUB 仓库下载安装方法
1,首先到GITHUB下载「TFT_eSPI」:https://github.com/Bodmer/TFT_eSPI
2,解压
3,把解压的文件放进Arduino IDE的libraries文件夹
配置屏幕
在本示例中,使用的是ESP32和ST7789,240x240分辨率的屏幕,所以我们需要对屏幕进行配置
1,找到配置文件
安装好库之后,这个User_Setup.h配置文件的位置在Arduino IDE的libraries的文件夹里的tft_eSPI
2,修改配置文件
本示例使用的是ESP32 和 ST7789系列的240x240分辨率屏幕,根据接线图配置,把User_Setup.h修改成如下代码:
// Welcome to lingshunlab.com
// Setup for the ESP32 with ST7789 display
#define USER_SETUP_ID 18
// See SetupX_Template.h for all options available
#define ST7789_DRIVER
// Typical board default pins
#define TFT_CS 5 // Chip select control pin
// #define TFT_MISO 13 //
#define TFT_MOSI 23 // In some display driver board, it might be written as "SDA" and so on.
#define TFT_SCLK 18 //
#define TFT_DC 13 // Data Command control pin
#define TFT_RST 14 //
#define TFT_BL 12 // LED back-light
//#define TOUCH_CS 16 // Optional for touch screen
#define TFT_WIDTH 240
#define TFT_HEIGHT 240
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
// FSPI port will be used unless the following is defined
// #define USE_HSPI_PORT
// #define SPI_FREQUENCY 20000000
// #define SPI_FREQUENCY 27000000
// #define SPI_FREQUENCY 40000000
#define SPI_FREQUENCY 80000000
#define SPI_READ_FREQUENCY 6000000 // 6 MHz is the maximum SPI read speed for the ST7789V
#define SPI_TOUCH_FREQUENCY 2500000
// 如果遇到红色为蓝色,蓝色为红色的话,去掉以下一行的注释,重定义TFT的颜色顺序,一般使用默认值,颜色顺序没有问题的可以不用理会。
// #define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
// #define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
在tft_eSPI的文件夹里,有个文件夹「User_Setups」,里面有其他屏幕系列的配置文件,可以参考。
测试程序代码
// Welcome to lingshunlab.com
#include "SPI.h"
#include "TFT_eSPI.h"
TFT_eSPI tft = TFT_eSPI();
unsigned long total = 0;
unsigned long tn = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println(""); Serial.println("");
Serial.println("TFT_eSPI library test!");
tft.init();
tn = micros();
tft.fillScreen(TFT_BLACK);
yield(); Serial.println(F("Benchmark Time (microseconds)"));
yield(); Serial.print(F("Screen fill "));
yield(); Serial.println(testFillScreen());
//total+=testFillScreen();
//delay(500);
yield(); Serial.print(F("Text "));
yield(); Serial.println(testText());
//total+=testText();
//delay(3000);
yield(); Serial.print(F("Lines "));
yield(); Serial.println(testLines(TFT_CYAN));
//total+=testLines(TFT_CYAN);
//delay(500);
yield(); Serial.print(F("Horiz/Vert Lines "));
yield(); Serial.println(testFastLines(TFT_RED, TFT_BLUE));
//total+=testFastLines(TFT_RED, TFT_BLUE);
//delay(500);
yield(); Serial.print(F("Rectangles (outline) "));
yield(); Serial.println(testRects(TFT_GREEN));
//total+=testRects(TFT_GREEN);
//delay(500);
yield(); Serial.print(F("Rectangles (filled) "));
yield(); Serial.println(testFilledRects(TFT_YELLOW, TFT_MAGENTA));
//total+=testFilledRects(TFT_YELLOW, TFT_MAGENTA);
//delay(500);
yield(); Serial.print(F("Circles (filled) "));
yield(); Serial.println(testFilledCircles(10, TFT_MAGENTA));
//total+= testFilledCircles(10, TFT_MAGENTA);
yield(); Serial.print(F("Circles (outline) "));
yield(); Serial.println(testCircles(10, TFT_WHITE));
//total+=testCircles(10, TFT_WHITE);
//delay(500);
yield(); Serial.print(F("Triangles (outline) "));
yield(); Serial.println(testTriangles());
//total+=testTriangles();
//delay(500);
yield(); Serial.print(F("Triangles (filled) "));
yield(); Serial.println(testFilledTriangles());
//total += testFilledTriangles();
//delay(500);
yield(); Serial.print(F("Rounded rects (outline) "));
yield(); Serial.println(testRoundRects());
//total+=testRoundRects();
//delay(500);
yield(); Serial.print(F("Rounded rects (filled) "));
yield(); Serial.println(testFilledRoundRects());
//total+=testFilledRoundRects();
//delay(500);
yield(); Serial.println(F("Done!")); yield();
//Serial.print(F("Total = ")); Serial.println(total);
//yield();Serial.println(millis()-tn);
}
void loop(void) {
for (uint8_t rotation = 0; rotation < 4; rotation++) {
tft.setRotation(rotation);
testText();
delay(2000);
}
}
unsigned long testFillScreen() {
unsigned long start = micros();
tft.fillScreen(TFT_BLACK);
tft.fillScreen(TFT_RED);
tft.fillScreen(TFT_GREEN);
tft.fillScreen(TFT_BLUE);
tft.fillScreen(TFT_BLACK);
return micros() - start;
}
unsigned long testText() {
tft.fillScreen(TFT_BLACK);
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(TFT_WHITE); tft.setTextSize(2);
tft.println("LingShunLAB.com");
tft.setTextColor(TFT_YELLOW); tft.setTextSize(2);
tft.println(1234.56);
tft.setTextColor(TFT_RED); tft.setTextSize(3);
tft.println(0xDEADBEEF, HEX);
tft.println();
tft.setTextColor(TFT_GREEN);
tft.setTextSize(5);
tft.println("Groop");
tft.setTextSize(2);
tft.println("I implore thee,");
//tft.setTextColor(TFT_GREEN,TFT_BLACK);
tft.setTextSize(1);
tft.println("my foonting turlingdromes.");
tft.println("And hooptiously drangle me");
tft.println("with crinkly bindlewurdles,");
tft.println("Or I will rend thee");
tft.println("in the gobberwarts");
tft.println("with my blurglecruncheon,");
tft.println("see if I don't!");
return micros() - start;
}
unsigned long testLines(uint16_t color) {
unsigned long start, t;
int x1, y1, x2, y2,
w = tft.width(),
h = tft.height();
tft.fillScreen(TFT_BLACK);
x1 = y1 = 0;
y2 = h - 1;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t = micros() - start; // fillScreen doesn't count against timing
tft.fillScreen(TFT_BLACK);
x1 = w - 1;
y1 = 0;
y2 = h - 1;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
tft.fillScreen(TFT_BLACK);
x1 = 0;
y1 = h - 1;
y2 = 0;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = w - 1;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
t += micros() - start;
tft.fillScreen(TFT_BLACK);
x1 = w - 1;
y1 = h - 1;
y2 = 0;
start = micros();
for (x2 = 0; x2 < w; x2 += 6) tft.drawLine(x1, y1, x2, y2, color);
x2 = 0;
for (y2 = 0; y2 < h; y2 += 6) tft.drawLine(x1, y1, x2, y2, color);
return micros() - start;
}
unsigned long testFastLines(uint16_t color1, uint16_t color2) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height();
tft.fillScreen(TFT_BLACK);
start = micros();
for (y = 0; y < h; y += 5) tft.drawFastHLine(0, y, w, color1);
for (x = 0; x < w; x += 5) tft.drawFastVLine(x, 0, h, color2);
return micros() - start;
}
unsigned long testRects(uint16_t color) {
unsigned long start;
int n, i, i2,
cx = tft.width() / 2,
cy = tft.height() / 2;
tft.fillScreen(TFT_BLACK);
n = min(tft.width(), tft.height());
start = micros();
for (i = 2; i < n; i += 6) {
i2 = i / 2;
tft.drawRect(cx - i2, cy - i2, i, i, color);
}
return micros() - start;
}
unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
unsigned long start, t = 0;
int n, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
n = min(tft.width(), tft.height());
for (i = n - 1; i > 0; i -= 6) {
i2 = i / 2;
start = micros();
tft.fillRect(cx - i2, cy - i2, i, i, color1);
t += micros() - start;
// Outlines are not included in timing results
tft.drawRect(cx - i2, cy - i2, i, i, color2);
}
return t;
}
unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;
tft.fillScreen(TFT_BLACK);
start = micros();
for (x = radius; x < w; x += r2) {
for (y = radius; y < h; y += r2) {
tft.fillCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testCircles(uint8_t radius, uint16_t color) {
unsigned long start;
int x, y, r2 = radius * 2,
w = tft.width() + radius,
h = tft.height() + radius;
// Screen is not cleared for this one -- this is
// intentional and does not affect the reported time.
start = micros();
for (x = 0; x < w; x += r2) {
for (y = 0; y < h; y += r2) {
tft.drawCircle(x, y, radius, color);
}
}
return micros() - start;
}
unsigned long testTriangles() {
unsigned long start;
int n, i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
n = min(cx, cy);
start = micros();
for (i = 0; i < n; i += 5) {
tft.drawTriangle(
cx , cy - i, // peak
cx - i, cy + i, // bottom left
cx + i, cy + i, // bottom right
tft.color565(0, 0, i));
}
return micros() - start;
}
unsigned long testFilledTriangles() {
unsigned long start, t = 0;
int i, cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
start = micros();
for (i = min(cx, cy); i > 10; i -= 5) {
start = micros();
tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(0, i, i));
t += micros() - start;
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(i, i, 0));
}
return t;
}
unsigned long testRoundRects() {
unsigned long start;
int w, i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
w = min(tft.width(), tft.height());
start = micros();
for (i = 0; i < w; i += 6) {
i2 = i / 2;
tft.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(i, 0, 0));
}
return micros() - start;
}
unsigned long testFilledRoundRects() {
unsigned long start;
int i, i2,
cx = tft.width() / 2 - 1,
cy = tft.height() / 2 - 1;
tft.fillScreen(TFT_BLACK);
start = micros();
for (i = min(tft.width(), tft.height()); i > 20; i -= 6) {
i2 = i / 2;
tft.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, tft.color565(0, i, 0));
}
return micros() - start;
}
/***************************************************
Original Adafruit text:
This is an example sketch for the Adafruit 2.2" SPI display.
This library works with the Adafruit 2.2" TFT Breakout w/SD card
----> http://www.adafruit.com/products/1480
Check out the links above for our tutorials and wiring diagrams
These displays use SPI to communicate, 4 or 5 pins are required to
interface (RST is optional)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
程序上传完后,就会见到屏幕以非常快的速度在测试。