提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本文主要记录自己在VSCode+PlatformIO平台下学习如何使用ESP32-WROOM 32驱动ILI9341屏幕移植lvgl并实现触摸操作;个人笔记,描述简略;
提示:以下是本篇文章正文内容,下面案例可供参考
一、下载库文件
首先我们需要先下载好相应的库函数,需要下载的有TFT_sPI、lvgl和PT2046_Touchscreen;
下图展示了TFT_eSPI文件下载过程,其余两个如法炮制即可,版本选最新版本就好;
二、配置TFT_eSPI驱动
1.修改User_Setup.h
由于我们使用的是ILI9341显示屏,我们需要将#define ILI9341_DRIVER 取消注释;当然文件默认取消的就是该注释;
接下来对各个引脚进行宏定义;取消注释下图位置上的代码;将其改为自己连接的引脚号;由于LED引脚文件没有定义,需要LED背光引脚连接到3.3V引脚上或者连接一个IO口上,将其模式设置为输出模式并高电平输出;
TFT驱动配置完成可以在example文件中选一个案例的代码复制到main.cpp文件里去运行;
二、配置LVGL
1、修改文件
首先需要将lv_conf_template.h文件名改为lv_conf.h;以下是lv_conf.h文件中需要修改的地方:
将其宏定义改为1即可如下图所示:
lvgl配置更改完毕;可以在lvgl\examples\arduino\LVGL_Arduino\LVGL_Arduino.ino路径下复制代码到main.cpp进行调试,也可以复制下行代码进行下载验证;
#include <lvgl.h>
#include "TFT_eSPI.h"
#include "Arduino.h"
// #define CS_PIN 21
// MOSI=11, MISO=12, SCK=13
// The TIRQ interrupt signal must be used for this example.
// #define TIRQ_PIN 22
/*Change to your screen resolution*/
static const uint16_t screenWidth = 320;
static const uint16_t screenHeight = 240;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * 10 ];
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
lv_obj_t *label ;
/* 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 );
}
void setup() {
/*TFT_LED high*/
pinMode(25,OUTPUT);
digitalWrite(25,HIGH);
/*Serial init*/
Serial.begin(9600);
/*tft 初始化*/
tft.init();
tft.setRotation(1);
lv_init();
#if LV_USE_LOG != 0
lv_log_register_print_cb( my_print ); /* register print function for debugging */
#endif
lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 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 = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register( &disp_drv );
/* Create simple label */
label = lv_label_create( lv_scr_act() );
lv_label_set_text( label, "hello world!" );
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
}
void loop() {
lv_timer_handler(); /* let the GUI do its work */
}
三、配置XPT2046触摸驱动
下载好XPT2046_TouchScreen库,由于该驱动用的是硬件SPI进行驱动,我们我们只需配置两个引脚;
#define CS_PIN 21
#define TIRQ_PIN 22
触摸屏的引脚连线我们需要按照SPI的IO口进行连线;
MOSI | MISO | CLK |
---|---|---|
GPIO23 | GPIO19 | GPIO 18 |
复制下面的代码进行调试验证;
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
#define CS_PIN 21
// MOSI=11, MISO=12, SCK=13
//XPT2046_Touchscreen ts(CS_PIN);
#define TIRQ_PIN 22
//XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, 255); // Param 2 - 255 - No interrupts
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
void setup() {
Serial.begin(38400);
ts.begin();
ts.setRotation(1);
while (!Serial && (millis() <= 1000));
}
void loop() {
if (ts.touched()) {
TS_Point p = ts.getPoint();
Serial.print("Pressure = ");
Serial.print(p.z);
Serial.print(", x = ");
Serial.print(p.x);
Serial.print(", y = ");
Serial.print(p.y);
delay(30);
Serial.println();
}
}
如果要在lvgl使用触摸操作;需要设置输入设备;以下链接如何输入设备接口:https://deepinout.com/lvgl-tutorials/lvgl-getting-started/lvgl-input-device-interface.html
以下代码验证,触摸屏左滑右滑操作;
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
#include <lvgl.h>
#include "TFT_eSPI.h"
#include "Arduino.h"
#define CS_PIN 21
// MOSI=11, MISO=12, SCK=13
// The TIRQ interrupt signal must be used for this example.
#define TIRQ_PIN 22
/*Change to your screen resolution*/
static const uint16_t screenWidth = 320;
static const uint16_t screenHeight = 240;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf1[ screenWidth * 10 ];
static lv_color_t buf2[ screenWidth * 10 ];
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data );
/* 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 );
}
lv_obj_t *label ;
void my_event(lv_event_t * e)
{
lv_obj_t * screen = lv_event_get_current_target(e);
lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
switch(dir) {
case LV_DIR_LEFT:
lv_label_set_text( label, "hello LEFT!" );
Serial.print("hello LEFT!");
Serial.println();
break;
case LV_DIR_RIGHT:
lv_label_set_text( label, "hello RIGHT!" );
break;
case LV_DIR_TOP:
lv_label_set_text( label, "hello TOP!" );
break;
case LV_DIR_BOTTOM:
lv_label_set_text( label, "hello BOTTOM!" );
break;
}
}
void setup() {
/*TFT_LED high*/
pinMode(25,OUTPUT);
digitalWrite(25,HIGH);
/*Serial init*/
Serial.begin(9600);
/*tft 初始化*/
tft.init();
tft.setRotation(1);
ts.begin();
ts.setRotation(1);
// while (!Serial && (millis() <= 1000));
// tft.fillCircle(160,120,50,TFT_CYAN);
lv_init();
#if LV_USE_LOG != 0
lv_log_register_print_cb( my_print ); /* register print function for debugging */
#endif
lv_disp_draw_buf_init( &draw_buf, buf1, NULL, screenWidth * 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 = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register( &disp_drv );
/*Initialize the (dummy) input device driver*/
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 );
/* Create simple label */
label = lv_label_create( lv_scr_act() );
lv_label_set_text( label, "hello world!" );
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
lv_obj_add_event_cb(lv_scr_act() , my_event, LV_EVENT_GESTURE, NULL);
}
/*Read the touchpad*/
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
{
uint16_t touchX, touchY;
if (ts.tirqTouched()) {
if (ts.touched()) {
TS_Point p = ts.getPoint();
data->state = LV_INDEV_STATE_PR;
/*Set the coordinates*/
data->point.x = ((3400-p.x)*320)/3400;
data->point.y = (p.y*240)/3400;
Serial.print("Pressure = ");
Serial.print(p.z);
Serial.print(", x = ");
Serial.print(data->point.x);
Serial.print(", y = ");
Serial.print(data->point.y);
Serial.println();
}
}else{
data->state = LV_INDEV_STATE_REL;
}
}
void loop() {
lv_timer_handler(); /* let the GUI do its work */
}
总结
个人笔记;