【前言】
我在移植LVGL到STM32F769上时,前面移植好图像驱动,接着移植GT911的驱动,在移植过程中出现了一些问题,比如起先读取状态时,一直是状态码128,读取不到参数,后面又是读取的xy值对应不上,为此我将调试的过程记录如下:
【GT911地址】
GT911他是根据上电复位的时序不同,他的地址也是不一样的。我找到一份GT911的数据手册,他的记录如下:
也就是上电先把REST拉高,INT拉低,然后把INT拉高,延时100us后把REST拉高,5ms后把INT拉低,然后延时50ms后把INT设置为悬浮输入态。这直I2C地址写入地址为0x28,读的地址为0x29;
如果上电RESET为低电平,然后RESET拉高,延时55ms以后把INT转为悬浮输入,测他的地址为0xBA/0xBB。
【工程复位代码】
HAL_GPIO_WritePin(GTP_INT_GPIO_PORT, GTP_INT_GPIO_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(GTP_RST_GPIO_PORT, GTP_RST_GPIO_PIN, GPIO_PIN_RESET); HAL_Delay(100); /*复位为低电平,为初始化做准备*/ HAL_GPIO_WritePin(GTP_INT_GPIO_PORT, GTP_INT_GPIO_PIN, GPIO_PIN_SET); HAL_Delay(5); /*拉高一段时间,进行初始化*/ HAL_GPIO_WritePin(GTP_RST_GPIO_PORT, GTP_RST_GPIO_PIN, GPIO_PIN_SET); HAL_Delay(10); HAL_GPIO_WritePin(GTP_INT_GPIO_PORT, GTP_INT_GPIO_PIN, GPIO_PIN_RESET); HAL_Delay(50); /*把INT引脚设置为浮空输入模式,以便接收触摸中断信号*/ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Pin = GTP_INT_GPIO_PIN; GPIO_InitStructure.Mode = GPIO_MODE_INPUT; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Pull = GPIO_NOPULL; HAL_GPIO_Init(GTP_INT_GPIO_PORT, &GPIO_InitStructure); // HAL_NVIC_SetPriority(GTP_INT_EXTI_IRQ, 1, 1);/* 配置中断优先级 */ // HAL_NVIC_EnableIRQ(GTP_INT_EXTI_IRQ);/* 使能中断 */
这样就可以成功的将址设置为0x28/0x29了。
【读取代码】
void GTXXXX_Scanf(void) { uint8_t _temp; // 中间变量 GTXXXX_ReadReg(GT_GSTID_REG, &_temp, 1); // 读取状态寄存器 // 记录触摸状态 User_Touch.Touch_State = _temp; User_Touch.Touch_Number = (User_Touch.Touch_State & 0x0f); // 获取触摸点数 User_Touch.Touch_State = (User_Touch.Touch_State & 0x80); // 触摸状态 // 判断是否有触摸数据 switch (User_Touch.Touch_State) { case TOUCH__NO: // 没有数据 break; case TOUCH_ING: // 触摸中~后,有数据,并读出数据 for (uint8_t i = 0; i < User_Touch.Touch_Number; i++) { GTXXXX_ReadReg((GT_TPD_Sta + i * 8 + X_L), &_temp, 1); // 读出触摸x坐标的低8位 User_Touch.Touch_XY[i].X_Point = _temp; GTXXXX_ReadReg((GT_TPD_Sta + i * 8 + X_H), &_temp, 1); // 读出触摸x坐标的高8位 User_Touch.Touch_XY[i].X_Point |= (_temp << 8); GTXXXX_ReadReg((GT_TPD_Sta + i * 8 + Y_L), &_temp, 1); // 读出触摸y坐标的低8位 User_Touch.Touch_XY[i].Y_Point = _temp; GTXXXX_ReadReg((GT_TPD_Sta + i * 8 + Y_H), &_temp, 1); // 读出触摸y坐标的高8位 User_Touch.Touch_XY[i].Y_Point |= (_temp << 8); GTXXXX_ReadReg((GT_TPD_Sta + i * 8 + S_L), &_temp, 1); // 读出触摸大小数据的低8位 User_Touch.Touch_XY[i].S_Point = _temp; GTXXXX_ReadReg((GT_TPD_Sta + i * 8 + S_H), &_temp, 1); // 读出触摸大小数据的高8位 User_Touch.Touch_XY[i].S_Point |= (_temp << 8); } _temp = 0; GTXXXX_WriteReg(GT_GSTID_REG, &_temp, 1); // 清除数据标志位 break; } }
通过读取之后,通现调试发现,他的x/y坐标是反向的,所以需要在lvgl的坐标获取之后进行反转。但是返转之后,我的屏的x是240,他的最大值给出了320,y坐村读取的最大值为240,实际的最大值是320,因此,需要再进行处理。最后的转换与读取之后的代码如下:
/*Return true if the touchpad is pressed*/ static bool touchpad_is_pressed(void) { GTXXXX_Scanf(); if (User_Touch.Touch_Number>0) { return true; } else { return false; } } /*Get the x and y coordinates if the touchpad is pressed*/ /*Get the x and y coordinates if the touchpad is pressed*/ static void touchpad_get_xy(lv_coord_t *x, lv_coord_t *y) { if (User_Touch.Touch_Number > 0) { // 原始坐标 lv_coord_t original_x = User_Touch.Touch_XY[0].X_Point; lv_coord_t original_y = User_Touch.Touch_XY[0].Y_Point; // 调整坐标 (*y) = (original_x * 320) / 240; (*x) = (original_y * 240) / 320; printf("touchpad_get_xy:x=%d,y=%d\r\n", *x, *y); } else { (*x) = 0; (*y) = 0; } }
这里注意的是,只在获取是否有按下时,只需要GTXXXX_Scanf();一次,下面的getxy只需要读取就行了,如果再scanf一次就读不到数值了。
通过上面的处理,就可以正确到读取到数据,并且是正确的触摸了。通过串口打印如下:
前前后后调试昨晚搞到1点,早上到11点才搞好。特此记录在这篇文章中,希望能给在GT911调试的人有借鉴。
同时我这里还是周期读取的,有空还得搞一下中断读取,来减少CPU的工作量。