ESP IoT Solution 组件实战:基于 esp_lcd_touch_ili2118 驱动 ILI2118 触摸屏(版本演进与 I2C 配置全解析)
【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution
导读
esp_lcd_touch_ili2118是 ESP IoT Solution 仓库中为 ILI2118(ILITEK)电容触摸控制器提供的官方驱动组件,基于esp_lcd_touch抽象层实现,通过 I2C 总线与主机通信。本文以该组件的 CHANGELOG.md 为脉络,结合头文件、驱动源码与测试用例,完整讲解其版本演进历程、底层寄存器协议、I2C 配置宏参数含义,以及中断/轮询两种读取触摸数据的实战方案。读完本文,你将能够独立完成 ILI2118 触摸屏在 ESP-IDF(≥5.0)工程中的接入、初始化、坐标读取与问题排查。
组件概览:一个面向 ILI2118 的 I2C 触摸驱动
| 触摸控制器 | 通信接口 | 组件名称 | 版本 |
|---|---|---|---|
| ILI2118(ILI2118A) | I2C | esp_lcd_touch_ili2118 | v0.1.2 |
组件核心实现位于 esp_lcd_touch_ili2118.c,对外 API 与配置宏定义在 include/esp_lcd_touch_ili2118.h。从 idf_component.yml 可以看到其依赖约束:
idf: ">=5.0":要求 ESP-IDF 5.0 及以上版本;esp_lcd_touch: "^1":依赖esp_lcd_touch抽象层组件(public 依赖),驱动最终注册为esp_lcd_touch_handle_t;cmake_utilities: "0.*":用于组件版本号自动管理(对应 CMakeLists.txt 中的cu_pkg_define_version)。
从源码结构看,该驱动实现了esp_lcd_touch接口的三要素:read_data(读原始触摸数据)、get_xy(取坐标与压力)、del(反初始化),因此任何基于esp_lcd_touch的 GUI 或手势框架都可以直接复用。
版本演进:CHANGELOG 揭示的三个关键节点
v0.0.1(2025-01-07):驱动从零实现
首个版本完成了 ILI2118 触摸控制器的完整驱动移植,包含:
- 基于 I2C 的底层寄存器读写;
- 触摸坐标解析与屏幕分辨率换算;
- 中断 GPIO 配置与回调注册;
- 触摸信息(固件版本、协议版本、原始分辨率)读取。
v0.1.1(2025-12-09):API 迁移,弃用旧接口
该版本将文档与测试从已弃用的esp_lcd_touch_get_coordinates迁移到新接口esp_lcd_touch_get_data。新接口配合esp_lcd_touch_point_data_t结构体,一次调用即可同时取得 x、y 坐标与触摸力度(strength),语义更清晰,且不再需要分别传入touch_x/touch_y/touch_strength三个数组。这一迁移在 README.md 与 test_esp_lcd_touch_ili2118.c 中均已落地。
v0.1.2(2026-04-21):I2C 频率默认化,开箱即用
为配置宏ESP_LCD_TOUCH_IO_I2C_ILI2118A_CONFIG()补充了默认的 I2C 时钟频率(100 kHz),开发者无需手工指定scl_speed_hz即可完成 IO 层配置,进一步降低了接入门槛。
I2C 通信配置:核心宏逐字段拆解
esp_lcd_touch_ili2118通过 include/esp_lcd_touch_ili2118.h 中的两个宏完成与esp_lcd_panel_io_i2c_config_t的对接:
#define ESP_LCD_TOUCH_IO_I2C_ILI2118A_ADDRESS (0x4C >> 1) #define ESP_LCD_TOUCH_IO_I2C_ILI2118A_CONFIG() \ { \ .scl_speed_hz = 100000, \ .dev_addr = ESP_LCD_TOUCH_IO_I2C_ILI2118A_ADDRESS, \ .control_phase_bytes = 1, \ .lcd_cmd_bits = 16, \ .flags = { \ .disable_control_phase = 1, \ } \ }各字段含义与取值依据:
dev_addr = 0x4C >> 1 = 0x26:ILI2118A 的 7 位 I2C 从机地址。0x4C 是常见的 8 位写地址写法(含 R/W 位),右移一位得到标准 7 位地址,这也是 ESP LCD 面板 IO 层约定的地址格式。scl_speed_hz = 100000:默认 SCL 时钟 100 kHz(标准模式)。v0.1.2 起由宏内建,开发者仍可在初始化后自行覆盖。从 test_apps/main/test_esp_lcd_touch_ili2118.c 可以看到测试环境将总线配置为 90 kHz(TEST_I2C_CLK_SPEED = 90 * 1000),说明该器件对 100 kHz 附近的标准速率均能稳定工作。control_phase_bytes = 1、lcd_cmd_bits = 16、disable_control_phase = 1:三者配合实现“无控制阶段、直接以 16 bit 命令/寄存器地址发起 I2C 读”的访问模式。ILI2118A 的寄存器采用 16 bit 地址编码(例如 0x0011 读取触摸数据),通过面板 IO 的rx_param/tx_param接口即可完成单次事务,无需额外的控制字节相位。
底层协议:寄存器、魔数与坐标换算
寄存器命令集
源码顶部(esp_lcd_touch_ili2118.c)定义了驱动用到的全部寄存器命令:
| 宏 | 值 | 用途 |
|---|---|---|
ILITEK_TP_CMD_READ_SUB_DATA | 0x11 | 读取触摸子数据(当前触点) |
ILITEK_TP_CMD_GET_RESOLUTION | 0x20 | 读取触摸屏原始分辨率 |
ILITEK_TP_CMD_GET_FIRMWARE_VERSION | 0x40 | 读取固件版本(4 字节) |
ILITEK_TP_CMD_GET_PROTOCOL_VERSION | 0x42 | 读取协议版本(2 字节) |
触摸数据帧解析
read_data()(esp_lcd_touch_ili2118.c)通过esp_lcd_panel_io_rx_param一次性读取 53 字节(ILI2118_BUF_SIZE)数据,并以帧头魔数区分两种数据格式:
0x5A魔数帧:有效坐标位于buf[1]..buf[3],其中raw_x = ((buf[1] & 0xF0) << 4) | buf[2]raw_y = ((buf[1] & 0x0F) << 8) | buf[3]
0x99魔数帧:有效坐标位于buf[6]..buf[8],其中 x/y 的拼接方式对调:raw_y = ((buf[6] & 0xF0) << 4) | buf[7]raw_x = ((buf[6] & 0x0F) << 8) | buf[8]
任何坐标字节为0xFF(ILI2118_INVALID_COORD)时判定为无效触点,不产生触摸事件。
原始坐标到屏幕坐标的换算
控制器上报的原始分辨率上限为 2048×2048(TOUCH_MAX_WIDTH/TOUCH_MAX_HEIGHT),驱动将其等比映射到应用配置的屏幕分辨率:
tp->data.coords[0].x = (raw_x * tp->config.x_max) / TOUCH_MAX_WIDTH; tp->data.coords[0].y = (raw_y * tp->config.y_max) / TOUCH_MAX_HEIGHT;因此esp_lcd_touch_config_t中的x_max/y_max应填写 LCD 面板的实际水平/垂直分辨率(如 480×480),保证触摸坐标与显示像素一一对应。
设备信息自检
read_info()(esp_lcd_touch_ili2118.c)在初始化时自动读取固件版本、协议版本、原始分辨率与通道数,并通过日志打印:
Touch info: 480x480, protocol v1.0, firmware v1.0.0.0该输出可用于快速验证 I2C 链路与器件是否正常工作。
工程接入与完整初始化流程
添加依赖
推荐通过 ESP-IDF 组件管理器添加:
idf.py add-dependency "espressif/esp_lcd_touch_ili2118==*"或在工程根目录的idf_component.yml中声明依赖(版本号以 CHANGELOG.md 记录的最新版 v0.1.2 为准,亦可使用"*"自动获取最新):
dependencies: espressif/esp_lcd_touch_ili2118: "^0.1.2"初始化代码(以 README 示例为蓝本)
#include "esp_lcd_touch_ili2118.h" /* 1. I2C 面板 IO 配置:v0.1.2 起频率已内建默认值 100 kHz */ esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_ILI2118A_CONFIG(); /* 2. 触摸参数配置:分辨率与 LCD 对齐,本例 RST/INT 不启用 */ esp_lcd_touch_config_t tp_cfg = { .x_max = CONFIG_LCD_HRES, /* 例如 480 */ .y_max = CONFIG_LCD_VRES, /* 例如 480 */ .rst_gpio_num = -1, .int_gpio_num = -1, .levels = { .reset = 0, .interrupt = 0, }, .flags = { .swap_xy = 0, .mirror_x = 0, .mirror_y = 0, }, }; /* 3. 创建触摸句柄 */ esp_lcd_touch_handle_t tp; esp_lcd_touch_new_i2c_ili2118(io_handle, &tp_cfg, &tp);提示:
io_handle需由esp_lcd_new_panel_io_i2c()基于同一个esp_lcd_i2c_bus_handle_t创建(可与 LCD 面板共用 I2C 总线);若启用中断,可在tp_cfg.interrupt_callback中注册回调,驱动会自动配置int_gpio_num的上升/下降沿中断(由levels.interrupt决定)。
读取与消费触摸数据(v0.1.1 起的新接口)
/* 周期性调用,将触摸数据读入 RAM(轮询或中断回调中均可) */ esp_lcd_touch_read_data(tp); /* 取出坐标与力度 */ esp_lcd_touch_point_data_t points[1] = {0}; uint8_t touch_cnt = 0; esp_lcd_touch_get_data(tp, points, &touch_cnt, 1); if (touch_cnt > 0) { ESP_LOGI(TAG, "Touch position: [%d, %d], strength %d, count %d", points[0].x, points[0].y, points[0].strength, touch_cnt); }这是 v0.1.1 引入的标准用法:esp_lcd_touch_get_data取代旧版esp_lcd_touch_get_coordinates,一次调用同时返回坐标、力度与触点数量,并自动清空内部缓冲,避免重复消费。
测试验证:中断模式与轮询模式
组件的单元测试位于 test_apps/main/test_esp_lcd_touch_ili2118.c,包含两个典型场景:
[ili2118a][intr]中断模式:注册touch_interrupt_callback,在 ISR 中通过信号量唤醒任务,触发后调用esp_lcd_touch_read_data读取数据(3 秒窗口、30 ms 超时轮询信号量)。该用例还验证了 ISR 安全的内存交互(portYIELD_FROM_ISR)。[ili2118a][poll]轮询模式:不注册回调,以固定 30 ms 周期循环调用esp_lcd_touch_read_data+esp_lcd_touch_get_data。
测试环境参数(sdkconfig.defaults)可作为自定义工程模板:GPIO18/GPIO8 分别作 SCL/SDA,GPIO1/GPIO0 作 INT/RST,分辨率 480×480。此外,测试基架通过setUp/tearDown对比MALLOC_CAP_8BIT/MALLOC_CAP_32BIT堆水位,检测驱动是否存在内存泄漏,可直接复用该模式校验自定义工程。
常见问题排查清单
| 现象 | 排查方向 |
|---|---|
| 初始化日志无 “Touch info:” 输出 | 检查 I2C 地址(0x26)与 SCL/SDA 接线、上拉电阻;确认esp_lcd_new_panel_io_i2c已先于驱动创建执行 |
| 触摸无响应 | 确认x_max/y_max与 LCD 分辨率一致;检查read_data调用频率是否足够(建议 ≤ 30 ms 周期) |
| 坐标反向或错位 | 调整tp_cfg.flags中的swap_xy/mirror_x/mirror_y |
| 中断模式不进回调 | 核对levels.interrupt电平与硬件实际触发沿,确认int_gpio_num已正确配置 |
总结
esp_lcd_touch_ili2118以三个版本完成了从“驱动实现”到“API 现代化”再到“配置开箱即用”的演进:v0.0.1 奠定了基于 I2C 的寄存器读写与坐标换算框架,v0.1.1 全面迁移至esp_lcd_touch_get_data新接口,v0.1.2 内建 100 kHz 默认 I2C 频率。结合 include/esp_lcd_touch_ili2118.h、esp_lcd_touch_ili2118.c 与测试用例,开发者可以快速将 ILI2118 触摸屏接入 ESP-IDF 工程,并依据本文的排查清单独立定位链路、配置与坐标映射问题。
【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考