正点原子imx6ull裸机开发实战---GT1151触摸屏驱动与PWM背光调光详解

张开发
2026/4/15 13:07:14 15 分钟阅读

分享文章

正点原子imx6ull裸机开发实战---GT1151触摸屏驱动与PWM背光调光详解
1. 触摸屏驱动开发实战从硬件混淆到精准控制第一次拿到正点原子4.3寸屏套件时我完全没想到会在触摸芯片型号上栽跟头。官方资料和视频教程都明确标注使用GT9147芯片但实际焊接在PCB上的却是GT1151Q——这个细节差异导致我浪费了两天时间调试不通。相信很多开发者都遇到过类似问题今天我就把完整的排查过程和驱动编写经验分享给大家。GT1151Q是Goodix公司推出的电容式触摸控制器通过I2C接口与主控通信支持五点触控。与GT9147相比它的寄存器映射和初始化时序有显著区别。最明显的特征是设备地址固定为0x147位地址而GT9147通常使用0x5D或0x14取决于ADDR引脚电平。当发现读取的产品ID不符合预期时建议先用显微镜确认芯片丝印这是最直接的验证方法。硬件连接方面需要注意三个关键点一是I2C信号线必须配置SION位通过IOMUXC_SetPinMux的最后一个参数设置确保能读取物理引脚真实电平二是中断引脚建议配置为下降沿触发因为GT1151Q在数据就绪时会拉低INT信号三是复位时序要严格遵守手册要求典型操作是拉低至少1ms后再释放。2. GT1151Q驱动代码深度解析2.1 寄存器操作基础框架驱动代码的核心是I2C读写函数这里采用NXP官方推荐的传输结构体方式。特别要注意GT1151Q的寄存器地址是16位的需要设置subaddressSize2。以下是经过验证的读写函数void GT1151_ReadReg(u16 reg, u8 len, u8 *data) { i2c_transfer tran { .slaveAddress GT1151_ADDR, .direction kI2C_Read, .subaddress reg, .subaddressSize 2, .data data, .dataSize len }; I2C_transfer(I2C2, tran); }读取触摸坐标时需要先检查GSTID寄存器(0x814E)的最高位该位为1表示有新数据。每个触摸点的坐标存储在独立的寄存器组中TP1_REG到TP5_REG每个点占用4字节包含X/Y坐标值。实测发现坐标数据采用大端格式需要先将高字节左移8位再与低字节相加。2.2 中断处理优化技巧GT1151Q的中断行为有个重要特性如果主控没有及时读取坐标数据芯片会持续产生中断脉冲但不会更新坐标寄存器内容。这要求我们在中断服务函数中必须完成两件事快速读取所有有效触点数据并及时清除GSTID寄存器状态。推荐的中断处理流程如下进入中断后立即禁用GPIO中断防止重入读取GSTID寄存器获取当前触点数量循环读取各触点的坐标数据向GSTID寄存器写入0清除状态位重新使能中断并清除标志void gpio1_io9_irqhandler(void *param) { gpio_disableint(GPIO1, 9); // 立即禁用中断 touch_info *info (touch_info*)param; GT1151_read_point(info); // 读取坐标数据 gpio_clearintflags(GPIO1, 9); gpio_enableint(GPIO1, 9); // 重新使能 }3. PWM背光控制全攻略3.1 硬件电路设计要点i.MX6ULL的PWM1输出引脚(GPIO1_IO08)通常直接连接屏幕背光驱动电路。在设计PCB时要注意背光LED串的电流需通过采样电阻转换为电压反馈PWM频率建议设置在1-10kHz之间避免可闻噪声如果使用外部MOSFET驱动要确保栅极驱动能力足够实际测量发现当PWM占空比低于5%时部分屏幕会出现闪烁现象。这是因为背光驱动芯片有最小导通时间要求解决方法是在软件中设置最小占空比限制void PWM1_Set_BLVal(u16 val) { if(val 5) val 5; // 设置最小亮度阈值 if(val 100) val 100; BGlight_param val; }3.2 FIFO空中断的妙用i.MX6ULL的PWM控制器有个独特功能当FIFO为空时会触发中断。我们可以利用这个特性实现动态调光。具体实现步骤初始化时向FIFO写入4个初始值在中断服务函数中检测PWMSR[3]标志位当FIFO空时立即写入新的占空比值清除中断标志这种机制可以确保PWM波形连续无抖动特别适合需要平滑调光的场景。以下是关键代码片段void PWM1_BGlight_DutyRatio(void *param) { if(PWM1-PWMSR (1 3)) { // FIFO空标志 u16 fifoval *((u16 *)param); for(int i0; i4; i) { PWM1-PWMSAR fifoval; // 填充FIFO } PWM1-PWMSR | (1 3); // 清除标志 } }4. 调试过程中的血泪教训第一次上电测试时触摸完全无反应。用逻辑分析仪抓取I2C波形后发现SCL频率高达400kHz而GT1151Q在默认配置下只支持100kHz。解决方法是在初始化时先以低速模式配置芯片然后再切换为高速模式。另一个坑是关于IOMUX配置的。最初没有设置SION位导致I2C始终无法产生ACK。后来查阅参考手册才明白当引脚被配置为I2C功能时必须开启SION才能读取实际电平状态。正确的配置代码如下IOMUXC_SetPinMux(IOMUXC_UART5_RX_DATA_I2C2_SDA, 1); // 最后一个参数1表示开启SION IOMUXC_SetPinMux(IOMUXC_UART5_TX_DATA_I2C2_SCL, 1);背光调试时遇到PWM输出不稳定的问题最终发现是时钟配置错误。i.MX6ULL的PWM模块可以选择多种时钟源我们需要根据实际需求计算分频系数。一个实用的公式是 PWM频率 时钟源频率 / (分频系数 * (PWMPR 1))例如使用IPG_CLK66MHz要实现1kHz PWM且PWMPR99时分频系数应设置为66MHz/(1kHz*100)660取整后得到clkDiv659。

更多文章