HAL库源码移植与使用之触摸屏

 

 

 你可以这么认为屏幕下有几条线引出来就是电阻屏

万用表与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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广药门徒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值