【STM32】-TTP223B触摸开关

news2025/1/23 22:11:22

前言

本文章旨在记录博主STM32的学习经验,我自身也在不断的学习当中,如果文章有写的不对的地方,欢迎各位大佬批评指正。

准备工作

今天这篇文章介绍的是触摸开关这一外围硬件。

  1. ST-link调试器
  2. STM32最小系统板
  3. 单路TTP223B触摸传感器模块
  4. LED灯珠

开始

1.理清思路

通过查找网络资料我们了解到该传感器特点如图所示

image-20250122213606990

博主也是第一次尝试自己查阅资料来写一个模块的驱动代码,在此之前是跟着B站UP主江协科技学习如何编写驱动代码的。

第一次独立编写驱动代码我是怎么做的呢?我首先想到,既然都是开关,那么是不是可以修改先前学习的按钮驱动代码,在其基础上来实现驱动触摸开关呢?答案是可以!

这里贴上按钮驱动代码 Key.c来供大家参考,注意这里是按钮驱动不是我们本次介绍的触摸驱动

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

void Key_Init(void)
{
	//初始化按钮端口
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIOInitStructure;
	GPIOInitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIOInitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIOInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIOInitStructure);

}

uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;
	
	
	//判断1号端口按钮按下情况
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
	{
		Delay_ms(20);//规避按下按钮的抖动
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); //一直按住按钮则卡住
		Delay_ms(20);//规避松开按钮的抖动
		KeyNum = 1;
	}
	
	return KeyNum;
}

2.编写代码

有了以上思路我们开始编写触摸模块的驱动代码

连接电路

这里我将触摸传感器的SIG口接到了STM32最小系统板的PB1接口上。LED灯珠接到PA1接口上,采用高电平触发接法。

连接完电路通电后效果如图所示(传感器的VCC还有GND引脚别接反了,亮绿灯代表没接错)

9ca634a95e5a6d0a949b724b1079162

编写驱动

和按键驱动一样,我们首先在Hardware目录新建触摸模块的c和h文件,取名Touch

image-20250122215437318

在新建的Touch.c文件当中新建一个Touch_Init函数,代码如下

首先初始化RCC时钟,然后选择上拉输入模式,接着巴拉巴拉(相信你们都会了,我这里就不多说)

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

void Touch_Init(void)
{
	//初始化按钮端口
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIOInitStructure;
	GPIOInitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIOInitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIOInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIOInitStructure);
}

有了触摸模块的初始化函数后我们还需要一个函数用于获取按钮状态,即按钮是否被触摸,这里我们新建函数 Touch_GetNum

注意这个函数是有返回数值的,这里返回类型为uint8_t,还有就是,和按键一样我们为了避免外界因素对我们产生的影响,还是要进行一个消抖动的过程,代码如下

uint8_t Touch_GetNum(void)
{
	uint8_t TouchNum = 0;
	
	//判断1号端口按钮按下情况
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1)
	{
        Delay_ms(20);//消去抖动
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1); //一直按住按钮则卡住
        Delay_ms(20);//消去抖动
		TouchNum = 1;
	}
	
	return TouchNum;
}

完成这两个函数后我们的触摸模块驱动基本已经完成了,完整代码如下

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

void Touch_Init(void)
{
	//初始化按钮端口
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIOInitStructure;
	GPIOInitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIOInitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIOInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIOInitStructure);
}

uint8_t Touch_GetNum(void)
{
	uint8_t TouchNum = 0;
	
	//判断1号端口按钮按下情况
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1)
	{
        Delay_ms(20);//消去抖动
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1); //一直按住按钮则卡住
        Delay_ms(20);//消去抖动
		TouchNum = 1;
	}
	
	return TouchNum;
}

写完Touch.c后别忘了在头文件touch.h当中添加这两个函数,代码如下

#ifndef __TOUCH_H
#define __TOUCH_H

void Touch_Init(void);
uint8_t Touch_GetNum(void);

#endif

到这里我们驱动代码已经编写完成了,接下来就是到main.c当中完善一下逻辑代码了

这里直接贴上完整代码

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "Touch.h"

uint8_t TouchNum;

int main(void)
{	
	LED_Init(); //LED灯珠初始化
	Touch_Init(); //触摸模块初始化
	
	
	while (1)
	{
		TouchNum = Touch_GetNum();
		if(TouchNum == 1)
		{
			LED1_Turn();
		}
	}
}

还有LED灯珠驱动这里也一并贴上(同样的也是放在Hardware文件夹内)

LED.c

#include "stm32f10x.h"                  // Device header

void LED_Init(void)
{
	//初始化LED端口
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIOInitStructure;
	GPIOInitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIOInitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIOInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIOInitStructure);
}

void LED1_ON(void)
{
	//开启LED
	GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
	
void LED1_OFF(void)
{
	//关闭LED
	GPIO_SetBits(GPIOA, GPIO_Pin_1);
}

void LED1_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_1);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);
	}
}

LED.h

#ifndef __LED_H
#define __LED_H

void LED_Init(void);
void LED1_ON(void);
void LED1_OFF(void);
void LED1_Turn(void);

#endif

以上代码全部写好后我们就可以编译并下载到系统板上查看效果了

结尾

感谢你能阅读到这里,相信你已经掌握了触摸模块的驱动编写了吧!在这里,我希望各位大佬跟我一起共进步,后续我也会多分享一些我自己的学习经验,以及像这篇文章一样的模块分享,最后还是感谢你的阅读,我们下篇文章再见吧

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ceph基本概念,架构,部署(一)

一、分布式存储概述 1.存储分类 存储分为封闭系统的存储和开放系统的存储,而对于开放系统的存储又被分为内置存储和外挂存储。 外挂存储又被细分为直连式存储(DAS)和网络存储(FAS),而网络存储又被细分网络接入存储(NAS)和存储区域网络(SAN)等。 DAS(D…

Apache Hive3定位表并更改其位置

Apache Hive3表 1、Apache Hive3表概述2、Hive3表存储格式3、Hive3事务表4、Hive3外部表5、定位Hive3表并更改位置6、使用点表示法引用表7、理解CREATE TABLE行为 1、Apache Hive3表概述 Apache Hive3表类型的定义和表类型与ACID属性的关系图使得Hive表变得清晰。表的位置取决于…

计算机网络介质访问控制全攻略:从信道划分到协议详解!!!

一、信道划分介质访问控制 介质访问控制:多个节点共享同一个“总线型”广播信道时,可能发生“信号冲突” 应该怎么控制各节点对传输介质的访问,才能减少冲突,甚至避免冲突? 时分复用(TDM) 时分复用:将时间分为等长的“…

IJCAI-2024 | 具身导航的花样Prompts!VLN-MP:利用多模态Prompts增强视觉语言导航能力

作者: Haodong Hong1,2 , Sen Wang1∗ , Zi Huang1 , Qi Wu3 and Jiajun Liu2,1 单位:昆士兰大学,澳大利亚科学与工业研究组织,阿德莱德大学 论文标题:Why Only Text: Empowering Vision-and-Language Navigation wi…

C语言程序设计十大排序—冒泡排序

文章目录 1.概念✅2.冒泡排序🎈3.代码实现✅3.1 直接写✨3.2 函数✨ 4.总结✅ 1.概念✅ 排序是数据处理的基本操作之一,每次算法竞赛都很多题目用到排序。排序算法是计算机科学中基础且常用的算法,排序后的数据更易于处理和查找。在计算机发展…

docker 安装 redis 详解

在平常的开发工作中,我们经常会用到 redis,那么 docker 下应该如何安装 redis 呢?简单来说:第一步:拉取redis镜像;第二步:设置 redis.conf 配置文件;第三步:编写 docker-…

人工智能之深度学习_[4]-神经网络入门

文章目录 神经网络基础1 神经网络1.1 神经网络概念1.1.1 什么是神经网络1.1.2 如何构建神经网络1.1.3 神经网络内部状态值和激活值 1.2 激活函数1.2.1 网络非线性因素理解1.2.2 常见激活函数1.2.2.1 Sigmoid 激活函数1.2.2.2 Tanh 激活函数1.2.2.3 ReLU 激活函数1.2.2.4 SoftMa…

FPGA中场战事

2023年10月3日,英特尔宣布由桑德拉里维拉(Sandra Rivera)担任“分拆”后独立运营的可编程事业部首席执行官。 从数据中心和人工智能(DCAI)部门总经理,转身为执掌该业务的CEO,对她取得像AMD掌门人苏姿丰博士类似的成功,无疑抱以厚望。 十年前,英特尔花费167亿美元真金白银…

李沐vscode配置+github管理+FFmpeg视频搬运+百度API添加翻译字幕

终端输入nvidia-smi查看cuda版本 我的是12.5,在网上没有找到12.5的torch,就安装12.1的。torch,torchvision,torchaudio版本以及python版本要对应 参考:https://blog.csdn.net/FengHanI/article/details/135116114 创…

Android系统开发(六):从Linux到Android:模块化开发,GKI内核的硬核科普

引言: 今天我们聊聊Android生态中最“硬核”的话题:通用内核镜像(GKI)与内核模块接口(KMI)。这是内核碎片化终结者的秘密武器,解决了内核和供应商模块之间无尽的兼容性问题。为什么重要&#x…

K8S如何让worker使用kubectl命令(RBAC方法)

背景 目前集群规划如下 kubeadm安装集群master节点默认能使用kubectl命令,worker则不能使用。这是因为worker节点没授权。当然,你可以通过以下方式授权 mkdir .kube scp master1:/root/.kube/config .kube/但这样无疑给了worker节点非常大的权限&#…

【Excel】【VBA】Reaction超限点筛选与散点图可视化

【Excel】【VBA】Reaction超限点筛选与散点图可视化 功能概述 这段代码实现了以下功能: 从SAFE输出的结果worksheet通过datalink获取更新数据从指定工作表中读取数据检测超过阈值的数据点生成结果表格并添加格式化创建可视化散点图显示执行时间 流程图 #mermaid-…

[Computer Vision]实验三:图像拼接

目录 一、实验内容 二、实验过程及结果 2.1 单应性变换 2.2 RANSAC算法 三、实验小结 一、实验内容 理解单应性变换中各种变换的原理(自由度),并实现图像平移、旋转、仿射变换等操作,输出对应的单应性矩阵。利用RANSAC算法优…

微信小程序使用picker根据接口给的省市区的数据实现省市区三级联动或者省市区街道等多级联动

接口数据如上图 省市区多级联动&#xff0c;都是使用的一个接口通过传参父类的code。返回我们想要的数据 比如获取省就直接不要参数。市就把省得code传给接口&#xff0c;区就把市的code作为参数。 <picker mode"multiSelector" :range"mulSelect1" …

自动化01

测试用例的万能公式&#xff1a;功能测试界面测试性能测试易用性测试安全性测试兼容性测试 自动化的主要目的就是用来进行回归测试 新产品--第一个版本 (具备丰富的功能)&#xff0c;将产品的整体进行测试&#xff0c;人工创造一个自动化测试用例&#xff0c;在n个版本的时候…

JS宏进阶:正则表达式的使用

正则表达式&#xff0c;对于任何一门编程语言来说&#xff0c;都是一种非常强大的工具&#xff0c;主要用于搜索、编辑或操作文本和数据。因此&#xff0c;在JS中&#xff0c;也存在相应的对象new RegExp( )&#xff0c;在本章中&#xff0c;将详细介绍正则表达式在JS宏中的运用…

深度学习笔记——循环神经网络RNN

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的循环神经网络RNN知识点。 文章目录 文本特征提取的方法1. 基础方法1.1 词袋模型&#xff08;Bag of Words, BOW&#xff09;工作原…

Git进阶笔记系列(01)Git核心架构原理 | 常用命令实战集合

读书笔记&#xff1a;卓越强迫症强大恐惧症&#xff0c;在亲子家庭、职场关系里尤其是纵向关系模型里&#xff0c;这两种状态很容易无缝衔接。尤其父母对子女、领导对下属&#xff0c;都有望子成龙、强将无弱兵的期望&#xff0c;然而在你的面前&#xff0c;他们才是永远强大的…

SpringBoot读取yml配置文件一组对象数据初始化

1. yml的短横杠语法2. yml数组元素读取并初始化3. 测试结果 1. yml的短横杠语法 - 短横杠加空格&#xff0c;可以表示数组元素&#xff0c;如下配置 表示有名为apps的一组数据&#xff0c;数组的元素对象包含有corpId、corpSecret、appCode三个字段像server.port没有 - 表示的…

基于JAVA的校园二手商品交易平台的设计与开发

摘 要&#xff1a;政府政策引导与社会观念的转变使得国内大学生的创业意识逐渐提高&#xff0c;很多高校大学生开始自主创业。目前我国各大高校暂且还没有较为成型的针对校内学生创业者的校园网络服务平台。本文首先主要是介绍了关于java语言以及web开发的相关技术&#xff0c;…