当前位置:首页 > 工业控制 > 工业控制
[导读] 工业HMI(基于Linux,如i.MX6ULL/RK3568+Qt)的触摸屏驱动移植,难点不在“点亮”,而在“抗干扰”——车间里变频器、电机、焊机产生的电磁噪声会耦合进触摸屏的I2C/SPI接口,导致坐标跳变、误触发。下面以Goodix GT9271电容触摸屏(I2C接口,5点触控)在i.MX6ULL上的移植和校准为例。

工业HMI(基于Linux,如i.MX6ULL/RK3568+Qt)的触摸屏驱动移植,难点不在“点亮”,而在“抗干扰”——车间里变频器、电机、焊机产生的电磁噪声会耦合进触摸屏的I2C/SPI接口,导致坐标跳变、误触发。下面以Goodix GT9271电容触摸屏(I2C接口,5点触控)在i.MX6ULL上的移植和校准为例。

一、驱动移植:设备树配置与内核编译

GT9271是主流工业触控芯片,Linux内核自带了goodix.c驱动。移植只需三步:

1. 设备树节点:在i2c2总线下添加GT9271,配置中断引脚和复位引脚。

&i2c2 {

   clock-frequency = <400000>;

   pinctrl-names = "default";

   pinctrl-0 = <&pinctrl_i2c2>;

   status = "okay";


   gt9271@5d {

       compatible = "goodix,gt9271";

       reg = <0x5d>;

       interrupt-parent = <&gpio1>;

       interrupts = <13 IRQ_TYPE_EDGE_FALLING>;

       irq-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;

       reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;

       touchscreen-size-x = <1024>;

       touchscreen-size-y = <600>;

       touchscreen-inverted-x;

       touchscreen-swapped-xy;

   };

};

1. 内核配置:Device Drivers → Input device support → Touchscreens → Goodix GT9xx based touchscreens 设为<*>

2. 编译并替换dtb:make dtbs,拷贝到板子重启。dmesg | grep goodix 看到Goodix GT9271 device found即成功。

二、抗干扰触摸校准:去抖与滤波

工业环境下触摸屏的原始坐标常有毛刺。驱动层可以做两点处理:

1. 硬件滤波(I2C寄存器配置)

GT9271内部有滤波寄存器,上电时写入:

static int gt9271_set_filter(struct i2c_client *client) {

   u8 buf[3];

   // 配置去抖阈值(0x8047寄存器,值越大去抖越强)

   buf[0] = 0x80; buf[1] = 0x47; buf[2] = 0x0A; // 10次连续采样一致才上报

   i2c_master_send(client, buf, 3);

   // 配置噪声抑制(0x8048)

   buf[1] = 0x48; buf[2] = 0x03; // 中等抑制

   i2c_master_send(client, buf, 3);

   return 0;

}

2. 软件滑动平均(应用层或内核层)

在输入子系统中对坐标做中值滤波,消除单点跳变:

// 触摸点结构体维护最近5个坐标,取中值

#define MEDIAN_WINDOW 5

static int median_filter(int *buffer, int len) {

   int tmp[MEDIAN_WINDOW];

   memcpy(tmp, buffer, len * sizeof(int));

   // 简单排序取中

   for (int i = 0; i < len-1; i++)

       for (int j = i+1; j < len; j++)

           if (tmp[i] > tmp[j]) { int t = tmp[i]; tmp[i] = tmp[j]; tmp[j] = t; }

   return tmp[len/2];

}

在goodix_ts_report()函数中调用该滤波,再将结果上报input子系统。

三、校准流程:tslib或手动四点校准

虽然电容屏一般免校准,但工业HMI因面板厚度、贴合误差可能需要校准。使用tslib的ts_calibrate工具,生成pointercal文件。如果不想依赖tslib,可以自己实现四点校准:

// 四点校准:屏幕四个角显示十字,记录触摸坐标与物理坐标的映射

typedef struct { int x, y; } point_t;

point_t screen_pts[4] = {{50,50},{974,50},{50,550},{974,550}}; // 物理坐标

point_t touch_pts[4]; // 用户点击后记录


// 计算仿射变换矩阵(简化:仅缩放和平移)

float scale_x = (float)(screen_pts[3].x - screen_pts[0].x) / (touch_pts[3].x - touch_pts[0].x);

float offset_x = screen_pts[0].x - touch_pts[0].x * scale_x;

// 同理Y

将scale和offset写入配置文件,Qt的QWS_MOUSE_PROTO或libinput可以加载。

四、调试与验证

• 查看原始坐标:evtest /dev/input/event1 观察触摸点,看是否有跳变。如果跳变频繁,增大硬件去抖寄存器值或软件窗口大小。

• 抗干扰测试:在触摸屏附近运行手持电钻(模拟变频器干扰),触摸不应误触发。如果误触,检查I2C走线屏蔽和电源滤波。

• 校准精度:点击屏幕四角和中心,实际坐标与期望坐标偏差应<3mm。

五、三个翻车高发点

• 中断引脚没配上拉:GT9271中断是开漏输出,外部必须上拉(4.7kΩ到3.3V),否则中断丢失导致触摸无响应。

• I2C时钟频率太高:工业环境长走线,400kHz可能通信不稳定。降到100kHz或200kHz,并在SDA/SCL加10pF电容滤波。

• 复位时序不对:GT9271上电后需要先拉低复位引脚>10ms,再拉高,然后等待>100ms才能访问I2C。驱动中goodix_reset()函数必须满足该时序。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭