使用ESP+Platfromio开发 驱动ILI9341屏幕移植lvgl并实现触摸操作;

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文主要记录自己在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口进行连线;

MOSIMISOCLK
GPIO23GPIO19GPIO 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 */                                                  
 
}

总结

        个人笔记;

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值