当前位置: 首页 > news >正文

K230基础-获取触摸坐标

第二十二章 获取触摸坐标-K230触摸屏交互基础

🎯 本章目标
掌握在 K230 开发板(如 CanMV-K230)上通过 I2C 接口获取触摸屏坐标 的方法,学会使用 touch 模块或 I2C 协议读取 X、Y 坐标与触摸状态,实现触摸交互功能,为构建图形用户界面(GUI)打下基础。


1. 触摸屏硬件概述

1.1 常见触摸屏类型

类型说明是否适用于 K230
电阻式压力感应,需按压✅ 支持(较少)
电容式指尖感应,支持多点✅ 推荐(常见于 TFT 屏)

📌 K230 典型配置
TFT LCD + 电容触摸屏(如 2.8"、3.5" 屏),通过 I2C 传输触摸数据。


1.2 主流触摸控制器芯片

芯片接口I2C 地址特点
FT6236 / FT6336I2C0x38电容式,2点触控
GT911I2C0x140x5D多点触控,需配置
XPT2046SPI-电阻式,SPI 接口

本章重点FT6336 + I2C 获取触摸坐标(最常见)


2. 硬件连接

触摸屏引脚K230 引脚说明
SCLI2C1_SCLK(如 Pin3)I2C 时钟
SDAI2C1_SDA(如 Pin2)I2C 数据
GNDGND
VDD3.3V电源
INT可选 GPIO中断输出(通知有触摸)
RST可选 GPIO复位引脚

注意
触摸控制器与 OLED/EEPROM 共用 I2C 总线,需通过 i2c.scan() 确认地址。


3. 使用 touch 模块(CanMV 官方支持)

⚠️ 前提:固件需包含 touch 模块(非所有版本支持)

import touch
import time

3.1 初始化触摸屏

# 创建触摸对象
ts = touch.Touch(screen_width=320, screen_height=240)# 检查是否初始化成功
if ts.init():print("✅ 触摸屏初始化成功")
else:print("❌ 触摸屏初始化失败")raise Exception("Touch init failed")

3.2 读取触摸坐标

while True:# 获取触摸状态touch_points = ts.points()if touch_points:for point in touch_points:x, y, event_type, id = point# event_type: 0=按下, 1=释放, 2=移动# id: 触摸点 IDprint(f"触摸: ID={id}, X={x}, Y={y}, 事件={event_type}")else:# 无触摸passtime.sleep_ms(10)

输出示例

触摸: ID=0, X=120, Y=100, 事件=0
触摸: ID=0, X=125, Y=102, 事件=2
触摸: ID=0, X=0, Y=0, 事件=1

4. 手动 I2C 读取触摸数据(通用方法)

若无 touch 模块,可直接通过 I2C 读取触摸芯片寄存器。

4.1 FPIOA 映射与 I2C 初始化

from fpioa_manager import fm
from machine import I2C, Pin# I2C 引脚
I2C_SDA = 2
I2C_SCL = 3fm.register(I2C_SDA, fm.fpioa.I2C1_SDA)
fm.register(I2C_SCL, fm.fpioa.I2C1_SCL)i2c = I2C(I2C.I2C1, freq=400_000, sda=Pin(I2C_SDA), scl=Pin(I2C_SCL))

4.2 扫描 I2C 设备确认触摸芯片

devices = i2c.scan()
print("I2C 设备地址:", [hex(dev) for dev in devices])# FT6336 地址通常为 0x38
TOUCH_ADDR = 0x38
if TOUCH_ADDR not in devices:print(f"❌ 未检测到触摸芯片 @ 0x38")
else:print(f"✅ 检测到触摸芯片 @ 0x{TOUCH_ADDR:02X}")

4.3 读取 FT6336 触摸数据

# FT6336 寄存器地址
REG_TD_STATUS = 0x02  # 触摸点数
REG_P1_XH     = 0x03  # 第一个触摸点 X 高位def read_touch():# 读取状态寄存器try:data = i2c.readfrom_mem(TOUCH_ADDR, REG_TD_STATUS, 1)[0]num_points = data & 0x0Fif num_points > 0:# 读取第一个触摸点(2 个字节 X,2 个字节 Y)raw = i2c.readfrom_mem(TOUCH_ADDR, REG_P1_XH, 4)# 解析 X: [XH(高4位), XL] → 12位x = ((raw[0] & 0x0F) << 8) | raw[1]# 解析 Y: [YH(高4位), YL]y = ((raw[2] & 0x0F) << 8) | raw[3]return x, yelse:return None, Noneexcept:return None, None# 循环读取
while True:x, y = read_touch()if x is not None and y is not None:print(f"触摸坐标: X={x}, Y={y}")else:# print("无触摸")passtime.sleep_ms(50)

5. 坐标映射到屏幕显示区域

触摸屏原始坐标通常为 0~4095,需映射到屏幕分辨率(如 320x240)。

def map_touch_to_screen(x_raw, y_raw, screen_w=320, screen_h=240):x = int(x_raw * screen_w / 4095)y = int(y_raw * screen_h / 4095)return x, y# 使用
x_raw, y_raw = read_touch()
if x_raw:x, y = map_touch_to_screen(x_raw, y_raw)print(f"屏幕坐标: X={x}, Y={y}")

校准建议:实际使用中可能需手动校准映射系数。


6. 实战项目:触摸点显示在 TFT 屏上

# 假设已初始化 TFT 屏幕(见第13章)
import st7789
import vga1_8x8 as font# 清屏
tft.fill(0)
tft.text(font, "触摸测试", 100, 100, st7789.YELLOW)while True:x_raw, y_raw = read_touch()if x_raw and y_raw:# 映射到 240x240 屏幕x = int(x_raw * 240 / 4095)y = int(y_raw * 240 / 4095)# 限制范围x = max(0, min(239, x))y = max(0, min(239, y))# 显示触摸点tft.fill(0)  # 清屏tft.text(font, "Touch:", 10, 10, st7789.CYAN)tft.text(font, f"X={x}", 10, 30, st7789.YELLOW)tft.text(font, f"Y={y}", 10, 50, st7789.YELLOW)tft.pixel(x, y, st7789.RED)  # 画点tft.circle(x, y, 5, st7789.GREEN)  # 画圈else:tft.fill_rect(10, 70, 200, 20, 0)  # 清除提示

7. 高级技巧与优化

7.1 使用中断引脚(INT)减少轮询

from machine import PinINT_PIN = 12
fm.register(INT_PIN, fm.fpioa.GPIOHS0)
int_pin = Pin(INT_PIN, Pin.IN)# 仅在 int_pin.value() == 0 时读取触摸
if not int_pin.value():x, y = read_touch()

优势:降低 CPU 占用


7.2 触摸事件去抖与滤波

last_x, last_y = None, None
threshold = 5def smooth_touch(new_x, new_y):global last_x, last_yif last_x is None:last_x, last_y = new_x, new_yreturn new_x, new_y# 简单滤波x = (last_x * 2 + new_x) // 3y = (last_y * 2 + new_y) // 3last_x, last_y = x, yreturn x, y

8. 常见问题与调试

❌ 问题1:无法读取触摸数据

排查

  • I2C 地址是否正确?
  • 接线是否松动?
  • 电源是否稳定?

❌ 问题2:坐标跳变或不准

解决

  • 增加滤波(均值、中值)
  • 检查屏幕方向是否匹配
  • 手动校准映射参数

❌ 问题3:touch 模块导入失败

原因:固件未包含该模块
解决:使用 I2C 手动读取(通用方法)


9. 性能与限制

操作耗时
I2C 读取一次~2ms
坐标解析< 0.1ms
轮询频率建议 10~50ms 间隔

建议

  • 使用定时器周期读取
  • 结合 GUI 框架实现按钮、滑动等交互

本章你已掌握

  • 触摸屏硬件连接与 I2C 通信
  • 使用 touch 模块获取坐标
  • 手动 I2C 读取 FT6336 数据
  • 坐标映射与显示
  • 触摸去抖与优化

http://www.dtcms.com/a/461529.html

相关文章:

  • Linux应用--网络编程
  • 鸟哥的Linux私房菜 第三部分: 学习shell与shell script
  • 鸿蒙中 UDP 数据包发不出去?一文教你从权限到代码彻底排查!
  • 前端小白学习路线(参考)
  • 大连工业大学图书馆网站建设优化培训班
  • 浅谈 富文本编辑器
  • 有手机网站了还要微网站吗设计平台兼职
  • **发散创新:状态函数在编程中的深度应用与实现**在编程领域,状态函数是一个核心概
  • 【OCR】PaddleX
  • Python 元组与集合详解
  • 微信小程序的页面生命周期 以及onShow的应用场景
  • 微信小程序入门学习教程,从入门到精通,微信小程序核心 API 详解与案例(13)
  • 企业建站系统知识库管理系统方案
  • 购物网站的排版wordpress个人主页
  • 51c视觉~3D~合集7
  • 生鲜买菜商城APP:便捷生活,触手可及的新鲜体验
  • 网站seo去哪个网站找好做化妆品的网站有哪些
  • Java求职面试:从Spring Boot到Kafka的技术探讨
  • ChatGPT Agent深度总结:从“对话工具”到“超级助理”的AI革命
  • shell编程实战
  • 拟定网站建设合同的工作过程记录拍摄微电影公司
  • 厦门 公司网站建设绵阳做网站的公司
  • 【android 驱动开发十一】pinctrl 子系统
  • 【android驱动开发十二】内核子系统大概-进阶
  • vue前端面试题——记录一次面试当中遇到的题(2)
  • 【pyTorch】关于PyTorch的高级索引机制理解
  • c++ bug 函数定义和声明不一致导致出bug
  • 网站建设需求分析文档手机上制作ppt的软件
  • 推广网站怎么做能增加咨询南宁企业官网seo
  • MATLAB的无线传感器网络(WSN)算法仿真