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

2024-06-22 07:28

本文主要是介绍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;elsereturn 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;elsereturn 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 __cplusplusextern "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                0x11int 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 proprietaryinformation of mingfei.tang and is confidential in nature.Under no circumstances is this software to be combined with anyOpen Source Software in any way or placed under an Open Source Licenseof 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               2typedef 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 测试

编译代码下载到板卡中

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

这篇关于STM32硬件接口I2C应用(基于FT6336)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1083665

相关文章

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

硬件基础知识——自学习梳理

计算机存储分为闪存和永久性存储。 硬盘(永久存储)主要分为机械磁盘和固态硬盘。 机械磁盘主要靠磁颗粒的正负极方向来存储0或1,且机械磁盘没有使用寿命。 固态硬盘就有使用寿命了,大概支持30w次的读写操作。 闪存使用的是电容进行存储,断电数据就没了。 器件之间传输bit数据在总线上是一个一个传输的,因为通过电压传输(电流不稳定),但是电压属于电势能,所以可以叠加互相干扰,这也就是硬盘,U盘

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用。如果你看不懂,请留言。 完整代码: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><ti

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述。以下是从不同角度对气象站的种类和应用范围的介绍: 一、气象站的种类 根据用途和安装环境分类: 农业气象站:专为农业生产服务,监测土壤温度、湿度等参数,为农业生产提供科学依据。交通气象站:用于公路、铁路、机场等交通场所的气象监测,提供实时气象数据以支持交通运营和调度。林业气象站:监测林区风速、湿度、温度等气象要素,为林区保护和

vue3项目将所有访问后端springboot的接口统一管理带跨域

vue3项目将所有访问后端springboot的接口统一管理带跨域 一、前言1.安装Axios2.创建Axios实例3.创建API服务文件4.在组件中使用API服务 二、跨域三、总结 一、前言 在Vue 3项目中,统一管理所有访问后端Spring Boot接口的最佳实践是创建一个专门的API服务层。这可以让你的代码更加模块化、可维护和集中管理。你可以使用Axios库作为HTT

PyTorch模型_trace实战:深入理解与应用

pytorch使用trace模型 1、使用trace生成torchscript模型2、使用trace的模型预测 1、使用trace生成torchscript模型 def save_trace(model, input, save_path):traced_script_model = torch.jit.trace(model, input)<

哺乳细胞重组表达人鼠嵌合抗体:制备与应用

重组抗体是一类具有广泛应用价值的蛋白质,在药物研发和生物医学研究中发挥着重要作用。本文将介绍重组抗体的表达方式,重点关注嵌合抗体制备和哺乳细胞重组表达人鼠嵌合抗体的技术原理和应用。 重组抗体表达的原理和方法 重组抗体表达是通过将人或动物源的免疫球蛋白基因导入表达宿主细胞,并使其表达出特异性抗体蛋白质。常用的表达系统包括细菌、哺乳细胞和真核微生物等。 嵌合抗体制备的步骤和优势 选择适当的抗原

【Qt6.3 基础教程 16】 掌握Qt中的时间和日期:QTimer和QDateTime的高效应用

文章目录 前言QTimer:定时任务的强大工具QTimer的基本用法高级特性:单次定时器 QDateTime:处理日期和时间获取当前日期和时间日期和时间的格式化输出日期和时间计算 用例:创建一个倒计时应用结论 前言 在开发桌面应用程序时,处理时间和日期是一个常见且重要的任务。Qt框架提供了强大的工具来处理与时间相关的功能,其中QTimer和QDateTime是最核心的类。本