STM32硬件接口I2C应用(基于FT6336)

目录

概述

1 硬件介绍

1.1 ST7796-LCD

1.2 MCU IO与LCD PIN对应关系

1.3 MCU IO与Touch PIN对应关系

2 FT6336的寄存器

2.1 FT6336寄存器列表

2.2 寄存器功能介绍 

3 STM32Cube控制配置I2C

3.1  软硬件版本信息

3.2 I2C参数配置

3.3 使用STM32Cube产生工程

4 HAL库函数介绍

4.1 初始化函数

4.2 写数据函数

 4.3 读数据函数

5 FT6336驱动程序

5.1 读写寄存器接口

5.2 初始化函数

5.3 源代码

6 触摸屏功能实现

6.1 触摸屏应用程序

6.2 源代码

7 测试

7.1 代码实现

7.2 测试


概述

本文主要介绍FT6336触摸屏芯片的相关内容,主要包括其寄存器的信息,还介绍了LCD模组上使用的芯片的引脚定义,以及和STM32 IO的对应关系。重点介绍使用STM32硬件I2C接口驱动FT6336的实现方法。笔者使用基于STM32F407的板卡,使用STM32Cube创建工程,并完成整个项目的FT6336驱动程序和触摸功能程序,并验证其功能。

1 硬件介绍

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对应关系如下图所示

1.2 MCU IO与LCD PIN对应关系

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

1.3 MCU IO与Touch PIN对应关系

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

2 FT6336的寄存器

2.1 FT6336寄存器列表

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控制配置I2C

3.1  软硬件版本信息

STM32CubeMX 版本: 6.11

HAL库版本: STM32Cube_FW_F4_V1.27.1

3.2 I2C参数配置

STM32F407 的标准I2C接口最大支持100K工作频率,笔者选择最大工作频100k,以配置I2C的参数。

I2C使用的GPIO接口如下:

使用MCU类型和HAL库的版本

3.3 使用STM32Cube产生工程

 在配置完成项目后,点击GENERATE生成项目,打开项目后项目目录如下,和I2C相关的代码如下:

代码第40行:选择I2C2作为硬件接口

代码第41行:I2C通信速率为100K

代码第44行:定义地址位7bit

4 HAL库函数介绍

STM32 HAL库函数数量很多,本文仅介绍笔者使用的一些函数接口。其他函数在使用的时候在具体研究,而不许把每个函数搞清楚才去应用。

4.1 初始化函数

函数原型:

HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);

参数介绍

hi2c:  指向I2C_HandleTypeDef结构体的指针,该结构体包含指定I2C的配置信息。

 一个使用案例: 如果已经初始化完成hi2c结构,初始化时,直接调用该结构体即可。

4.2 写数据函数

函数原型:

HAL_StatusTypeDef HAL_I2C_Mem_Write(   I2C_HandleTypeDef *hi2c, 
                                       uint16_t DevAddress, 
                                       uint16_t MemAddress, 
                                       uint16_t MemAddSize, 
                                       uint8_t *pData, 
                                       uint16_t Size, uint32_t Timeout)

参数介绍:

hi2c:  指向I2C_HandleTypeDef结构体的指针,该结构体包含指定I2C的配置信息。

DevAddress: 目标设备地址:设备的7位地址值在调用接口之前,必须将数据表向左移动

MemAddress:内存地址

MemAddSize:内存地址大小

pData:            写数据指针

Size:               写数据大小

Timeout:         写数据超时时间

 4.3 读数据函数

函数原型:

HAL_StatusTypeDef HAL_I2C_Mem_Read( I2C_HandleTypeDef *hi2c, 
                                    uint16_t DevAddress, 
                                    uint16_t MemAddress, 
                                    uint16_t MemAddSize, 
                                    uint8_t *pData, 
                                    uint16_t Size, 
                                    uint32_t Timeout)

参数介绍:

hi2c:  指向I2C_HandleTypeDef结构体的指针,该结构体包含指定I2C的配置信息。

DevAddress: 目标设备地址:设备的7位地址值在调用接口之前,必须将数据表向左移动

MemAddress:内存地址

MemAddSize:内存地址大小

pData:            读数据指针

Size:               读数据大小

Timeout:         读数据超时时间

5 FT6336驱动程序

5.1 读写寄存器接口

代码57行: 调用HAL库中的写数据函数,向FT6336寄存器写数据

代码69行:调用HAL库中的读数据函数,从FT6336寄存器读取数据

5.2 初始化函数

代码82行: 初始化Touch相关的IO

代码83行: RESET FT6336

代码85行:读取FT6336的ID参数

5.3 源代码

创建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 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;
}



/* End of this file */

 创建ft6336.h文件,编写如下代码:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : ft6336.h
  * Description        : I2C drive based on STM32F4
  * 
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024~2029 mingfei.tang
  * All rights reserved.
  *
  *************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FT6336_H
#define __FT6336_H

#ifdef __cplusplus
 extern "C" {
#endif

#include "stdio.h"
#include "main.h"


#define RCC_TOUCH_CLK_ENABLE()       __HAL_RCC_GPIOH_CLK_ENABLE()

#define GPIO_PORT_TOUCH              GPIOH

#define FT_RST_PIN                   GPIO_PIN_9      //FT6636复位引脚
#define FT_INT_PIN                   GPIO_PIN_10     //FT6636中断引脚

#define FT_RST_L                     HAL_GPIO_WritePin(GPIO_PORT_TOUCH, FT_RST_PIN, GPIO_PIN_RESET)
#define FT_RST_H                     HAL_GPIO_WritePin(GPIO_PORT_TOUCH, FT_RST_PIN, GPIO_PIN_SET)



#define FT6336_OK                 1
#define FT6336_ERROR              0

#define FT_TRUE                   1
#define FT_FALSE                  0

#define FT6336_ADDR              0X71

//FT5426 部分寄存器定义 
#define FT_DEVIDE_MODE           0x00         //FT6336模式控制寄存器
#define FT_REG_NUM_FINGER        0x02         //触摸状态寄存器

#define FT_TP1_REG               0X03         //第一个触摸点数据地址
#define FT_TP2_REG               0X09         //第二个触摸点数据地址

#define FT_ID_G_CIPHER_MID       0x9F         //芯片代号(中字节) 默认值0x26
#define FT_ID_G_CIPHER_LOW       0xA0         //芯片代号(低字节) 0x01: Ft6336G  0x02: Ft6336U 
#define FT_ID_G_LIB_VERSION      0xA1         //版本
#define FT_ID_G_CIPHER_HIGH      0xA3         //芯片代号(高字节) 默认0x64 
#define FT_ID_G_MODE             0xA4         //FT6636中断模式控制寄存器
#define FT_ID_G_FOCALTECH_ID     0xA8         //VENDOR ID 默认值为0x11
#define FT_ID_G_THGROUP          0x80         //触摸有效值设置寄存器
#define FT_ID_G_PERIODACTIVE     0x88         //激活状态周期设置寄存器


// MATCH VALUE LIST 
#define PANNEL_ID                0x11


int ft6336_Init( void );
uint8_t ft6336_RdReg( uint16_t regAdd, uint8_t *pData, uint16_t Size );
uint8_t ft6336_WeReg( uint16_t regAdd, uint8_t *pData, uint16_t Size );

#ifdef __cplusplus
}
#endif

#endif /*__FT6336_H */

6 触摸屏功能实现

6.1 触摸屏应用程序

代码第45行:读取当前触摸点的个数

代码第59行:读取触摸点的值

6.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;
    
    if( touch_isOK == FT_FALSE )
        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;
        }
    }
    
    if( cnt>240 )
       cnt=10;
    
    return set;
}


/* End of this file */ 

 创建usr_touch.h文件,编写如下代码:

#ifndef __USR_TOUCH_H
#define __USR_TOUCH_H

#include <stdlib.h>
#include <stdio.h>
#include "main.h"
#include "ft6336.h"

#define CTP_MAX_TOUCH               2

typedef struct
{
   uint8_t ptNum                    : 4;
   uint8_t tpDown                   : 1;
   uint8_t tpPress                  : 1;
   uint8_t res                      : 2;
} Status_bit;

typedef struct
{
    uint16_t xpox[CTP_MAX_TOUCH];
    uint16_t ypox[CTP_MAX_TOUCH];
    union
    {
        uint8_t status;
        Status_bit status_bit;
    };
}stru_pos;

void usr_touchInit( void );
uint8_t usr_ScanTouchProcess( stru_pos *pPos);


#endif  /*  __USR_TOUCH_H */

7 测试

7.1 代码实现

代码110行: 初初始化touch接口

代码117行: monitor触摸点

7.2 测试

编译代码下载到板卡中

点击屏幕,运行触摸点信息如下:

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

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

相关文章

用自己的数据集训练TimeSformer并转ONNX用c++推理

用自己的数据集训练TimeSformer并转ONNX用c++推理 文章目录 用自己的数据集训练TimeSformer并转ONNX用c++推理下载安装TimeSformer创建分类文件夹创建数据集修改训练配置运行脚本开始训练测试模型模型转为onnx测试一下生成的onnx模型转为用c++推理下载安装TimeSformer TimeSfo…

EasyRecovery数据恢复软件2024免费版下载

EasyRecovery数据恢复软件&#xff0c;是我在电脑使用过程中遇到的神器&#xff01;它不仅功能强大&#xff0c;操作简便&#xff0c;还帮我找回了丢失的重要文件。今天&#xff0c;我就来给大家分享一下我的使用体验和心得。 让我来介绍一下EasyRecovery的功能。这款软件可以恢…

qt开发-09_分裂器

QSplitter 是 Qt 框架中的一个非常实用的控件&#xff0c;用于创建可调整大小的窗格。它允许用户通过拖动子窗口间的边界&#xff08;也称为分割条&#xff09;来动态调整子窗口的尺寸。这在开发需要多个视图同时显示&#xff0c;且用户需要根据需要调整每个视图大小的应用程序…

内容安全复习 6 - 白帽子安全漏洞挖掘披露的法律风险

文章目录 安全漏洞的法律概念界定安全漏洞特征白帽子安全漏洞挖掘面临的法律风险“白帽子”安全漏洞挖掘的风险根源“白帽子”的主体边界授权行为边界关键结论 安全漏洞的法律概念界定 可以被利用来破坏所在系统的网络或信息安全的缺陷或错误&#xff1b;被利用的网络缺陷、错…

推荐4款实用工具,非常好用,建议收藏

PDFREAL PDFReal 是一个功能强大的在线PDF编辑工具&#xff0c;提供多种实用的PDF处理功能。用户可以在一个网站上完成包括PDF合并、PDF拆分、PDF压缩、PDF保护、PDF解锁等多种操作。此外&#xff0c;PDFReal 还支持将文本转换为PDF、将图片转换为PDF、添加水印、提取页面内容等…

【Springcloud微服务】Docker上篇

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Springcloud微服务 &#x1f320; 首发时间&#xff1a;2024年6月22日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f4…

Vue73-命名路由

一、路由的name属性 二、小结

Pyqt5 + Qt Creator实现QML开发环境配置

先安装Qt Creator, 该软件主要是为了编辑QML文件 在pycharm中配置外部插件&#xff0c;实现Qt Creator的调用 配置完成后&#xff0c;右击qml文件选择Qt Creator就可以直接进行编辑了

Nominatim免费的地址解析,逆地址解析,OpenStreetMap开源地图数据【全网最全】

视频学习地址 国内的一些地址解析供应商的API都开始付费了&#xff0c;就想找个免费的地址解析和逆地址解析的应用&#xff0c;最终选择了Nominatim OpenStreetMap 文章目录 一、选型1-1、数据源1-2、地理编码引擎2-1、初尝Nominatim2-1-1、地址解析2-1-2、逆地址解析 2-2、OS…

HarmonyOS角落里的知识—Stage模型应用程序

开发态包结构 在DevEco Studio上创建一个项目工程&#xff0c;并尝试创建多个不同类型的Module。根据实际工程中的目录对照本章节进行学习&#xff0c;可以有助于理解开发态的应用程序结构。 图1 项目工程结构示意图&#xff08;以实际为准&#xff09; 工程结构主要包含的文…

RabbitMQ —— 理解及应用场景

一、MQ相关的概念 RabbitMQ 是一种分布式消息中间件&#xff0c;消息中间件也称消息队列MQ&#xff0c;那么什么是MQ呢&#xff1f;请继续阅读下文。 1.1、MQ的基本概念 什么是MQ MQ(message queue)&#xff0c;从字面意思上看就个 FIFO 先入先出的队列&#xff0c;只不过队列…

工业互联网的独特UI风格

工业互联网的独特UI风格

纯血鸿蒙 璀璨星河

点击上方蓝字关注我&#xff0c;知识会给你力量 华为最近可谓是加班加点&#xff0c;前段时间华为给出了鸿蒙系统的计划表&#xff0c;让大家都摩拳擦掌&#xff0c;想看看华为到底有几把刷子&#xff0c;这次的621HDC大会&#xff0c;就是华为给全世界的第一个交待。 最近在网…

锂磷硫(LPS)属于硫化物固态电解质 Li7P3S11是代表性产品

锂磷硫&#xff08;LPS&#xff09;属于硫化物固态电解质 Li7P3S11是代表性产品 锂磷硫&#xff08;LPS&#xff09;&#xff0c;为非晶态材料&#xff0c;是硫化物固态电解质代表性产品之一&#xff0c;具有热稳定性好、成本较低等优点&#xff0c;在固态电解质中离子电导率较…

外卖APP开发详解:从同城O2O系统源码开始

近期&#xff0c;从事软件开发的小伙伴们都在讨论外卖APP&#xff0c;热度非常之高&#xff0c;所以小编今天将与大家一同探讨同城O2O系统源码、外卖APP开发。 一、外卖APP开发的前期准备 了解目标用户的需求&#xff0c;分析竞争对手的优劣势&#xff0c;明确自身的市场定位。…

Excel 导入实例

在上一节的基础上&#xff0c;本文演示下如何导入excel数据。 Excel导入操作指导 继承ocean-easyexcel SDK&#xff0c;上一节打包生成 <dependency><groupId>com.angel.ocean</groupId><artifactId>ocean-easyexcel</artifactId><version…

VB验证密码

在文本框中输入密码&#xff0c;“验证密码”按钮检验输入的是否为“123456”。“清空”按钮清空文本框。“结束”按钮关闭窗体。 Public Class Form1Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.ClickDim P$P Trim(TextBox1.Text)If P &…

第13章.创建MDK工程-基于标准库版

目录 0. 《STM32单片机自学教程》专栏 13.1 新建本地工程文件夹 13.2 新建工程 13.2.1 新建工程 13.2.2 新建组 13.2-3 添加文件 13.3 配置魔术棒选项卡 13.3.1 Output 选项卡 13.3.2 C/C选项配置 13.3.3 Dubug选项配置 13.4 使用标准库点亮LED 参考资料&#xff1…

分布式锁(Redission)

分布式锁&#xff1a; 使用场景&#xff1a; 通常对于一些使用率高的服务&#xff0c;我们会进行多次部署&#xff0c;可能会部署在不同的服务器上&#xff0c;但是他们获取和操作的数据仍然是同一份。为了保证服务的强一致性&#xff0c;我们需要对线程进行加锁&#xff0c;…

Appium Android 自动化测试 -- 元素定位

自动化测试元素定位是难点之一&#xff0c;编写脚本时会经常卡在元素定位这里&#xff0c;有时一个元素能捣鼓一天&#xff0c;到最后还是定位不到。 Appium 定位方式和 selenium 一脉相承&#xff0c;selenium 中的定位方式Appium 中都支持&#xff0c;而 Appium 还增加了自己…