☰
INAV 仓库中的 STM32H7 FT6X06 电容触摸屏组件驱动解析:架构、寄存器与 BSP 集成指南
2026/10/14 2:20:35 网站建设 项目流程
  • 无人机
  • 嵌入式
  • 智能硬件

【免费下载链接】inav

INAV: Navigation-enabled flight control software

项目地址:https://gitcode.com/gh_mirrors/in/inav
点击查看免费下载

本文以lib/main/STM32H7/Drivers/BSP/Components/ft6x06/Release_Notes.md的版本发布说明为主体,结合仓库内 FT6X06 组件驱动的完整源码,系统性讲解该触摸屏驱动的文件构成、寄存器模型、核心 API、配置方式以及它在 STM32H7 评估板 BSP 层中的实际调用链。读完本文,你将能够理解 FT6X06/FT6x36 电容触摸控制器的驱动分层思路,掌握如何在 STM32Cube BSP 框架下初始化、轮询、读取触摸坐标并启用中断。

一、驱动背景:FT6X06 组件驱动是什么

FT6X06 是 FocalTech 出品的一款电容式触摸屏控制器,通过 I2C 接口与主控(MCU)通信,负责将触摸屏上的触点坐标、触点事件、压力(Weight)、触点面积(Area)等信息上报给主机。本仓库在lib/main/STM32H7/Drivers/BSP/Components/ft6x06/目录下携带了 STMicroelectronics 官方发布的 FT6X06 组件驱动,其用途正如 Release_Notes 中 "Purpose" 一节所述:

"This driver provides a set of Touch Screen functions offered by FT6X06 component"(该驱动提供 FT6X06 组件所具备的一组触摸屏功能)。

在 INAV 的仓库结构中,这一组件驱动位于 STM32H7 标准外设库(BSP)的Components目录下,属于"以 STM32Cube BSP 驱动开发规范(UM2298)为准则"的组件级驱动,向上为 STM32H747I-EVAL、STM32H747I-DISCO 等开发板的触摸屏 BSP 层提供统一的TS_Drv_t接口。

二、版本发布历史(原文档核心内容)

Release_Notes 记录了该组件驱动从 2015 年至 2019 年的四个版本,完整脉络如下:

版本发布日期主要变更
V1.0.02015-08-03FT6X06 TS 驱动的首个正式发布
V1.0.12016-05-03新增对 FT6x36 触摸控制器的支持(FT6X36_ID = 0xCD,见 ft6x06.h)
V1.0.22017-04-07更新注释,以适配 PDSC(Pack Description)文档生成流程
V2.0.02019-11-23首个"官方正式发布"版本:完全遵循 STM32Cube BSP 驱动开发指南(UM2298)重构,驱动由三类文件组成(见下节),并与之前的版本不兼容

V2.0.0 的重要说明:

  • 向后兼容性(Backward Compatibility):官方明确标注 "This version breaks the compatibility with previous versions",即 V2.0.0 打破了与旧版的接口兼容,从旧版本升级的工程需要适配新的 API。
  • 依赖(Dependencies):该软件发布版本要求 BSP Common 版本在v6.0.0 或以上。这意味着集成时必须保证Components目录所依赖的 BSP 公共层版本足够新。

三、V2.0.0 驱动文件组成与分层架构

Release_Notes 中 V2.0.0 的 "Main Changes" 明确指出组件驱动由三部分文件组成,对应仓库 ft6x06 目录 下的实际文件:

  1. 组件核心驱动文件:ft6x06.h/ft6x06.c提供面向应用的触摸屏功能集合,包括初始化、反初始化、读 ID、获取单点/多点触摸状态、手势识别、能力查询以及中断使能/禁止/查询/清除等 API。核心文件导出了一个全局驱动结构体:

    FT6X06_TS_Drv_t FT6X06_TS_Driver = { FT6X06_Init, FT6X06_DeInit, FT6X06_GestureConfig, FT6X06_ReadID, FT6X06_GetState, FT6X06_GetMultiTouchState, FT6X06_GetGesture, FT6X06_GetCapabilities, FT6X06_EnableIT, FT6X06_DisableIT, FT6X06_ClearIT, FT6X06_ITStatus };

    该结构体(定义见 ft6x06.h)正是 BSP 层通过统一驱动指针Ts_Drv调用的入口,体现了 STM32Cube BSP 组件驱动"函数指针表 + 对象句柄"的标准抽象方式。

  2. 寄存器驱动文件:ft6x06_reg.h/ft6x06_reg.c提供对 FT6X06 每个寄存器的"单一寄存器级"访问函数(unitary register functions),例如ft6x06_dev_mode_w/r、ft6x06_gest_id、ft6x06_td_status、ft6x06_p1_xh_tp、ft6x06_th_group等,并统一封装了通用读写函数:

    int32_t ft6x06_read_reg(ft6x06_ctx_t *ctx, uint8_t reg, uint8_t* pdata, uint16_t length); int32_t ft6x06_write_reg(ft6x06_ctx_t *ctx, uint8_t reg, uint8_t *pdata, uint16_t length);

    从 ft6x06_reg.c 的注释可以看到,其内部通过ctx->ReadReg / ctx->WriteReg调用上下文句柄,具体是 I2C 还是 SPI 由上层总线实现决定。

  3. 配置文件模板:ft6x06_conf_template.h这是一个可被用户修改的配置模板,使用时一般复制为ft6x06_conf.h。当前模板内容为:

    #define FT6X06_AUTO_CALIBRATION_ENABLED 0U #define FT6X06_MAX_X_LENGTH 800U #define FT6X06_MAX_Y_LENGTH 480U
    • FT6X06_AUTO_CALIBRATION_ENABLED:是否在上电后执行一次内部硬件校准(详见第六节);当前仓库默认关闭(0U)。
    • FT6X06_MAX_X_LENGTH / FT6X06_MAX_Y_LENGTH:触摸屏最大 X/Y 坐标长度,模板默认 800×480,需与实际屏分辨率匹配。

此外目录下还保留了对应的Release_Notes.html版本(渲染版发布说明),以及_htmresc/下的样式与 ST logo 资源,供文档生成流水线(PDSC 流程)使用。

四、寄存器模型:从ft6x06_reg.h看 FT6X06 的寄存器布局

FT6X06 的寄存器模型完整定义于 ft6x06_reg.h 中。按功能可分为四组:

4.1 触摸数据类寄存器(读取触点信息)

寄存器地址说明
FT6X06_DEV_MODE_REG0x00当前模式寄存器(R/W),0x00为工作模式、0x04为工厂校准模式
FT6X06_GEST_ID_REG0x01手势 ID(只读)
FT6X06_TD_STAT_REG0x02触摸数据状态:当前有效触点数量(0~2)
FT6X06_P1_XH/XL_REG0x03 / 0x04触点 1 的 X 坐标(高字节含事件标志 EF)与低字节
FT6X06_P1_YH/YL_REG0x05 / 0x06触点 1 的 Y 坐标(高字节含触点 ID)与低字节
FT6X06_P1_WEIGHT_REG0x07触点 1 的压力(Weight)
FT6X06_P1_MISC_REG0x08触点 1 的触摸面积(Area,高 4 位有效)
FT6X06_P2_XH/XL_REG等0x09~0x0E触点 2 的 X/Y/Weight/Area,布局与触点 1 完全对称

X/Y 坐标的合成方式在 ft6x06.c 的FT6X06_GetState()中一目了然:

State->TouchX = (((uint32_t)data[0] & FT6X06_P1_XH_TP_BIT_MASK) << 8) | ((uint32_t)data[1] & FT6X06_P1_XL_TP_BIT_MASK); State->TouchY = (((uint32_t)data[2] & FT6X06_P1_YH_TP_BIT_MASK) << 8) | ((uint32_t)data[3] & FT6X06_P1_YL_TP_BIT_MASK);

即XH的低 4 位(TP位,掩码0x0F)左移 8 位后与XL全字节拼接,得到 12 位分辨率坐标。而XH的高 2 位(掩码0xC0)是触点事件标志,取值见 ft6x06.h:

  • FT6X06_TOUCH_EVT_FLAG_PRESS_DOWN(0x00):按下
  • FT6X06_TOUCH_EVT_FLAG_LIFT_UP(0x01):抬起
  • FT6X06_TOUCH_EVT_FLAG_CONTACT(0x02):接触(滑动中)
  • FT6X06_TOUCH_EVT_FLAG_NO_EVENT(0x03):无事件

4.2 工作参数类寄存器(触摸检测与功耗)

寄存器地址默认值说明
FT6X06_TH_GROUP_REG0x80—触摸检测阈值
FT6X06_TH_DIFF_REG0x85—滤波函数系数
FT6X06_CTRL_REG0x860x01控制寄存器
FT6X06_TIMEENTERMONITOR_REG0x870x0A无触摸时从 Active 模式切入 Monitor 模式的等待时间
FT6X06_PERIODACTIVE_REG0x88—Active(工作)模式下的上报周期
FT6X06_PERIODMONITOR_REG0x890x28Monitor(监视)模式下的上报周期

从源码结构可以推断,这两项周期与模式切换寄存器共同实现了 FT6X06 的功耗管理:有触摸时以较高频率上报,无触摸时降频进入 Monitor 模式以省电。

4.3 手势识别类寄存器

用于配置旋转、上下左右滑动与缩放手势的判定参数,与FT6X06_Gesture_Init_t结构体字段一一对应:

寄存器地址默认值对应配置字段
FT6X06_RADIAN_VALUE_REG0x910x0ARadian(旋转手势允许的最小角度)
FT6X06_OFFSET_LR_REG0x920x19OffsetLeftRight(左右滑动最大偏移)
FT6X06_OFFSET_UD_REG0x930x19OffsetUpDown(上下滑动最大偏移)
FT6X06_DISTANCE_LR_REG0x940x19DistanceLeftRight(左右滑动最小距离)
FT6X06_DISTANCE_UD_REG0x950x19DistanceUpDown(上下滑动最小距离)
FT6X06_DISTANCE_ZOOM_REG0x960x32DistanceZoom(缩放手势最大距离)

FT6X06_GestureConfig()正是将这 6 个字段依次写入上述 6 个寄存器(见 ft6x06.c)。手势 ID 的取值则定义在 ft6x06.h:上滑0x10、右滑0x14、下滑0x18、左滑0x1C、放大0x48、缩小0x49。

4.4 器件信息与模式类寄存器

寄存器地址说明
FT6X06_LIB_VER_H/L_REG0xA1 / 0xA2固件库版本号高/低字节
FT6X06_CIPHER_REG0xA3芯片选择信息(默认 0x06)
FT6X06_GMODE_REG0xA4中断模式寄存器:0x00轮询模式、0x01中断触发模式
FT6X06_PWR_MODE_REG0xA5当前电源模式(只读)
FT6X06_FIRMID_REG0xA6固件版本
FT6X06_CHIP_ID_REG0xA8芯片 ID:FT6X06 为0x11,FT6x36 为0xCD
FT6X06_RELEASE_CODE_ID_REG0xAF发布代码版本
FT6X06_STATE_REG0xBC当前工作模式状态

其中GMODE寄存器与中断机制直接相关:FT6X06_EnableIT()写入FT6X06_G_MODE_INTERRUPT_TRIGGER(0x01),FT6X06_DisableIT()写入FT6X06_G_MODE_INTERRUPT_POLLING(0x00),见 ft6x06.c。

需要特别注意的是,FT6X06_ITStatus()与FT6X06_ClearIT()这两个函数在当前实现中总是返回FT6X06_OK,源码注释明确说明 "This feature is not supported by FT6X06"——即 FT6X06 不支持中断状态寄存器查询与清除,BSP 层的中断处理需要依赖 MCU 侧的 EXTI 外部中断机制而非芯片状态寄存器。

五、核心 API 与数据结构

ft6x06.h 定义了组件对外导出的完整 API:

int32_t FT6X06_RegisterBusIO (FT6X06_Object_t *pObj, FT6X06_IO_t *pIO); int32_t FT6X06_Init(FT6X06_Object_t *pObj); int32_t FT6X06_DeInit(FT6X06_Object_t *pObj); int32_t FT6X06_GestureConfig(FT6X06_Object_t *pObj, FT6X06_Gesture_Init_t *GestureInit); int32_t FT6X06_ReadID(FT6X06_Object_t *pObj, uint32_t *Id); int32_t FT6X06_GetState(FT6X06_Object_t *pObj, FT6X06_State_t *State); int32_t FT6X06_GetMultiTouchState(FT6X06_Object_t *pObj, FT6X06_MultiTouch_State_t *State); int32_t FT6X06_GetGesture(FT6X06_Object_t *pObj, uint8_t *GestureId); int32_t FT6X06_EnableIT(FT6X06_Object_t *pObj); int32_t FT6X06_DisableIT(FT6X06_Object_t *pObj); int32_t FT6X06_ITStatus(FT6X06_Object_t *pObj); int32_t FT6X06_ClearIT(FT6X06_Object_t *pObj); int32_t FT6X06_GetCapabilities(FT6X06_Object_t *pObj, FT6X06_Capabilities_t *Capabilities);

5.1 对象模型

驱动采用典型的"组件对象 + IO 回调"模型。核心对象FT6X06_Object_t由三部分组成(ft6x06.h):

typedef struct { FT6X06_IO_t IO; /* 总线 IO 回调集合 */ ft6x06_ctx_t Ctx; /* 寄存器层上下文(写/读回调 + handle) */ uint8_t IsInitialized; } FT6X06_Object_t;

FT6X06_IO_t定义了上层必须提供的 IO 回调(ft6x06.h):

typedef int32_t (*FT6X06_Init_Func) (void); typedef int32_t (*FT6X06_DeInit_Func) (void); typedef int32_t (*FT6X06_GetTick_Func) (void); typedef int32_t (*FT6X06_WriteReg_Func)(uint16_t, uint16_t, uint8_t*, uint16_t); typedef int32_t (*FT6X06_ReadReg_Func) (uint16_t, uint16_t, uint8_t*, uint16_t);

FT6X06_RegisterBusIO()(见 ft6x06.c)负责把这些回调存入对象,并通过内部静态包装函数ReadRegWrap / WriteRegWrap桥接到寄存器层:包装函数将pObj->IO.ReadReg(Address, Reg, pData, Length)转为寄存器层所需的ctx->ReadReg(handle, Reg, pData, Length)形式。这样就实现了"组件核心层 → 寄存器层 → 总线层"的三层解耦,总线上层可以自由切换 I2C 或 SPI 实现。

5.2 数据输出结构体

单点状态FT6X06_State_t与多点状态FT6X06_MultiTouch_State_t(ft6x06.h):

typedef struct { uint32_t TouchDetected; /* 检测到的触点数量 */ uint32_t TouchX; /* X 坐标 */ uint32_t TouchY; /* Y 坐标 */ } FT6X06_State_t; typedef struct { uint32_t TouchDetected; uint32_t TouchX[FT6X06_MAX_NB_TOUCH]; /* 最多 2 点 */ uint32_t TouchY[FT6X06_MAX_NB_TOUCH]; uint32_t TouchWeight[FT6X06_MAX_NB_TOUCH]; /* 压力 */ uint32_t TouchEvent[FT6X06_MAX_NB_TOUCH]; /* 事件标志 */ uint32_t TouchArea[FT6X06_MAX_NB_TOUCH]; /* 面积 */ } FT6X06_MultiTouch_State_t;

FT6X06_MAX_NB_TOUCH在 ft6x06.h 定义为2U,即最多支持同时两点触摸。多点状态通过一次突发读取P1_XH起的连续 12 个寄存器(data[12])一次性解析出两个触点的坐标、事件、压力与面积(见 ft6x06.c)。

5.3 能力查询

FT6X06_GetCapabilities()(ft6x06.c)向 BSP 层汇报组件能力:

Capabilities->MultiTouch = 1; /* 支持多点 */ Capabilities->Gesture = 0; /* 手势功能当前未在芯片固件上启用 */ Capabilities->MaxTouch = FT6X06_MAX_NB_TOUCH; Capabilities->MaxXl = FT6X06_MAX_X_LENGTH; Capabilities->MaxYl = FT6X06_MAX_Y_LENGTH;

注意Gesture = 0的注释 "Gesture feature is currently not activated on FW chipset"——即当前驱动认为手势功能在芯片固件上未激活,这也是为什么上节GetGesture()只是简单读回GEST_ID寄存器。

六、可选的上电自动校准流程

当FT6X06_AUTO_CALIBRATION_ENABLED配置为 1 时,FT6X06_Init()会在初始化总线后调用私有校准函数FT6X06_TS_Calibration()(ft6x06.c),其流程为:

  1. 将器件切换到工厂模式(FT6X06_DEV_MODE_FACTORY= 0x04),写DEV_MODE_REG并回读校验,等待 300 ms;
  2. 向TD_STAT_REG写入0x04启动内部校准命令,再等待 300 ms;
  3. 循环最多 100 次(每次间隔 200 ms)轮询DEV_MODE_REG,直到器件自动切回工作模式(FT6X06_DEV_MODE_WORKING= 0x00),即表示校准结束。

该流程中的延时由FT6X06_Delay()基于pObj->IO.GetTick()毫秒计数实现。由于校准应在每次上电后执行一次,而当前模板默认关闭该功能,工程中是否开启取决于触摸屏是否已经过出厂校准。

七、BSP 层集成:以 STM32H747I-EVAL 为例

Release_Notes 中 V2.0.0 提到的 "BSP Common v6.0.0 or above" 依赖关系,在 STM32H747I-EVAL 的触摸屏驱动 中有完整的落地实例。该文件展示了组件驱动如何被嵌入板级 BSP 流程。

7.1 探测与初始化

BSP_TS_Init()接收TS_Init_t(宽、高、方向、精度)参数,先做参数合法性校验,然后调用私有函数FT6X06_Probe()完成组件探测:

  • 通过FT6X06_RegisterBusIO挂载 I2C 总线读写回调,并绑定器件 I2C 地址;
  • 调用FT6X06_ReadID读取CHIP_ID_REG,验证是否为 FT6X06(0x11)/ FT6x36(0xCD);
  • 将全局驱动指针Ts_Drv指向组件导出的FT6X06_TS_Driver结构体。

之后 BSP 层通过Ts_Drv->GetCapabilities()读取MaxXl / MaxYl存入上下文Ts_Ctx[Instance].MaxX / MaxY,并初始化"上一次触点位置"以便后续做触点抖动过滤。

7.2 坐标方向处理与精度过滤

BSP_TS_GetState()(stm32h747i_eval_ts.c)展示了 BSP 层对原始坐标的完整后处理链:

  1. 调用Ts_Drv->GetState()取得原始 X/Y;
  2. 按Ts_Ctx[Instance].Orientation中的方向位(TS_SWAP_XY、TS_SWAP_X、TS_SWAP_Y)做坐标交换/翻转;
  3. 按屏宽高做比例缩放:TouchX = x_oriented * Width / MaxX;
  4. 做精度(Accuracy)过滤:若新坐标与上一次坐标的差值未超过 Accuracy,则沿用上一次坐标,避免抖动导致的光标跳变。

多点版本BSP_TS_Get_MultiTouchState()对两个触点执行同样的方向与精度处理(见 stm32h747i_eval_ts.c)。

7.3 中断模式集成

FT6X06 的 INT 引脚为低电平有效。BSP_TS_EnableIT()(stm32h747i_eval_ts.c)的调用链为:

  1. 通过 IO 扩展器(BSP_IOEXPANDER_Init+BSP_IO_Init)把TS_INT_PIN配置为IO_MODE_IT_FALLING_EDGE(下降沿触发,上拉);
  2. 调用Ts_Drv->EnableIT()把 FT6X06 的GMODE置为中断触发模式;
  3. 通过HAL_EXTI_GetHandle / HAL_EXTI_RegisterCallback注册TS_EXTI_Callback;
  4. 应用层实现弱函数BSP_TS_Callback()即可在触摸事件到来时得到通知。

BSP_TS_DisableIT()则把引脚切回IO_MODE_OFF并调用Ts_Drv->DisableIT()回到轮询模式。这一实例也印证了上节所述:FT6X06 自身不提供中断状态寄存器,中断处理完全依赖 MCU 侧 EXTI。

八、集成要点与注意事项

综合 Release_Notes 与源码,在实际工程中集成该驱动时需要注意:

  1. 版本匹配:若从 V1.x 升级到 V2.0.0,接口不兼容,需同步更新调用代码;同时确保 BSP Common 版本不低于 v6.0.0。
  2. 配置文件:将ft6x06_conf_template.h复制为ft6x06_conf.h并按屏的实际分辨率修改FT6X06_MAX_X_LENGTH / FT6X06_MAX_Y_LENGTH;按是否需要上电校准决定FT6X06_AUTO_CALIBRATION_ENABLED的取值。
  3. 总线实现:FT6X06_IO_t中的WriteReg / ReadReg需由上层提供真实的 I2C/SPI 传输函数(地址、寄存器号、数据、长度四个参数),GetTick提供毫秒级时基用于校准延时。
  4. 器件 ID 校验:初始化阶段通过FT6X06_ReadID区分 FT6X06(0x11)与 FT6x36(0xCD),据此确认挂载的是哪颗芯片。
  5. 中断模式:FT6X06 不支持中断状态寄存器,ITStatus / ClearIT恒返回 OK;中断触发后需在 EXTI 回调中主动调用BSP_TS_GetState读取触点数据。

九、总结

FT6X06 组件驱动以"组件核心层(ft6x06.c/h)— 寄存器层(ft6x06_reg.c/h)— 配置文件(ft6x06_conf_template.h)"三层结构,在 STM32Cube BSP 框架下提供了对 FocalTech FT6X06 / FT6x36 电容触摸屏的完整操作能力:从 I2C 总线挂载、器件 ID 探测、单点/多点坐标读取、事件/压力/面积解析,到手势参数配置、中断触发与可选的上电校准。其发布历史(V1.0.0 → V2.0.0)完整反映了 STM32 组件驱动从"裸驱动"走向"符合 UM2298 规范的官方 BSP 组件"的演进过程。对于需要为 STM32H7 平台接入电容触摸屏的开发者,可以直接复用 ft6x06 组件目录 的驱动,并以 stm32h747i_eval_ts.c 为参考完成 BSP 层的坐标方向处理、精度过滤与 EXTI 中断集成。

  • 无人机
  • 嵌入式
  • 智能硬件

【免费下载链接】inav

INAV: Navigation-enabled flight control software

项目地址:https://gitcode.com/gh_mirrors/in/inav
点击查看免费下载

相关推荐

上一篇:Go-Limiter RFC合规性:正确设置X-RateLimit headers的终极指南
下一篇:learnyounode 實作教學:用 Node.js http 與 URL 模組打造 JSON 時間 API 伺服器(http_json_api_server)

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询