- 无人机
- 嵌入式
- 智能硬件
【免费下载链接】inav
INAV: Navigation-enabled flight control software
本文以
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.0 | 2015-08-03 | FT6X06 TS 驱动的首个正式发布 |
| V1.0.1 | 2016-05-03 | 新增对 FT6x36 触摸控制器的支持(FT6X36_ID = 0xCD,见 ft6x06.h) |
| V1.0.2 | 2017-04-07 | 更新注释,以适配 PDSC(Pack Description)文档生成流程 |
| V2.0.0 | 2019-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 目录 下的实际文件:
组件核心驱动文件:
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 组件驱动"函数指针表 + 对象句柄"的标准抽象方式。寄存器驱动文件:
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 由上层总线实现决定。配置文件模板:
ft6x06_conf_template.h这是一个可被用户修改的配置模板,使用时一般复制为ft6x06_conf.h。当前模板内容为:#define FT6X06_AUTO_CALIBRATION_ENABLED 0U #define FT6X06_MAX_X_LENGTH 800U #define FT6X06_MAX_Y_LENGTH 480UFT6X06_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_REG | 0x00 | 当前模式寄存器(R/W),0x00为工作模式、0x04为工厂校准模式 |
FT6X06_GEST_ID_REG | 0x01 | 手势 ID(只读) |
FT6X06_TD_STAT_REG | 0x02 | 触摸数据状态:当前有效触点数量(0~2) |
FT6X06_P1_XH/XL_REG | 0x03 / 0x04 | 触点 1 的 X 坐标(高字节含事件标志 EF)与低字节 |
FT6X06_P1_YH/YL_REG | 0x05 / 0x06 | 触点 1 的 Y 坐标(高字节含触点 ID)与低字节 |
FT6X06_P1_WEIGHT_REG | 0x07 | 触点 1 的压力(Weight) |
FT6X06_P1_MISC_REG | 0x08 | 触点 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_REG | 0x80 | — | 触摸检测阈值 |
FT6X06_TH_DIFF_REG | 0x85 | — | 滤波函数系数 |
FT6X06_CTRL_REG | 0x86 | 0x01 | 控制寄存器 |
FT6X06_TIMEENTERMONITOR_REG | 0x87 | 0x0A | 无触摸时从 Active 模式切入 Monitor 模式的等待时间 |
FT6X06_PERIODACTIVE_REG | 0x88 | — | Active(工作)模式下的上报周期 |
FT6X06_PERIODMONITOR_REG | 0x89 | 0x28 | Monitor(监视)模式下的上报周期 |
从源码结构可以推断,这两项周期与模式切换寄存器共同实现了 FT6X06 的功耗管理:有触摸时以较高频率上报,无触摸时降频进入 Monitor 模式以省电。
4.3 手势识别类寄存器
用于配置旋转、上下左右滑动与缩放手势的判定参数,与FT6X06_Gesture_Init_t结构体字段一一对应:
| 寄存器 | 地址 | 默认值 | 对应配置字段 |
|---|---|---|---|
FT6X06_RADIAN_VALUE_REG | 0x91 | 0x0A | Radian(旋转手势允许的最小角度) |
FT6X06_OFFSET_LR_REG | 0x92 | 0x19 | OffsetLeftRight(左右滑动最大偏移) |
FT6X06_OFFSET_UD_REG | 0x93 | 0x19 | OffsetUpDown(上下滑动最大偏移) |
FT6X06_DISTANCE_LR_REG | 0x94 | 0x19 | DistanceLeftRight(左右滑动最小距离) |
FT6X06_DISTANCE_UD_REG | 0x95 | 0x19 | DistanceUpDown(上下滑动最小距离) |
FT6X06_DISTANCE_ZOOM_REG | 0x96 | 0x32 | DistanceZoom(缩放手势最大距离) |
FT6X06_GestureConfig()正是将这 6 个字段依次写入上述 6 个寄存器(见 ft6x06.c)。手势 ID 的取值则定义在 ft6x06.h:上滑0x10、右滑0x14、下滑0x18、左滑0x1C、放大0x48、缩小0x49。
4.4 器件信息与模式类寄存器
| 寄存器 | 地址 | 说明 |
|---|---|---|
FT6X06_LIB_VER_H/L_REG | 0xA1 / 0xA2 | 固件库版本号高/低字节 |
FT6X06_CIPHER_REG | 0xA3 | 芯片选择信息(默认 0x06) |
FT6X06_GMODE_REG | 0xA4 | 中断模式寄存器:0x00轮询模式、0x01中断触发模式 |
FT6X06_PWR_MODE_REG | 0xA5 | 当前电源模式(只读) |
FT6X06_FIRMID_REG | 0xA6 | 固件版本 |
FT6X06_CHIP_ID_REG | 0xA8 | 芯片 ID:FT6X06 为0x11,FT6x36 为0xCD |
FT6X06_RELEASE_CODE_ID_REG | 0xAF | 发布代码版本 |
FT6X06_STATE_REG | 0xBC | 当前工作模式状态 |
其中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),其流程为:
- 将器件切换到工厂模式(
FT6X06_DEV_MODE_FACTORY= 0x04),写DEV_MODE_REG并回读校验,等待 300 ms; - 向
TD_STAT_REG写入0x04启动内部校准命令,再等待 300 ms; - 循环最多 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 层对原始坐标的完整后处理链:
- 调用
Ts_Drv->GetState()取得原始 X/Y; - 按
Ts_Ctx[Instance].Orientation中的方向位(TS_SWAP_XY、TS_SWAP_X、TS_SWAP_Y)做坐标交换/翻转; - 按屏宽高做比例缩放:
TouchX = x_oriented * Width / MaxX; - 做精度(Accuracy)过滤:若新坐标与上一次坐标的差值未超过 Accuracy,则沿用上一次坐标,避免抖动导致的光标跳变。
多点版本BSP_TS_Get_MultiTouchState()对两个触点执行同样的方向与精度处理(见 stm32h747i_eval_ts.c)。
7.3 中断模式集成
FT6X06 的 INT 引脚为低电平有效。BSP_TS_EnableIT()(stm32h747i_eval_ts.c)的调用链为:
- 通过 IO 扩展器(
BSP_IOEXPANDER_Init+BSP_IO_Init)把TS_INT_PIN配置为IO_MODE_IT_FALLING_EDGE(下降沿触发,上拉); - 调用
Ts_Drv->EnableIT()把 FT6X06 的GMODE置为中断触发模式; - 通过
HAL_EXTI_GetHandle / HAL_EXTI_RegisterCallback注册TS_EXTI_Callback; - 应用层实现弱函数
BSP_TS_Callback()即可在触摸事件到来时得到通知。
BSP_TS_DisableIT()则把引脚切回IO_MODE_OFF并调用Ts_Drv->DisableIT()回到轮询模式。这一实例也印证了上节所述:FT6X06 自身不提供中断状态寄存器,中断处理完全依赖 MCU 侧 EXTI。
八、集成要点与注意事项
综合 Release_Notes 与源码,在实际工程中集成该驱动时需要注意:
- 版本匹配:若从 V1.x 升级到 V2.0.0,接口不兼容,需同步更新调用代码;同时确保 BSP Common 版本不低于 v6.0.0。
- 配置文件:将
ft6x06_conf_template.h复制为ft6x06_conf.h并按屏的实际分辨率修改FT6X06_MAX_X_LENGTH / FT6X06_MAX_Y_LENGTH;按是否需要上电校准决定FT6X06_AUTO_CALIBRATION_ENABLED的取值。 - 总线实现:
FT6X06_IO_t中的WriteReg / ReadReg需由上层提供真实的 I2C/SPI 传输函数(地址、寄存器号、数据、长度四个参数),GetTick提供毫秒级时基用于校准延时。 - 器件 ID 校验:初始化阶段通过
FT6X06_ReadID区分 FT6X06(0x11)与 FT6x36(0xCD),据此确认挂载的是哪颗芯片。 - 中断模式: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
相关推荐
INAV 仓库 STM32H7 BSP 库中的 FT5336 触摸屏组件驱动:架构、寄存器映射与移植指南
INAV 仓库 STM32H7 BSP 库中的 FT5336 触摸屏组件驱动:架构、寄存器映射与移植指南 导读 FT5336 是 FocalTech 推出的电容
无人机嵌入式智能硬件INAV 仓库中的 STM32H7 BSP Common 组件驱动:从 ST 版本演进看外设驱动接口设计
INAV 仓库中的 STM32H7 BSP Common 组件驱动:从 ST 版本演进看外设驱动接口设计 导读 本文以 INAV 仓库中随 STM32CubeH
无人机嵌入式智能硬件INAV 仓库 STM32H7 BSP 组件 ADV7533 驱动全解析:DSI 到 HDMI 桥的显示与音频驱动发布说明及源码实现
INAV 仓库 STM32H7 BSP 组件 ADV7533 驱动全解析:DSI 到 HDMI 桥的显示与音频驱动发布说明及源码实现 本文以 INAV 仓库中随
无人机嵌入式智能硬件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考