优化基于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 */ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/737482.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python unoconv库:文档转换神器

更多Python学习内容&#xff1a;ipengtao.com unoconv&#xff08;Universal Office Converter&#xff09;是一个命令行工具&#xff0c;用于使用LibreOffice将不同格式的文档相互转换。通过unoconv&#xff0c;用户可以轻松地将文档从一种格式转换为另一种格式&#xff0c;例…

Android使用DevRing框架搭建数据库实体类以及使用

一、引用DevRing依赖 //导入DevRing依赖implementation com.ljy.ring:devring:1.1.8创建数据库表的依赖implementation org.greenrobot:greendao:3.2.2 // add libraryimplementation org.greenrobot:greendao-generator:3.0.0 二、修改工程目录下的.idea->gradle.xml文件&…

【Java算法】滑动窗口 下

​ ​ &#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【算法工作坊】算法实战揭秘 &#x1f98c;一.水果成篮 题目链接&#xff1a;904.水果成篮 ​ 算法原理 算法原理是使用“滑动窗口”&#xff08;Sliding Window&#xff09;策略&#xff0c;结…

SD卡无法读取:原因解析与数据恢复策略

一、SD卡无法读取的尴尬场景 在数字化日益普及的今天&#xff0c;SD卡作为便携式存储设备&#xff0c;广泛应用于各类电子设备中。然而&#xff0c;当您急需访问SD卡中的数据时&#xff0c;却发现设备无法读取SD卡&#xff0c;这无疑是一个令人沮丧的场景。SD卡无法读取可能表…

SUSE linux 15的网络管理

1 手工配置网络 wicked提供了一种新的网络配置框架。自SUSE 12起&#xff0c;SUSE使用了新的网络管理工具wicked&#xff0c;这个是区别与其他常见发行版的。常见的发行版目前大多使用的是NetworkManager服务进行网络管理。 1.1 wicked网络配置 传统网络接口管理面临的挑战之…

段,页,段页,三种内存(RAM)管理机制分析

段&#xff0c;页&#xff0c;段页 是为实现虚拟内存而产生的技术。直接使用物理内存弊端&#xff1a;地址空间不隔离&#xff0c;内存使用效率低。 段 段&#xff1a;就是按照二进制文件的格式&#xff0c;在内存给进程分段&#xff08;包括堆栈、数据段、代码段&#xff09;。…

Python 算法交易实验72 QTV200第一步: 获取原始数据并存入队列

说明 最近的数据流往前进了一步&#xff0c;我觉得基本可以开始同步的推进QTV200了。上次规划了整体的数据流&#xff0c;现在开始第一步。 内容 1 结构位置 这是上次的总体图&#xff1a; 以下是这次要实现的一小部分&#xff1a; 从结构上&#xff0c;这个是整体数据流的…

每日AI资讯-20240622

1. 可灵AI全新功能上线&#xff01; 可灵AI全新功能上线&#xff01;图生视频和视频续写来啦&#xff01; 图生视频&#xff1a;上传任意图片&#xff0c;生成5秒精彩视频。支持添加提示词控制图像运动视频续写&#xff1a;对生成视频一键续写4&#xff5e;5秒&#xff0c;支持…

LeetCode:经典题之1491、896 题解与延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 …

基于uni-app和图鸟UI开发上门服务小程序

一、技术栈选择 uni-app&#xff1a;我们选择了uni-app作为开发框架&#xff0c;因为它基于Vue.js&#xff0c;允许我们编写一次代码&#xff0c;发布到多个平台&#xff0c;包括iOS、Android、Web以及各种小程序。uni-app的丰富组件库、高效的状态管理以及便捷的预览调试功能&…

LightGBM算法详解

LightGBM算法详解 LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是由微软开发的高效梯度提升决策树&#xff08;GBDT&#xff09;实现。它以速度和效率著称&#xff0c;特别适用于大规模数据集和高维特征的场景。本文将详细介绍LightGBM的原理、特点、常用…

用于世界上最先进的医疗应用的精密电阻器

EAK的高性能电阻器使医疗产品设计人员能够继续改善全球患者的生活质量。我们的电阻器专为用于医疗诊断、治疗和预防的各种产品而设计。从小型植入式和非侵入性设备到大型诊断成像设备&#xff0c;医疗制造商之所以选择EAK 电阻器&#xff0c;是因为操作环境是高电压和磁场&…

AI-算力产业链之存力

在数字经济大潮下&#xff0c;数据已经成为新型的生产资料。 目前数据中心有三大力量&#xff1a;计算的力量——算力、存储的力量——存力、运输的力量——运力&#xff0c;即网络的力量。 算力产业链正在火热发展的同时&#xff0c;存力的需求也大幅度提升。2023年上半年&…

总结 CSS 选择器的常见用法

一&#xff0c;什么是css 在前端网页中&#xff0c;css就相当于化妆术&#xff0c;把一个很生硬的网页页面变得排版有序起来。 CSS可以对网页中的元素位置进行像素级精准控制&#xff0c;实现美化页面的效果&#xff0c;也能做到页面的样式和结构分离。 二&#xff0c;css的基…

MySQL中的ibd2sdi—InnoDB表空间SDI提取实用程序

ibd2sdi 是一个用于从 InnoDB 表空间文件中提取序列化字典信息&#xff08;Serialized Dictionary Information, SDI&#xff09;的实用程序。这个实用程序可以用于提取存储在持久化 InnoDB 表空间文件中的 SDI 数据。 可以对以下类型的表空间文件使用 ibd2sdi&#xff1a; 每…

消息认证码解析

1. 什么是消息认证码 消息认证码(Message Authentication Code)是一种确认完整性并进行认证的技术&#xff0c;取三个单词的首字母&#xff0c;简称为MAC。 消息认证码的输入包括任意长度的消息和一个发送者与接收者之间共享的密钥&#xff0c;它可以输出固定长度的数据&#x…

C语言之详解预处理

前言&#xff1a; 预处理也叫预编译&#xff0c;是编译代码时的第一步&#xff0c;经过预处理后生成一个.i文件&#xff0c;如果不明白编译与链接作用的小伙伴可以先看看博主的上一篇博客—— &#xff0c;不然知识连贯性可能会显得很差哦。 正文目录&#xff1a; 预定义符号#…

discuz迪恩cul!教育课程培训网站模板

Discuz x3.2模板 迪恩cul!教育课程培训 GBK&#xff0c;程序包中内附详细的安装教程&#xff0c;下载后按照教程安装即可 discuz迪恩cul!教育课程培训网站模板

qemu 安装ubuntu22.04虚拟机 -纯命令行-可ssh-带网络-编译安装 linux kernel-编译安装 kernel module

tar -xjf xxx.tar.bz2 1&#xff0c;预备系统盘数据 1.1 下载光盘 注意需要 liver-server $ wget https://releases.ubuntu.com/22.04.4/ubuntu-22.04.4-live-server-amd64.iso 1.2 挂载并拷贝 $ sudo mkdir /mnt/iso_ubuntu-22.04.4-live-server-amd64 $ sudo mount u…

星闪指向遥控,做家电交互的破壁人

“面壁者罗辑&#xff0c;我是你的破壁人。” 科幻小说《三体》中&#xff0c;当人类的基础科学被三体人封锁&#xff0c;变得停步不前&#xff0c;人类启动了自救的面壁计划&#xff0c;通过一次又一次破壁&#xff0c;找到战胜三体人的办法。 现实中&#xff0c;有一点已经成…