一、模块介绍
TFT屏幕(薄膜晶体管屏幕)是一种先进的液晶显示(LCD)技术,提供高分辨率和鲜艳色彩的显示效果。
下面是模块的一些参数信息:
还有更多详细的信息可以查看他的一些手册。
二、基础功能
本文章使用的是ESP32 + VSCode,接下来讲述一下如何通过VSCode驱动TFT屏幕
1. 首先,打开VScode,在VSCode拓展搜索PlatformIO,下载下面这个插件
2. 下载完打开PlatformIO,会看到下面这个界面,点击新建文件夹
3. 根据相关提示,填写信息
注意:第一次下载可能会比较慢,请耐心等待,也可以挂个梯子可能会更快
4. 点击看一下主函数,可以看到基本的arduino框架
5. 接下来去到PIO Home,搜索相关的TFT库,将他添加到工程文件中
6. 添加完后,就可以在我们工程文件夹中,看到这个TFT库
7. 接下来,使用官方给的例子,来实现我们TFT屏幕的显示
将范例里的代码Alt + A 复制粘贴到主函数里面
接着,我们需要去配置TFT屏幕的一些引脚
在下面这个头文件里面,选择你的TFT屏幕对应驱动的头文件,将它解除注释
打开头文件,看一下里面有什么东西
根据头文件的定义,完成ESP32跟TFT屏幕的接线,只需要一一对应就可以,其中LED引脚连接到ESP32的EN引脚
VCC | 3V3 |
GND | GND |
CS | D15 |
RESET | D4 |
DC | D2 |
SDI(MOSI) | D23 |
SCK | D18 |
LED | EN |
SDO(MISO) | D19 |
将函数下载并且上传到ESP32上面
8. 最后,我们就可以看到TFT屏幕成功显示了
三、进阶功能—触摸功能
如果你的屏幕带有触摸功能的话,可以继续往下看下去
在TFT_eSPI库中,带有触摸的相应功能及函数,接下来让我们来开启这个功能
1. 首先去到上面我们TFT驱动的头文件里面,将触摸功能的引脚打开
2. 然后在TFT_eSPI库里面找一个官方的触摸例子,我这里找的是键盘的例子
将这个例子全部复制到主函数里面
其中,在setup函数前面加上三句函数注释
void status(const char *msg);
void touch_calibrate();
void drawKeypad();
3. 接下来是接线的问题,因为TFT显示跟TFT触摸功能使用的都是SPI协议
SPI协议的通信接线方式如下:
不同的设备通过CS片选线来选择主机跟哪个从设备进行通信
所以为了解决显示功能跟触摸功能的同时使用,我们只需要将主设备的SCK、MISO、MOSI引脚引出,然后将多个从设备的SCK、MISO、MOSI引脚分别接在引出的三条对应的线路上,最后通过程序设置CS引脚来分时的选通从设备,就可以在这里实现对触摸显示屏的正常驱动。
具体的接线如下图所示:
VCC | 3V3 |
GND | GND |
CS | D15 |
RESET | D4 |
DC | D2 |
SDI(MOSI) | D23 |
SCK | D18 |
LED | EN |
SDO(MISO) | 不接 |
T_CLK(SCK) | D18 |
T_CS | D5 |
T_DIN(MOSI) | D19 |
T_DO(MISO) | D23 |
4. 最后编译下载代码,观看效果
四、超进阶学习—LVGL
LVGL(Light and Versatile Graphics Library)是一个免费的开源图形库,用于嵌入式系统和微控制器上的图形用户界面(GUI)开发。它提供了丰富的功能和组件,使开发人员能够轻松地创建高度自定义和响应式的用户界面。
太多的介绍就不在这里赘述了,可以移步到LVGL的文档去阅读
欢迎来到LVGL中文文档 — LVGL_Chinese_Documents 文档
下面,讲解在VSCode中怎么移植LVGL库
在Platform IO中,将LVGL库添加到工程中
将LVGL文件夹下将lv_conf_template.h重命名为lv_conf.h
紧接着,更改里面的内容
使能lv_conf.h文件
使能ESP32内部时钟心跳包
使能我们后面要用到的例子
接着将lvgl/demos文件移动到lvgl/src/demos
编写一下主函数
#include <Arduino.h>
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <demos/lv_demos.h>
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ 320 * 10 ];
TFT_eSPI tft = TFT_eSPI(240,320);
/* Display flushing */
void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p )
{
uint32_t w = ( area->x2 - area->x1 + 1 );
uint32_t h = ( area->y2 - area->y1 + 1 );
tft.startWrite();
tft.setAddrWindow( area->x1, area->y1, w, h );
tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );
tft.endWrite();
lv_disp_flush_ready( disp );
}
/*Read the touchpad*/
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
{
uint16_t touchX, touchY;
bool touched = tft.getTouch( &touchX, &touchY, 600 );
if( !touched )
{
data->state = LV_INDEV_STATE_REL;
}
else
{
data->state = LV_INDEV_STATE_PR;
/*Set the coordinates*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print( "Data x " );
Serial.println( touchX );
Serial.print( "Data y " );
Serial.println( touchY );
}
}
//TFT屏幕校准
void touch_calibrate()
{
uint16_t calData[5];
uint8_t calDataOK = 0;
// Calibrate
tft.fillScreen(TFT_BLACK);
tft.setCursor(20, 0);
tft.setTextFont(2);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.println("Touch corners as indicated");
tft.setTextFont(1);
tft.println();
tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
Serial.println(); Serial.println();
Serial.println("// Use this calibration code in setup():");
Serial.print(" uint16_t calData[5] = ");
Serial.print("{ ");
for (uint8_t i = 0; i < 5; i++)
{
Serial.print(calData[i]);
if (i < 4) Serial.print(", ");
}
Serial.println(" };");
Serial.print(" tft.setTouch(calData);");
Serial.println(); Serial.println();
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.println("Calibration complete!");
tft.println("Calibration code sent to Serial port.");
delay(4000);
}
void setup() {
lv_init();
Serial.begin(115200);
tft.begin();
tft.setRotation(3);
touch_calibrate();
uint16_t calData[5] = {539, 3379, 378, 3384, 5};
tft.setTouch(calData);
lv_disp_draw_buf_init( &draw_buf, buf, NULL, 320 * 10 );
/*Initialize the display*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init( &disp_drv );
/*Change the following line to your display resolution*/
disp_drv.hor_res = 320;
disp_drv.ver_res = 240;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register( &disp_drv );
/*Initialize the input display*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init( &indev_drv );
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register(&indev_drv);
//在这里放不同demo函数
lv_demo_widgets();
}
void loop() {
lv_timer_handler(); /* let the GUI do its work */
delay( 1 );
}
最后,编译下载代码,观看一下效果