文章目录
1 准备工作
1.1 实验资源准备
-
ESP32开发板是ESP32-DevKitC V4
-
ESP-IDF版本为 v5.2.1
-
使用的LCD屏是3.2inch SPI Module ILI9341
驱动芯片 ILI9341 分辨率 320*240 (Pixel) 工作电压 3.3V~5V 触摸驱动 xpt2046
1.2 工程准备
- 在 esp-idf-v5.2.1 目录下新建app目录,该目录专门用于工程实验
- 将 esp-idf-v5.2.1\examples\peripherals\lcd 目录下的spi_lcd_touch工程复制到 app 目录下
- 在esp-idf-v5.2.1\app\spi_lcd\main目录下的 idf_component.yml 文件可以看出lvgl是8.3.0版本
1.3 硬件焊接
- LCD显示驱动连接在 VSPI (SPI3_HOST);
- LCD触摸驱动连接在 HSPI (SPI2_HOST);
2 工程适配
2.1 修改LCD显示驱动程序
2.1.1 配置菜单修改
- 打开ESP-IDF 5.2 PowerShell 并进入spi_lcd_touch工程,使用
idf.py menuconfig
命令进入工程菜单; - 选择 LCD显示驱动芯片为ILI9341
2.1.2 修改LCD显示驱动代码
-
修改LCD对应的SPI
#define LCD_HOST VSPI_HOST // 即SPI3_HOST
-
修改LCD驱动引脚
#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000) #define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL 1 #define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL #define EXAMPLE_PIN_NUM_SCLK 18 #define EXAMPLE_PIN_NUM_MOSI 23 #define EXAMPLE_PIN_NUM_MISO 19 #define EXAMPLE_PIN_NUM_LCD_DC 22 #define EXAMPLE_PIN_NUM_LCD_RST 25 #define EXAMPLE_PIN_NUM_LCD_CS 5 #define EXAMPLE_PIN_NUM_BK_LIGHT 21 #define EXAMPLE_PIN_NUM_TOUCH_CS 15
2.1.3 编译工程
- 使用命令配置目标芯片
idf.py set-target esp32
#设置目标芯片为esp32 - 使用命令
idf.py build
编译工程,编译完成后可以看到工程多了 managed_components 文件夹,里面包含了lcd 显示驱动、lcd 触摸驱动以及lvgl程序文件;
- 使用命令
idf.py -p COM11 flash
烧录程序(这里的 COM序号需要根据自己实际情况选择) - lcd 显示成功,注意lcd需要外部电源额外供电,否则可能显示不出来
注意此刻是无法触摸的,因为还没有修改触摸驱动。
2.2 修改LCD触摸驱动程序
2.2.1 准备lcd触摸驱动程序
- 工程自带的触摸驱动芯片只有STMPE610,而这里使用的cld触摸驱动芯片是xpt2046,需要打开官方组件网站搜索xpt2046驱动程序,将驱动xpt2046添加到工程中,这里有两种方法:第一种使用指令添加,第二种直接下载并放到合适目录下。
第一种方法:复制指令到命令行,执行命令,之后执行编译命令即可
编译后工程下 managed_components 文件夹就有了xpt2046驱动程序
第二种方法:直接下载xpt2046驱动程序
还未验证
2.2.2 修改LCD触摸驱动代码
-
打开工程 Kconfig.projbuild 文件,添加xpt2046选项,添加代码如下
-
添加头文件
#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_STMPE610 #include "esp_lcd_touch_stmpe610.h" #elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_XPT2046 #include "esp_lcd_touch_xpt2046.h" #endif
-
添加触摸驱动SPI,在原工程中lcd显示驱动SPI和触摸驱动SPI是公用一个SPI,这里是分开的
#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_XPT2046 #define LCD_TOUCH_HOST SPI2_HOST // HSPI_HOST #define LCD_TOUCH_PIN_NUM_SCLK 14 #define LCD_TOUCH_PIN_NUM_MOSI 13 #define LCD_TOUCH_PIN_NUM_MISO 12 #define LCD_TOUCH_PIN_NUM_IRQ 26 #endif
-
初始化触摸的PSI (省略了原有的代码)
#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED #if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_STMPE610 // 自己添加的条件编译 esp_lcd_panel_io_handle_t tp_io_handle = NULL; esp_lcd_panel_io_spi_config_t tp_io_config = ESP_LCD_TOUCH_IO_SPI_STMPE610_CONFIG(EXAMPLE_PIN_NUM_TOUCH_CS); // Attach the TOUCH to the SPI bus ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &tp_io_config, &tp_io_handle)); esp_lcd_touch_config_t tp_cfg = { .x_max = EXAMPLE_LCD_H_RES, .y_max = EXAMPLE_LCD_V_RES, .rst_gpio_num = -1, .int_gpio_num = -1, .flags = { .swap_xy = 0, .mirror_x = 0, .mirror_y = 0, }, }; #elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_XPT2046 // 自己添加的条件编译 spi_bus_config_t touchbuscfg = { .sclk_io_num = LCD_TOUCH_PIN_NUM_SCLK, .mosi_io_num = LCD_TOUCH_PIN_NUM_MOSI, .miso_io_num = LCD_TOUCH_PIN_NUM_MISO, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = EXAMPLE_LCD_H_RES * 80 * sizeof(uint16_t), }; ESP_ERROR_CHECK(spi_bus_initialize(LCD_TOUCH_HOST, &touchbuscfg, SPI_DMA_CH_AUTO)); esp_lcd_panel_io_handle_t tp_io_handle = NULL; esp_lcd_panel_io_spi_config_t tp_io_config = ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(EXAMPLE_PIN_NUM_TOUCH_CS); // Attach the TOUCH to the SPI bus ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_TOUCH_HOST, &tp_io_config, &tp_io_handle)); esp_lcd_touch_config_t tp_cfg = { .x_max = EXAMPLE_LCD_H_RES, .y_max = EXAMPLE_LCD_V_RES, .rst_gpio_num = -1, .int_gpio_num = LCD_TOUCH_PIN_NUM_IRQ, .flags = { .swap_xy = 0, .mirror_x = 0, .mirror_y = 0, }, }; #endif #if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_STMPE610 ... #elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_XPT2046 ESP_LOGI(TAG, "Initialize touch controller XPT2046"); ESP_ERROR_CHECK(esp_lcd_touch_new_spi_xpt2046(tp_io_handle, &tp_cfg, &tp)); #endif #endif // CONFIG_EXAMPLE_LCD_TOUCH_ENABLED
2.2.3 打开工程配置菜单
- 使能并选择XTP2046
2.2.4 编译并下载
- 更新程序后可以触摸,但存在一个问题,触摸起作用的位置不对,左右颠倒了,修改如下函数(省略部分未修改的代码)
static void example_lvgl_touch_cb(lv_indev_drv_t * drv, lv_indev_data_t * data)
{
...
if (touchpad_pressed && touchpad_cnt > 0) {
data->point.y = EXAMPLE_LCD_V_RES - touchpad_y[0]; // 此处修改
} else {
}
}
- 再次更新后就可以触摸了
3 测试其他demo
3.1 测试lvgl库下的其他demo
3.1.1 测试 keypad_encoder
-
将 …\spi_lcd_touch\managed_components\lvgl__lvgl\demos\keypad_encoder目录下的lv_demo_keypad_encoder.c文件复制到 …\spi_lcd_touch\main 目录下。
-
打开…\spi_lcd_touch\main 目录下CMakeLists.txt文件,添加lv_demo_keypad_encoder.c文件。
-
打开 spi_lcd_touch_example_main.c 文件添加如下程序
extern void lv_demo_keypad_encoder(void); void app_main(void) { ... if (example_lvgl_lock(-1)) { // example_lvgl_demo_ui(disp); // 屏蔽原来的测试demo lv_demo_keypad_encoder(); // Release the mutex example_lvgl_unlock(); } }
-
编译并烧录
4 还存在问题
- 初始界面的触摸位置偏出了显示的按键,暂不知道是例程的问题还是适配不到位;