你可以这么认为屏幕下有几条线引出来就是电阻屏
万用表与VREF共地,你按下屏幕ITO层的导电体与电压层接触,该点就会带电,先测相对于y轴为电压表时的v值,再测相对于x轴为电压表时v值,又因为电阻片均匀供电,就可以用上面的公式算x,y长度,所以他每次只能检测一个被触摸点,如果大于一个点被触摸,它的x,y电压就会混乱,导致原本第一个点的v1值要减去第二个点的v2值然后v1-v2等于电压表测得值,使得两个点都测不到
就是驱动级x发射磁感线y级接收,一旦有电容体例如手指接触,就会使得磁感线混乱,充电时间变大,就可以得到哪里被触摸了。
这些芯片同种的话是代码通用的,比如gt9147 911 9147s 1151 ft5426他们一起协议一样指令一样
触摸屏ic
屏幕方向是指显示时(0,0)坐标向两边阔开的方向,x y方向指x-指向x+,y-指向y+的方向,屏幕显示方向是你自己设定的,一般都是竖屏时往右为x往下为y,但是会有竖屏显示和横屏显示之分,触摸屏方向现在看来是已被厂家固定,不知道用户能不能改,触摸屏方向就是竖屏时往右为x往下为y,那就要把方向确定好,方向相同就选
否则原本的x变为y,y变为x就选另一个
你也可以用代码来代替指令,竖横屏都用前者,只是代码会根据竖横显示而改变
校准实际上就是你用手点击四个分布于长方形顶点,这样就可以算出lcd屏幕的顶点在哪,也就可以知道里面点怎么分布
采用五点法,在lcd上顶点和中点画五个点,用手点击这五个点,把触摸屏传回来的数据x1 减去同y的x2得到s1,再把触摸屏传回来的数据y1 减去同x的y2得到s2,然后用相同的方法在显示屏也算出s3 s4,把s1/s3 s2/s4得到扩张比,用该扩张比算触摸屏相对于显示屏的点
电容触摸ic
就是不停组合代表不同地址选择
0x8047-0x8100有官方给的数组配置,你直接利用可连续输入读取功能连续输入读取就行,里面有配置屏幕大小等配置,但是正点原子里的代码没有体现,我认为厂家已经设定好了,不知道用户能不能改,它的默认触摸原点是在屏幕竖屏左上角,你也可以写代码自己测测
你可以读取状态寄存器的值看是否被触摸,也可以读取中断引脚看是否被触摸
Bit0-Bit3是用来记录有几个点被触摸了的,从这可以看出,最多有2^4,也就是说一次最多只有16个点可以被记录
读取完状态寄存器后要bit7置0或全部寄存器置零
最多可以记16个触摸点,存储有16个地方,触点1为0x8150,触点2为0x8158】,触点3为0x8158...开头,只需读取前四个字节就行
x y坐标的数值是一个16位数
电容屏
单点模式示例
#include "string.h"
#include "./BSP/TOUCH/ctiic.h"
#include "./BSP/TOUCH/gt9xxx.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
/* return 1fail 0succeed */
uint8_t gt9xxx_wr_reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
uint8_t ret = 0;
ct_iic_start();
ct_iic_send_byte(GT9XXX_CMD_WR);
ct_iic_wait_ack();
ct_iic_send_byte(reg >> 8);
ct_iic_wait_ack();
ct_iic_send_byte(reg & 0xFF);
ct_iic_wait_ack();
for (uint8_t i = 0; i < len; i++)
{
ct_iic_send_byte(buf[i]);
ret = ct_iic_wait_ack();
if (ret) break;
}
ct_iic_stop();
return ret;
}
void gt9xxx_rd_reg(uint16_t reg, uint8_t *buf, uint8_t len)
{
uint8_t i;
ct_iic_start();
ct_iic_send_byte(GT9XXX_CMD_WR);
ct_iic_wait_ack();
ct_iic_send_byte(reg >> 8);
ct_iic_wait_ack();
ct_iic_send_byte(reg & 0xFF);
ct_iic_wait_ack();
ct_iic_start();
ct_iic_send_byte(GT9XXX_CMD_RD);
ct_iic_wait_ack();
for (i = 0; i < len; i++)
{
/* 1:ack 0:nack */
buf[i] = ct_iic_read_byte(i == (len - 1)?0:1);
}
ct_iic_stop();
}
uint8_t gt9xxx_init(void)
{
uint8_t temp[5];
GPIO_InitTypeDef gpio_init_struct;
GT9XXX_RST_GPIO_CLK_ENABLE(); /* RST引脚时钟使能 */
GT9XXX_INT_GPIO_CLK_ENABLE(); /* INT引脚时钟使能 */
gpio_init_struct.Pin = GT9XXX_RST_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(GT9XXX_RST_GPIO_PORT, &gpio_init_struct); /* 初始化RST引脚 */
gpio_init_struct.Pin = GT9XXX_INT_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(GT9XXX_INT_GPIO_PORT, &gpio_init_struct); /* 初始化INT引脚 */
ct_iic_init(); /* 初始化电容屏的I2C总线 */
/* 通讯地址 0x28/0x29 */
HAL_GPIO_WritePin(GT9XXX_INT_GPIO_PORT, GT9XXX_INT_GPIO_PIN, GPIO_PIN_SET); /* INT输出高电平 */
GT9XXX_RST(0); /* 复位 */
delay_ms(10);
GT9XXX_RST(1); /* 释放复位 */
delay_ms(10);
/* INT引脚模式设置, 输入模式, 浮空输入 */
gpio_init_struct.Pin = GT9XXX_INT_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */
gpio_init_struct.Pull = GPIO_NOPULL; /* 不带上下拉,浮空模式 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(GT9XXX_INT_GPIO_PORT, &gpio_init_struct); /* 初始化INT引脚 */
/* 读取ID */
delay_ms(100);
gt9xxx_rd_reg(GT9XXX_PID_REG, temp, 4);
temp[4] = 0;
printf("CTP ID:%s\r\n",temp);
/* 软复位 */
temp[0] = 0x02;
gt9xxx_wr_reg(GT9XXX_CTRL_REG, temp, 1);
delay_ms(10);
/* 正常读取坐标 */
temp[0] = 0x00;
gt9xxx_wr_reg(GT9XXX_CTRL_REG, temp, 1);
return 0;
}
void gt9xxx_scan(void)
{
uint8_t mode = 0;
uint8_t i;
uint8_t buf[4];
uint16_t x,y;
/* 读取状态寄存器 */
gt9xxx_rd_reg(GT9XXX_GSTID_REG, &mode, 1);
if ((mode & 0x80) && ((mode & 0xF) <= 5))
{
i = 0;
gt9xxx_wr_reg(GT9XXX_GSTID_REG, &i, 1); /* 清楚标记 */
}
if ((mode & 0xF) && ((mode & 0xF) <= 5))
{
gt9xxx_rd_reg(GT9XXX_TP1_REG, buf, 4);
x = ((uint16_t)buf[1] << 8) + buf[0];
y = ((uint16_t)buf[3] << 8) + buf[2];
printf("x:%d y:%d\r\n",x,y);
}
}
#ifndef __GT9XXX_H
#define __GT9XXX_H
#include "./SYSTEM/sys/sys.h"
/******************************************************************************************/
/* GT9XXX INT 和 RST 引脚 定义 */
#define GT9XXX_RST_GPIO_PORT GPIOF
#define GT9XXX_RST_GPIO_PIN GPIO_PIN_11
#define GT9XXX_RST_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOF_CLK_ENABLE(); }while(0) /* PF口时钟使能 */
#define GT9XXX_INT_GPIO_PORT GPIOF
#define GT9XXX_INT_GPIO_PIN GPIO_PIN_10
#define GT9XXX_INT_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOF_CLK_ENABLE(); }while(0) /* PF口时钟使能 */
/******************************************************************************************/
/* 与电容触摸屏连接的芯片引脚(未包含IIC引脚)
* IO操作函数
*/
#define GT9XXX_RST(x) do{ x ? \
HAL_GPIO_WritePin(GT9XXX_RST_GPIO_PORT, GT9XXX_RST_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(GT9XXX_RST_GPIO_PORT, GT9XXX_RST_GPIO_PIN, GPIO_PIN_RESET); \
}while(0) /* 复位引脚 */
#define GT9XXX_INT HAL_GPIO_ReadPin(GT9XXX_INT_GPIO_PORT, GT9XXX_INT_GPIO_PIN) /* 读取做的引脚 */
/* IIC读写命令 */
#define GT9XXX_CMD_WR 0X28 /* 写命令 */
#define GT9XXX_CMD_RD 0X29 /* 读命令 */
/* GT9XXX 部分寄存器定义 */
#define GT9XXX_CTRL_REG 0X8040 /* GT9XXX控制寄存器 */
#define GT9XXX_CFGS_REG 0X8047 /* GT9XXX配置起始地址寄存器 */
#define GT9XXX_CHECK_REG 0X80FF /* GT9XXX校验和寄存器 */
#define GT9XXX_PID_REG 0X8140 /* GT9XXX产品ID寄存器 */
#define GT9XXX_GSTID_REG 0X814E /* GT9XXX当前检测到的触摸情况 */
#define GT9XXX_TP1_REG 0X8150 /* 第一个触摸点数据地址 */
#define GT9XXX_TP2_REG 0X8158 /* 第二个触摸点数据地址 */
#define GT9XXX_TP3_REG 0X8160 /* 第三个触摸点数据地址 */
#define GT9XXX_TP4_REG 0X8168 /* 第四个触摸点数据地址 */
#define GT9XXX_TP5_REG 0X8170 /* 第五个触摸点数据地址 */
/* 函数 */
void gt9xxx_scan(void);
uint8_t gt9xxx_init(void);
#endif