数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 1128|回复: 17

[STM] STM32驱动2.4寸UNO触摸屏

[复制链接]
发表于 2024-9-14 15:12:35 | 显示全部楼层 |阅读模式

就是这种屏,商家给的例程在arduino是可以使用触摸功能,但其他例程只能显示。如何使用触摸功能呢


一、显示
屏幕后已把的引脚标注好了,使用ILI9341驱动芯片,8080-I 8位总线接口。具体如何驱动不细说,参考商家例程





二、电阻触摸屏原理

1、此屏幕并没有使用触摸芯片,只是使用最原始的连接方式。由表面硬涂层、两个ITO 层、间隔点以及玻璃底层构成。两个ITO 层是触摸屏的关键结构,它们是涂有铟锡金属氧化物的导电层。两个ITO 层之间使用间隔点使两层分开,当触摸屏表面受到压力时,表面弯曲使得上层ITO 与下层ITO 接触,在触点处连通电路。两个ITO 涂层的两端分别引出X-、X+、Y-、Y+四个电极(见图),这是电阻屏最常见的四线结构。


2、当触摸屏被按下时,两个ITO 层相互接触,从触点处把ITO 层分为两个电阻,且由于ITO 层均匀导电,两个电阻的大小与触点离两电极的距离成比例关系,利用这个特性可检测坐标,这也正是电阻触摸屏名称的由来。
3、检测方法
计算X坐标时,在X+电极施加驱动电压Vref,X-极接地,所以X+与X-处形成了匀强电场,而触点处的电压通过Y+电极采集得到,由于ITO 层均匀导电,触点电压与Vref之比等于触点X 坐标与屏宽度(Width,象数值)之比。
X = Vy+ / Vref * Width
计算Y 坐标时,在Y+电极施加驱动电压Vref,Y-极接地,所以Y+与Y-处形成了匀强电场,而触点处的电压通过X+电极采集得到,由于ITO 层均匀导电,触点电压与Vref之比等于触点Y 坐标与屏高度(Height,象数值)之比。
Y = Vx+ / Vref * Height


三、寻找引脚
根据触摸屏原理
1、因为要测量电压,其中X+与Y+必须使用模拟引脚(J3中的其中两个)
2、这两个引脚与想对应的引脚之间必定存在一定电阻,对应引脚为X-与Y-
我的屏经测量LCD_CS/LCD_D1、LCD_RS/LCD_D0之间约有几百欧电阻值。锁定这两对引脚,至于与X/Y轴如何对应,驱动编写后测试一下就可以知道。

四、触摸驱动
因为显示与触摸同时使用4个引脚,因此要进行功能切换
1、设置X轴采样,把Y+与Y-设置为模拟输入,并设置Y+为ADC采集。X+高电平,X-低电平

void Touch_Y_Setup(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = ADC_YP_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(ADC_YP_GPIO_Port, &GPIO_InitStruct);
  
  GPIO_InitStruct.Pin = ADC_YM_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(ADC_YM_GPIO_Port, &GPIO_InitStruct);

  ADC_ChannelConfTypeDef sConfig = {0};
  sConfig.Channel = ADC_CHANNEL_8;
  //sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_41CYCLES_5;
  if (HAL_ADC_ChangeChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_GPIO_WritePin(ADC_XP_GPIO_Port, ADC_XP_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(ADC_XM_GPIO_Port, ADC_XM_Pin, GPIO_PIN_RESET);
}


2、采集数据,连续采集两次,如果两次差异大认为没有触摸动作(X+引脚悬空),如果差异不大(我设置AD值为20以内),认为有效,取两次平均值输出。

uint16_t Get_Value(void)
{
  uint16_t Value[2];
  uint8_t i;
  uint16_t Differ;
  for (i=0;i<2;i++)
  {
    HAL_ADC_Start(&hadc);                         // 启动ADC转换
    HAL_ADC_PollForConversion(&hadc, 10);         // 等待转换完成,时间为50ms
    Value = HAL_ADC_GetValue(&hadc);
  }
  HAL_ADC_Stop(&hadc);
  Differ = Value[0]>Value[1] ? Value[0]-Value[1] : Value[1]-Value[0];
  if ((Differ > ADC_DIFFER) || (Value[0] == 0) || (Value[1] ==0))
    return 0xFFFF;
  else
    return Value[0]+Value[1] >> 1;              // 取平均值
}


3、GPIO恢复显示设置

void Touch_Y_MspDeInit(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  HAL_GPIO_WritePin(ADC_YP_GPIO_Port, ADC_YP_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(ADC_YM_GPIO_Port, ADC_YM_Pin, GPIO_PIN_RESET);
  
  GPIO_InitStruct.Pin = ADC_YP_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(ADC_YP_GPIO_Port, &GPIO_InitStruct);
  
  GPIO_InitStruct.Pin = ADC_YM_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(ADC_YM_GPIO_Port, &GPIO_InitStruct);
}


4、触摸屏校准,获取直线公式

void TouchScr_Calibration(void)
{
  uint16_t Ad_X1,Ad_X2,Ad_Y1,Ad_Y2;
  _adc Calib_Datas[5];

  Calib_Datas[0] = Get_Point_Data(CROSS_CENTRE,CROSS_CENTRE);
  Calib_Datas[1] = Get_Point_Data(CROSS_CENTRE,LCD_H - CROSS_CENTRE);
  Calib_Datas[3] = Get_Point_Data(LCD_W - CROSS_CENTRE,LCD_H - CROSS_CENTRE);
  Calib_Datas[2] = Get_Point_Data(LCD_W - CROSS_CENTRE,CROSS_CENTRE);
  Calib_Datas[4] = Get_Point_Data(LCD_W>>1,LCD_H>>1);

  Ad_X1 = Calib_Datas[0].x+Calib_Datas[1].x>>1;
  Ad_X2 = Calib_Datas[2].x+Calib_Datas[3].x>>1;
  Ad_Y1 = Calib_Datas[0].y+Calib_Datas[2].y>>1;
  Ad_Y2 = Calib_Datas[1].y+Calib_Datas[3].y>>1;
  Delta_X = (Ad_X2-Ad_X1)/(LCD_W-2*CROSS_CENTRE);                     // 计算X方向每点的AD值
  Delta_Y = (Ad_Y2-Ad_Y1)/(LCD_H-2*CROSS_CENTRE);                     // 计算y方向每点的AD值
  X0 = Ad_X1 - Delta_X * CROSS_CENTRE;                    // X方向0点处AD值
  Y0 = Ad_Y1 - Delta_Y * CROSS_CENTRE;                   // Y方向0点处AD值
}


5、AD值反算坐标点

_position Cal_Pos(_adc Value)
{
  _position Pos;
  Pos.x = (uint16_t)((Value.x - X0) / Delta_X);                   // 反算X方向AD值对应的点位
  Pos.y = (uint16_t)((Value.y - Y0) / Delta_Y);                   // 反算Y方向AD值对应的点位
  return Pos;
}


五、效果
1、触摸屏校准


2、校准时获取的AD值,基本呈线性关系,中心点值可以忽略


3、简单手写效果,采样间隔有点大,所有断续情况稍严重。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
发表于 2024-9-14 15:16:56 | 显示全部楼层
找个开发板程序,直接修改下
回复 支持 反对

使用道具 举报

发表于 2024-9-14 15:33:26 | 显示全部楼层
能点屏幕的都是大神!
回复 支持 反对

使用道具 举报

发表于 2024-9-14 15:38:13 来自手机浏览器 | 显示全部楼层
这是在手搓触摸驱动啊!
回复 支持 反对

使用道具 举报

发表于 2024-9-14 15:55:36 | 显示全部楼层
谢谢分享,我也想学习一下
回复 支持 反对

使用道具 举报

发表于 2024-9-14 16:19:16 | 显示全部楼层
原理讲的通俗易懂
回复 支持 反对

使用道具 举报

发表于 2024-9-14 20:10:10 | 显示全部楼层
电容屏更有意思,我原来是电阻屏,后来重买电容屏,读出来的坐标已经处理过的,不用转换
回复 支持 反对

使用道具 举报

发表于 2024-9-14 20:11:20 | 显示全部楼层
11651189 发表于 2024-9-14 15:38
这是在手搓触摸驱动啊!

电阻屏触摸接口协议比较简单,电容屏直接用I2C更简单
回复 支持 反对

使用道具 举报

发表于 2024-9-15 09:08:02 | 显示全部楼层
这技术贴非常的实用。
回复 支持 反对

使用道具 举报

发表于 2024-9-15 09:25:53 | 显示全部楼层
各个厂商的驱动各有差异的
回复 支持 反对

使用道具 举报

发表于 2024-9-16 23:44:36 | 显示全部楼层
感谢分享


这行的 >>1 是啥意思?  注释说是 取平均值,没看懂









本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-9-17 13:41:31 | 显示全部楼层

右移一位,相当于除2
回复 支持 反对

使用道具 举报

发表于 2024-9-17 19:27:53 | 显示全部楼层
网络孤客 发表于 2024-9-17 13:41
右移一位,相当于除2


右移2位,是除4 吗
如果要除3 这样的奇数的时候怎么个移法?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-9-17 21:03:03 | 显示全部楼层
茶壹杯 发表于 2024-9-17 19:27
右移2位,是除4 吗
如果要除3 这样的奇数的时候怎么个移法?

是的
移位做除法只能用于除数为2、4、8...
如果除2,并进行四舍五入,先加1,再右移1位
如果除4,并进行四舍五入,先加2,再右移2位
回复 支持 反对

使用道具 举报

发表于 2024-9-17 21:11:45 | 显示全部楼层
网络孤客 发表于 2024-9-17 21:03
是的
移位做除法只能用于除数为2、4、8...
如果除2,并进行四舍五入,先加1,再右移1位


如果不管四舍五入  就不用先加1或2了对吗
回复 支持 反对

使用道具 举报

发表于 2024-9-17 23:07:54 | 显示全部楼层
电阻触摸的就那几款芯片,找个别家的参考下。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-9-18 08:24:10 | 显示全部楼层
茶壹杯 发表于 2024-9-17 21:11
如果不管四舍五入  就不用先加1或2了对吗

是的是的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-8-14 11:35 , Processed in 0.218401 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表