下面我们对这三款触摸IC做个介绍。
4.7.2 电容屏触摸IC---FT5X06
电容触摸IC都是支持多点触摸的,FT5X06支持多达10点触摸同时按下,并提供了I2C和SPI两种通信接口方式,开发板使用的是I2C通信接口。更多相关知识学习可以在这里下载FT5X06数据手册和应用手册:http://bbs.armfly.com/read.php?tid=16461 。
基于这个触摸芯片的触摸板最简单,我们开发板使用的是触摸芯片和触摸板一体的,使用时不需要配置,直接读取触摸数值即可(注意,这个芯片返回的就是实际的坐标值,比如显示屏的分辨率是800*480,那么返回的就是在这个分辨率范围内的实际坐标),读出数值后怎么跟emWin关联呢?这个是移植的关键,我们这里是通过函数GUI_PID_StoreState将FT5X06读出的实际坐标值存储到指针输入设备的FIFO中即可,默认情况下FIFO可以存储5组。具体实现代码如下(注意,我们这里并没有使用emWin支持的多点触摸功能,仅发一个触摸值给emWin,一般情况下已经够用):
复制代码
/*
*********************************************************************************************************
* 函 数 名: FT5X06_OnePiontScan
* 功能说明: FT5X06_OnePiontScan函数仅读取了电容触摸屏的一次触摸,在bsp_ts_ft5x06.h文件里面设置参数
* #define FT5X06_TOUCH_POINTS 1
* 专门用于emWin。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
extern GUI_PID_STATE State;
void FT5X06_OnePiontScan(void)
{
uint8_t buf[CFG_POINT_READ_BUF];
uint8_t i;
static uint8_t s_tp_down = 0;
uint16_t x, y;
if (g_tFT5X06.Enable == 0)
{
return;
}
if (FT5X06_PenInt() == 0)
{
return;
}
FT5X06_ReadReg(2, buf, 1); //--------------(1)
/* 判断是否有触摸数据 */
if ((buf[0] & 0x07) == 0)
{
if (s_tp_down == 1)
{
/* State.x和State.y的数值无需更新,State是全局变量,保存的就是最近一次的数值 */
s_tp_down = 0;
State.Pressed = 0;
GUI_PID_StoreState(&State); /* 释放 */
}
return;
}
/* 有触摸,读取完整的数据,这里读取了一次 */
FT5X06_ReadReg(0, buf, CFG_POINT_READ_BUF);
for (i = 0; i < FT5X06_TOUCH_POINTS; i++)
{
uint8_t pointid;
pointid = (buf[5 + 6*i]) >> 4;
if (pointid >= 0x0f)
{
break;
}
else
{
g_tFT5X06.X[i] = (int16_t)(buf[3 + 6*i] & 0x0F)<<8 | (int16_t)buf[4 + 6*i];
g_tFT5X06.Y[i] = (int16_t)(buf[5 + 6*i] & 0x0F)<<8 | (int16_t)buf[6 + 6*i];
g_tFT5X06.Event[i] = buf[0x3 + 6*i] >> 6;
g_tFT5X06.id[i] = (buf[5 + 6*i])>>4;
}
}
/* 检测按下 */
{
if ((g_tFT5X06.ChipID == 0x55)||(g_tFT5X06.ChipID == 0xa3)) /* 4.3寸 480 * 272 */
{
x = g_tFT5X06.Y[0];
y = g_tFT5X06.X[0];
/* 判断值域 */
if (x > 479)
{
x = 479;
}
if (y > 271)
{
y = 271;
}
}
else if (g_tFT5X06.ChipID == 0x0A) /* 5.0寸 800 * 480 */
{
x = g_tFT5X06.X[0];
y = g_tFT5X06.Y[0];
/* 判断值域 */
if (x > 799)
{
x = 799;
}
if (y > 479)
{
y = 479;
}
}
else /* id == 0x06 表示7寸电容屏(FT芯片) */
{
x = g_tFT5X06.X[0];
y = g_tFT5X06.Y[0];
/* 判断值域 */
if (x > 799)
{
x = 799;
}
if (y > 479)
{
y = 479;
}
}
}
if (s_tp_down == 0) //--------------(2)
{
s_tp_down = 1;
State.x = x;
State.y = y;
State.Pressed = 1;
GUI_PID_StoreState(&State);
}
else //--------------(3)
{
State.x = x;
State.y = y;
State.Pressed = 1;
GUI_PID_StoreState(&State);
}
#if 0
for (i = 0; i < CFG_POINT_READ_BUF; i++)
{
printf("%02X ", buf[i]);
}
printf("rn");
#endif
#if 0 /* 打印5个坐标点数据 */ //--------------(4)
printf("(%5d,%5d,%3d,%3d) ", g_tFT5X06.X[0], g_tFT5X06.Y[0], g_tFT5X06.Event[0], g_tFT5X06.id[0]);
printf("(%5d,%5d,%3d,%3d) ", g_tFT5X06.X[1], g_tFT5X06.Y[1], g_tFT5X06.Event[1], g_tFT5X06.id[1]);
printf("(%5d,%5d,%3d,%3d) ", g_tFT5X06.X[2], g_tFT5X06.Y[2], g_tFT5X06.Event[2], g_tFT5X06.id[2]);
printf("(%5d,%5d,%3d,%3d) ", g_tFT5X06.X[3], g_tFT5X06.Y[3], g_tFT5X06.Event[3], g_tFT5X06.id[3]);
printf("(%5d,%5d,%3d,%3d) ", g_tFT5X06.X[4], g_tFT5X06.Y[4], g_tFT5X06.Event[4], g_tFT5X06.id[4]);
printf("rn");
#endif
}
1. 从寄存器2读取一个数据,判断是否有触摸数据,如果没有触摸数据,而且变量标志s_tp_down = 1(此变量等于1表示之前处于触摸按下或者移动状态,如果等于0表示之前处于未被触摸状态),那么此时要给emWin发送触摸释放消息,这一步比较重要,切不可省略。如果变量标志s_tp_down= 0,直接退出即可。
2. 如果变量s_tp_down = 0表示之前处于未被触摸状态,这里设置此变量为1,并给emWin发送触摸按下消息和触摸坐标。
3. 如果变量不等于0(其实这里也就是1)表示之前处于按下状态,此时触摸处于移动状态,这里不用重复设置此变量了,但要给emWin发送触摸按下消息和触摸坐标(由于emWin没有移动状态标识,这里继续发送按下状态就可以)。
4. 这里预留的条件编译主要是方便调试阶段使用。 |