优化基于FT6336驱动芯片的触摸屏响应速度(STM32F4)

目录

概述

1 触摸屏功能实现

1.1 扫描监测方式

1.2 中断监测方式

2  ST7796-LCD

2.1 引脚定义

2.1.1  ST7796-LCD

2.1.2 MCU IO与LCD PIN对应关系

2.1.3  MCU IO与Touch PIN对应关系

2.2 FT6336的寄存器

2.2.1 FT6336寄存器列表

2.2.2 寄存器功能介绍 

3 STM32Cube控制配置FT6336驱动

3.1 引脚配置

3.2 STM32Cube生成软件架构

4 程序实现

4.1 FT6336驱动程序

4.2 触摸屏功能

5 源代码

 5.1 FT6336驱动程序

5.2 触摸屏功能程序


概述

本文主要介绍使用FT6336的INT引脚的中断功能优化触摸屏功能的性能。将FT6336的INT与MCU的IO连接起来,且使能该IO的外部输入中断功能。笔者详细介绍了代码的实现过程,并重写了触摸屏的功能。

1 触摸屏功能实现

1.1 扫描监测方式

笔者使用的LCD上的触摸屏功能是基于FT6336芯片实现,该芯片与MCU之间I2C接口通信。MCU可通过实时读取FT6336的寄存器的值得到,当前的坐标点位。

采用如下架构设计程序:MCU需要实时读取FT6336采集到的点坐标,即使屏幕没有被触摸,读取数据的操作,依然被执行。

存在的问题:

1)MCU需要周期性的读取FT6336寄存器的值,即使没有触碰操作,该过程依然持续

2)在没有触碰屏幕的情况下也读取FT6336寄存器的值,而该值是没有任何意义的,这极大浪费MCU的时间

1.2 中断监测方式

FT6336控制芯片提供了一个INT中断引脚,当屏幕有触动发生时,INT引脚会发出一个低电平信号。MCU可以通过外部中断的方式监测该信号的状态。当中断发生时,说明屏幕被触动,此时,MCU需要读取FT6336寄存器中的点坐标值。

 

2  ST7796-LCD

2.1 引脚定义

2.1.1  ST7796-LCD

LCD的PIN引脚功能介绍

序号模块引脚引脚说明
1VCC屏电源正
2GND屏电源地
3LCD_CS液晶屏片选控制信号,低电平有效
4LCD_RST液晶屏复位控制信号,低电平复位
5LCD_RS液晶屏命令/数据选择控制信号

高电平:数据,低电平:命令

6SDI(MOSI)SPI总线写数据信号(SD卡和液晶屏共用)
7SCKSPI总线时钟信号(SD卡和液晶屏共用)
8LED液晶屏背光控制信号(如需要控制,请接引脚,如不需要控制,可以不接)
9SDO(MISO)SPI总线读数据信号(SD卡和液晶屏共用)
10CTP_SCL电容触摸屏IIC总线时钟信号(无触摸屏的模块不需连接)
11CTP_RST电容触摸屏复位控制信号,低电平复位(无触摸屏的模块不需连接)
12CTP_SDA电容触摸屏IIC总线数据信号(无触摸屏的模块不需连接)
13CTP_INT电容触摸屏IIC总线触摸中断信号,产生触摸时,输入低电平到主控(无触摸屏的模块不需连接)
14SD_CSSD卡片选控制信号,低电平有效(不使用SD卡功能,可不接)

实体LCD Port对应关系如下图所示

2.1.2 MCU IO与LCD PIN对应关系

STM32 PIN引脚LCD PIN引脚
PB5-MOSIMOSI
PB4-MISOMISO
PB3-SCKSCK
PB6CS
PB9RST
PB8RS

2.1.3  MCU IO与Touch PIN对应关系

STM32 PIN引脚touch PIN引脚
PH4I2C-SCK
PH5I2C-SDA
PH10INIT
PH9RST

2.2 FT6336的寄存器

2.2.1 FT6336寄存器列表

2.2.2 寄存器功能介绍 

1)设备模式配置

 2)姿势ID寄存器

 3)TD状态寄存器

4) Pn_XH寄存器

 5) Pn_XL寄存器

 6) Pn_YH寄存器

 7) Pn_YL寄存器

 8) Pn_WEIGHT寄存器 

  9) Pn_MISC寄存器 

3 STM32Cube控制配置FT6336驱动

3.1 引脚配置

1) i2c 引脚配置

其用于实现I2C驱动,实时读取FT6336寄存器的中

2) 中断和复位引脚配置

3) 中断函数使能

3.2 STM32Cube生成软件架构

1) 创建ft6336.c文件,编写ft6336的驱动程序

2) 创建usr_touch.c文件,实现触摸屏功能程序

4 程序实现

4.1 FT6336驱动程序

代码47~54:  复位FT6336

代码55~65:  写寄存器函数

代码67~77:  读寄存器函数

代码84行: 初始化IO

代码85行: 复位芯片

代码87行:读取芯片的ID

代码88行:比较ID

4.2  触摸点监测功能

代码95~100行:  外部中断的回调函数,检测中断是否发生

代码102~105行:清除触摸屏按下的标志

代码107~110行:清除触摸屏按下的标志

4.2 触摸屏功能

代码25~29行: 调用芯片初始化函数

代码39行:读取当前触摸屏状态

代码47行:读取触摸点

 代码110: 清除当前触摸状态

5 源代码

 5.1 FT6336驱动程序

创建FT6336.c,编写如下文件:

/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name            : ft6336.c
* Description          : I2C drive based on STM32F4
* STM32 HAL library ver: STM32Cube_FW_F4_V1.27.1
* 
******************************************************************************
* @attention
*
* Copyright (c) 2024~2029 mingfei.tang
* All rights reserved.
*
*************************************************************************
*/
/* USER CODE END Header */
#include "ft6336.h"

static int isPressed = 0;


static void touch_delay_us(uint32_t us)
{
    uint32_t i=0;
    
    while(us--){
        for(i=0;i<1000;i++);
    }
}

static void ft6336_TouchIO_Init( void )
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    RCC_TOUCH_CLK_ENABLE();
    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(GPIO_PORT_TOUCH, FT_RST_PIN,GPIO_PIN_RESET);

    /*Configure GPIO pin : RST */
    GPIO_InitStruct.Pin = FT_RST_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIO_PORT_TOUCH, &GPIO_InitStruct);
}

static void  ft6336_rest( void )
{
    FT_RST_L;
    touch_delay_us( 10 );
    FT_RST_H;
    touch_delay_us( 50000 );
}

uint8_t ft6336_WeReg( uint16_t regAdd, uint8_t *pData, uint16_t Size )
{
    HAL_StatusTypeDef status;
    
    status = HAL_I2C_Mem_Write( &hi2c2, FT6336_ADDR, regAdd, 
                                I2C_MEMADD_SIZE_8BIT, pData, Size, 1000);
    if( status == HAL_OK)
        return FT6336_OK;
    else
        return FT6336_ERROR; 
}

uint8_t ft6336_RdReg( uint16_t regAdd, uint8_t *pData, uint16_t Size )
{
    HAL_StatusTypeDef status;
    
    status = HAL_I2C_Mem_Read( &hi2c2, FT6336_ADDR, regAdd, 
                               I2C_MEMADD_SIZE_8BIT, pData, Size, 1000);
    if( status == HAL_OK)
        return FT6336_OK;
    else
        return FT6336_ERROR; 
}


int ft6336_Init( void )
{
    uint8_t id;
   
    ft6336_TouchIO_Init();
    ft6336_rest();
    // read chip id 
    ft6336_RdReg(FT_ID_G_FOCALTECH_ID,&id, 1);
    if(id != PANNEL_ID)
    {
        return FT_FALSE;
    }
    return FT_TRUE;
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if( GPIO_Pin == ft6336_irq_Pin){
        isPressed = 1;
    }
}

void  ft6336_clearPressed( void )
{
   isPressed = 0;
}

int ft6336_getPressed( void )
{
   return isPressed;
}

/* End of this file */

5.2 触摸屏功能程序

创建usr_touch.c,编写如下文件:

/**
  ******************************************************************************
  *                              (c) Copyright 2024, tangmingfei2013@126.com
  *                                      All Rights Reserved
  * @file    usr_touch.c
  * @author  mingfei tang
  * @version V1.0.0
  * @date    2018/03/25
  * @description:
    This source code and any compilation or derivative thereof is the proprietary
    information of mingfei.tang and is confidential in nature.
    Under no circumstances is this software to be combined with any
    Open Source Software in any way or placed under an Open Source License
    of any type without the express written permission of mingfei.tang
  ******************************************************************************
**/
/* Includes ------------------------------------------------------------------*/
#include "usr_touch.h"
#include "lcd_drv.h"

extern _lcd_dev lcddev;
const uint16_t touch_press_reg[2]={FT_TP1_REG,FT_TP2_REG};
static int touch_isOK;

void usr_touchInit( void )
{
   touch_isOK = ft6336_Init();
}

uint8_t usr_ScanTouchProcess( stru_pos *pPos)
{
    uint8_t buf[4];
    uint8_t i = 0;
    uint8_t set = FT_FALSE;;
    uint8_t pointNub = 0;
    static uint8_t cnt = 0;
    int isPressed;
    
    isPressed = ft6336_getPressed();
    if( touch_isOK == FT_FALSE || !isPressed )
        return set;
    
    cnt++;
    if((cnt%10)==0 || cnt<10)
    {
        // read number of touch points 
        ft6336_RdReg(FT_REG_NUM_FINGER,&pointNub,1);
         
        pointNub= pointNub&0x0f;
        if( pointNub && (pointNub < 3) )
        {
            cnt=0;
            // read the point value 
            pPos->status_bit.tpDown = 1;
            pPos->status_bit.tpPress = 1;
            pPos->status_bit.ptNum = pointNub;
            
            for( i=0; i < CTP_MAX_TOUCH; i++)
            {

                ft6336_RdReg( touch_press_reg[i], buf, 4 );
                if( pPos->status_bit.ptNum )
                {
                    switch(lcddev.dir)
                    {
                        case 0:
                            pPos->xpox[i]=((uint16_t)(buf[0]&0X0F)<<8)+buf[1];
                            pPos->ypox[i]=((uint16_t)(buf[2]&0X0F)<<8)+buf[3];
                            break;
                        case 1:
                            pPos->ypox[i]=lcddev.height-(((uint16_t)(buf[0]&0X0F)<<8)+buf[1]);
                            pPos->xpox[i]=((uint16_t)(buf[2]&0X0F)<<8)+buf[3];
                            break;
                        case 2:
                            pPos->xpox[i]=lcddev.width-(((uint16_t)(buf[0]&0X0F)<<8)+buf[1]);
                            pPos->ypox[i]=lcddev.height-(((uint16_t)(buf[2]&0X0F)<<8)+buf[3]);
                            break;
                        case 3:
                            pPos->ypox[i] = ((uint16_t)(buf[0]&0X0F)<<8)+buf[1];
                            pPos->xpox[i] = lcddev.width-(((uint16_t)(buf[2]&0X0F)<<8)+buf[3]);
                            break;
                    } 
                    printf("x[%d]:%d,y[%d]:%d\r\n",i,pPos->xpox[i],i,pPos->ypox[i]);
                }
            } 
            
            set = FT_TRUE;
            if( pPos->xpox[0]==0 && pPos->ypox[0]==0)
            {
                pPos->status = 0;
            }
        }
    }
    
    if( pPos->status_bit.ptNum == 0)
    { 
        if( pPos->status_bit.tpDown )
        {   
            pPos->status_bit.tpDown = 0;
        }
        else
        { 
            pPos->xpox[0] = 0xffff;
            pPos->ypox[0] = 0xffff;
            pPos->status = 0;
        }
    }
    
    // clear pressed status
    ft6336_clearPressed();
    
    if( cnt>240 )
       cnt=10;
    
    return set;
}


/* End of this file */ 

### 回答1: FT6336U是一款触摸屏控制器芯片,用于实现电子设备的触摸功能。它具有一些寄存器,用于控制和配置其各种功能。 首先,FT6336U有一个配置寄存器,可以用来设置控制器的工作模式和参数。通过写入不同的值到配置寄存器,可以实现不同的触摸模式,如单触摸、多触摸、手势识别等。 其次,FT6336U内置了一组用于存储触摸坐标的寄存器。当用户触摸屏幕时,触摸控制器会将触摸坐标信息写入这些寄存器中,应用程序可以读取这些寄存器来获取用户的触摸位置。 此外,FT6336U还有一些用于配置报警功能的寄存器。通过设置这些寄存器,可以实现当触摸状态变化时的报警功能,例如当有触摸产生或者触摸离开时触发报警。 最后,FT6336U还包含一些用于控制触摸扫描频率和灵敏度的寄存器。通过调整这些寄存器的值,可以实现不同的触摸扫描速度和灵敏度,以满足不同应用场景的需求。 总之,FT6336U的寄存器用于控制和配置触摸屏控制器的各种功能和参数,使得设备能够实现准确、敏感的触摸操作,并提供了一些额外的功能,如报警和手势识别等。 ### 回答2: FT6336U是一款触摸屏控制器芯片,广泛应用于手机、平板电脑以及一些智能设备中。该芯片内部包含了多个寄存器,用于配置和控制触摸屏的各项功能。 FT6336U的寄存器主要包括: 1. 控制寄存器:用于配置和控制触摸屏的模式、工作状态、触摸检测的阈值等参数。 2. 坐标寄存器:用于存储触摸点的坐标信息,包括触摸点的x坐标和y坐标。 3. 手势寄存器:用于识别触摸屏上的手势操作,如点击、滑动等,通过读取手势寄存器中的信息可以实现对不同手势的响应和处理。 4. 感应寄存器:用于检测触摸屏的触摸力度,通过读取感应寄存器可以获取触摸点的压力信息,实现一些特殊的触摸操作,如按压、放大缩小等。 5. ID寄存器:用于存储触摸屏控制器芯片的唯一识别ID,可以用来区分不同的触摸屏设备。 通过对FT6336U的寄存器进行配置和读取,可以实现对触摸屏的各项功能的调控和控制。同时,可以通过与其他硬件设备的连接,实现更丰富的触摸交互效果和功能,满足不同应用场景的需求。 总之,FT6336U寄存器是触摸屏控制器芯片内部的存储单元,通过配置和读取寄存器中的参数和信息,可以控制和调节触摸屏的各项功能,实现更好的触摸交互体验。 ### 回答3: ft6336u 寄存器是指FT6336U芯片中内部的寄存器。FT6336U是一款触摸屏控制器芯片,内部包含多个寄存器用于存储和管理各种控制和配置信息。 寄存器是计算机硬件中的一种存储设备,用于存储指令和数据。在FT6336U芯片中,寄存器用来存储触摸屏控制器的各种参数和状态信息。这些寄存器可以通过特定的地址来访问和修改。 FT6336U寄存器的作用包括但不限于以下几个方面: 1. 控制寄存器:用于设置和控制FT6336U的工作模式、扫描频率、触摸灵敏度等参数。通过修改控制寄存器的值,可以实现不同的操作模式和效果。 2. 数据寄存器:用于存储触摸屏传感器采集到的原始触摸数据。包括触摸点的坐标、压力、面积等信息。这些数据可以被处理后用于实现多点触控功能。 3. 状态寄存器:用于记录当前触摸屏控制器的状态,如是否有触摸事件发生、触摸点的数量等。通过读取状态寄存器的值,可以判断触摸屏当前的状态。 4. 校准寄存器:用于存储触摸屏的校准参数。触摸屏需要进行校准以确保准确的触摸操作,校准寄存器中存储了校准后的参数。 总之,FT6336U 寄存器是FT6336U芯片中存储和管理各种控制和配置信息的设备。通过对这些寄存器的设置和读取,可以实现触摸屏控制器的各种功能和操作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值