发新帖我要提问
123
返回列表
[STM32F1]

STM32基础篇 触摸屏实验

[复制链接]
楼主: aizaixiyuanqian
手机看帖
扫描二维码
随时随地手机跟帖
aizaixiyuanqian|  楼主 | 2018-3-12 20:10 | 显示全部楼层
该程序就如上述所说,调用上一小节的 TOUCH_ReadData()读两次 X 轴和 Y 轴(如果
把 XY 轴,交叉来读,效果更好)。然后求取它们差值(求平均值在 TOUCH_ReadData()函
数中已经使用了),判断是否超过理想误差,然后求出它们两个的平均值,最后查看是否超
过 X 轴和 Y 轴的数据上限和数据下限。

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-3-12 20:12 | 显示全部楼层
我们使用 XPT2046 读取到了触摸屏的触摸位置之后,想要在 LCD 屏相对应的位置上进
行操作,我们还要将它转换成 LCD 屏的坐标值。比如说,我们在 LCD 屏(0, 0)坐标位置
按下,而读取到的物理坐标值(也就是 AD 值)为(100,200),那么我们想要在 LCD 屏(0, 0)
位置进行处理,将要将物理坐标(100, 200)转换成 LCD 屏坐标。
那如何转换呢?我们知道,XPT2046 的分辨率为 12 位,也就是说我们读取 X 轴的物理
坐标值(这里我们假设为:Px)和 Y 轴的物理坐标值(这里我们假设为:Py)的值肯定是
在 0~4096 之间。但是我们 LCD 彩屏 X 轴和 Y 轴的像素坐标确是 240X400。(这个值是
PZ6908L 开发板配的 3.5 寸彩屏像素,不过不管多少,我们明白原理就行,为了更好的表示,
在这里我们 LCD 彩屏 X 轴像素坐标我们假设为:Lcdx, LCD 彩屏 Y 轴像素坐标我们假设
为:Lcdy。)那么我们假设当(Px, Py) = (0, 0)时,正好 LCD 彩屏像素坐标的起始坐标(0, 0),
当(Px, Py) = (4096, 4096)时,正好 LCD 彩屏像素坐标的终止坐标(239, 399)。难么我们不难
看出触摸屏的物理坐标跟 LCD 彩屏像素坐标的对应关系为:
Factorx = Lcdx / Px;
Factory = Lcdy / Py;

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-3-12 20:13 | 显示全部楼层
那么我们就可以求出 Factorx 和 Factory,然后每次读取到 Px 和 Py 之后就可以讲它很轻
松的转换为 Lcdx 和 Lcdy。这是一个很简单的数学关系。
不过呢,事情没有那么理想化,我们在 LCD 像素坐标为(0, 0)读取的触摸屏物理坐标
值不一定是(0,0),在 LCD 像素坐标为最大时,也不一定读取到的是触摸屏的物理坐标最
大值。所以我们要进行一些数据校正,这也是屏幕校正的原因。

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-3-12 20:13 | 显示全部楼层
我们都知道每个触摸屏物理坐标值都能一一对应一个 LCD 彩屏上面的像素坐标值,也
就是它们是成比例关系的。现在我们知道 LCD 彩屏的 X 轴像素坐标最小值为 Lcdx1,我们
能显示的 LCD 彩屏的 X 轴像素坐标最大值为 Lcdx2。而我们在 LCD 彩屏像素坐标 X 轴最
小值处读取的触摸屏 X 轴物理坐标为 Px1,在 LCD 彩屏 X 轴像素坐标最大值处读取的触摸
屏 X 轴的物理坐标为 Px2。那么现在我们知道有一个触摸屏物理坐标值在 Px1 到 Px2 之间
的坐标值为 Px,那么和它对应的 Lcdx 的值是多少呢?
那么我们可以这么解:
Factorx = (Lcdx2 – Lcdx1) / (Px2 – Px1);
Lcdx = (Px – Px1) * Factorx;
那么就求得出 Lcdx 是多少了,对吧?
现在我们把它分解出来:
Lcdx = Px * Factorx – Px1 * Factorx;
然后将 Px1*Factorx 替换成一个变量 Offsetx。那么我们现在就可以得到 Lcdx 和 Px 之间
的对应关系式了。而关于 Y 轴也是同理,所以它们从物理坐标到像素坐标的转换关系式:
Lcdx = Px * Factorx – Offsetx;
Lcdy = Py * Factory – Offsety;
而求出 Factor 和 Offset 这两个数的过程就是校正程序应该做的工作了。

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-3-12 21:07 | 显示全部楼层
检测屏幕是否校正,没有的话进行校正,将校正值放置到 FLASH 中
static void TOUCH_Adjust(void)
{
uint16_t px[2], py[2], xPot[4], yPot[4];
float xFactor, yFactor;
/* 读取第一个点 */
if(TOUCH_ReadAdjust(LCD_ADJX_MIN, LCD_ADJY_MIN, &xPot[0], &yPot[0]))
{
return;
}
TOUCH_AdjDelay500ms();
/* 读取第二个点 */
if(TOUCH_ReadAdjust(LCD_ADJX_MIN, LCD_ADJY_MAX, &xPot[1], &yPot[1]))
{
return;
}
TOUCH_AdjDelay500ms();
/* 读取第三个点 */
if(TOUCH_ReadAdjust(LCD_ADJX_MAX, LCD_ADJY_MIN, &xPot[2], &yPot[2]))
{
return;
}
TOUCH_AdjDelay500ms();
/* 读取第四个点 */
if(TOUCH_ReadAdjust(LCD_ADJX_MAX, LCD_ADJY_MAX, &xPot[3], &yPot[3]))
{
return;
}
TOUCH_AdjDelay500ms();
/* 处理读取到的四个点的数据,整合成对角的两个点 */
px[0] = (xPot[0] + xPot[1]) / 2;
py[0] = (yPot[0] + yPot[2]) / 2;
px[1] = (xPot[3] + xPot[2]) / 2;
py[1] = (yPot[3] + yPot[1]) / 2;
/* 求出比例因数 */
xFactor = (float)LCD_ADJ_X / (px[1] - px[0]);
yFactor = (float)LCD_ADJ_Y / (py[1] - py[0]);
/* 求出偏移量 */
TouchAdj.xOffset = (int16_t)LCD_ADJX_MAX - ((float)px[1] * xFactor);
TouchAdj.yOffset = (int16_t)LCD_ADJY_MAX - ((float)py[1] * yFactor);
/* 将比例因数进行数据处理,然后保存 */
TouchAdj.xFactor = xFactor ;
TouchAdj.yFactor = yFactor ;
TouchAdj.posState = TOUCH_ADJ_OK;
FLASH_WriteData(&TouchAdj.posState, TOUCH_ADJ_ADDR, sizeof(TouchAdj));
}

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-3-12 21:07 | 显示全部楼层
扫描是否有触摸按下
uint8_t TOUCH_Scan(void)
{
if(TOUCH_PEN == 0) //查看是否有触摸
{
if(TOUCH_ReadXY(&TouchData.x, &TouchData.y)) //没有触摸
{
return 0xFF;
}
/* 根据物理坐标值,计算出彩屏坐标值 */
TouchData.lcdx = TouchData.x * TouchAdj.xFactor + TouchAdj.xOffset;
TouchData.lcdy = TouchData.y * TouchAdj.yFactor + TouchAdj.yOffset;
/* 查看彩屏坐标值是否超过彩屏大小 */
if(TouchData.lcdx > TFT_XMAX)
{
TouchData.lcdx = TFT_XMAX;
}
if(TouchData.lcdy > TFT_YMAX)
{
TouchData.lcdy = TFT_YMAX;
}
return 0;
}
return 0xFF;
}

使用特权

评论回复
dongnanxibei| | 2018-3-13 11:35 | 显示全部楼层
电阻屏很容易懂,电容屏是怎么回事

使用特权

评论回复
aizaixiyuanqian|  楼主 | 2018-3-14 17:27 | 显示全部楼层
dongnanxibei 发表于 2018-3-13 11:35
电阻屏很容易懂,电容屏是怎么回事

电容屏也是一样啊SPI

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则