STM32-11-电容触摸按键

STM32-01-认识单片机
STM32-02-基础知识
STM32-03-HAL库
STM32-04-时钟树
STM32-05-SYSTEM文件夹
STM32-06-GPIO
STM32-07-外部中断
STM32-08-串口
STM32-09-IWDG和WWDG
STM32-10-定时器

STM32电容触摸按键

  • 电容触摸按键原理
    在这里插入图片描述
    在这里插入图片描述

    无手指触摸:上电时,电阻作用下,电容Cs进行充电,直到电容充满,这时候会有一个充电时间Tcs.

    有手指触摸:上电时,电阻作用下,电容CsCx进行充电,电容充满时间会变长,得到充电时间Tcx.
    在这里插入图片描述
    在这里插入图片描述

  • 检测电容触摸按键过程

    1. TPAD引脚设置为推挽输出,输出低电平,实现电容放电到地
    2. TPAD引脚设置为浮空输入(IO复位后的状态),电容开始充电
    3. 同时开启TPAD引脚的输入捕获功能,开始捕获高电平
    4. 等待充电过程中,上升沿触发(充电到Vth(上升沿的电压值))
    5. 计算充电时间(定时器捕获/比较寄存器获取)
  • 硬件结构图
    在这里插入图片描述

  • 代码实现

    • TPAD初始化函数

      uint8_t tpad_init(uint16_t psc)
      {uint16_t buf[10];uint16_t temp;uint16_t i,j;tpad_timx_cap_init(0XFFFF, psc - 1);//连续读取10次for(i = 0; i < 10; i++){buf[i] = tpad_get_val();delay_init(10);}for(i = 0; i < 9; i++){for(j = i + 1; j < 10; j++){if(buf[i] > buf[j]){temp = buf[i];buf[i] = buf[j];buf[j] = temp;}}}temp = 0;for(i = 2; i < 8; i++){temp += buf[i];}g_tpad_default_val = temp / 6;printf("g_tpad_default_val:%d\r\n", g_tpad_default_val);if (g_tpad_default_val > 0XFFFF / 2){return 1;                   /* 初始化遇到超过TPAD_ARR_MAX_VAL/2的数值,不正常! */}return 0;
      }
      
    • 触摸按键输入捕获设置

      void tpad_timx_cap_init(uint16_t arr, uint16_t psc)
      {GPIO_InitTypeDef gpio_init_struct;TIM_IC_InitTypeDef timx_ic_cap_chy;__HAL_RCC_GPIOA_CLK_ENABLE();  //初始化GPIOA时钟__HAL_RCC_TIM5_CLK_ENABLE();   //初始化TIM5时钟gpio_init_struct.Pin = GPIO_PIN_1;       //PA1gpio_init_struct.Mode = GPIO_MODE_INPUT; //输入gpio_init_struct.Pull = GPIO_PULLDOWN;   //下拉gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; //中速HAL_GPIO_Init(GPIOA, &gpio_init_struct);  //初始化g_timx_cap_chy_handle.Instance = TIM5;      //定时器基地址g_timx_cap_chy_handle.Init.Prescaler = psc; //分频系数g_timx_cap_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;  //向上计数g_timx_cap_chy_handle.Init.Period = arr;    //自动重装载值g_timx_cap_chy_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;  //时钟分频因子HAL_TIM_IC_Init(&g_timx_cap_chy_handle);timx_ic_cap_chy.ICPolarity = TIM_ICPOLARITY_RISING;     //上升沿捕获timx_ic_cap_chy.ICSelection = TIM_ICSELECTION_DIRECTTI; //映射到TI1timx_ic_cap_chy.ICPrescaler = TIM_ICPSC_DIV1;           //输入分频设置为不分频timx_ic_cap_chy.ICFilter = 0;                           //输入滤波设置为不滤波HAL_TIM_IC_ConfigChannel(&g_timx_cap_chy_handle, &timx_ic_cap_chy, TIM_CHANNEL_2);HAL_TIM_IC_Start(&g_timx_cap_chy_handle, TIM_CHANNEL_2);  //使能输入捕获和定时器
      }
      

      输入捕获映射到TI1通道,意味着PA1引脚的信号将被定时器的第一个输入捕获通道TI1处理。代码中指定了TIM_ICSELECTION_DIRECTTI,表示直接选择输入引脚作为捕获源,而不是通过其他中间信号。

      PA1引脚的信号映射到定时器通道1(TI1)的过程是通过硬件内部的多路复用器(multiplexer,简称MUX)实现的。

    • 获取捕获值

      uint16_t tpad_get_val(void)
      {tpad_reset();//等待捕获上升沿,捕获结束后标志位会置1while(__HAL_TIM_GET_FLAG(&g_timx_cap_chy_handle, TIM_CHANNEL_2) == 0){if(g_timx_cap_chy_handle.Instance->CNT > 0xFFFF - 500){return g_timx_cap_chy_handle.Instance->CNT;}}return TIM5->CCR2;
      } 
      
    • 复位TPAD

      void tpad_reset(void)
      {GPIO_InitTypeDef gpio_init_struct;gpio_init_struct.Pin = GPIO_PIN_1;gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;gpio_init_struct.Pull = GPIO_PULLUP;gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOA, &gpio_init_struct);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);  //TPAD引脚输出0,放电delay_ms(5);g_timx_cap_chy_handle.Instance->SR = 0;   //清除标记g_timx_cap_chy_handle.Instance->CNT = 0;  //归零gpio_init_struct.Pin = GPIO_PIN_1;gpio_init_struct.Mode = GPIO_MODE_INPUT;gpio_init_struct.Pull = GPIO_NOPULL;gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOA, &gpio_init_struct);
      }
      
      1. 配置PA1为推挽输出模式,并且设置为上拉电阻。这样可以确保PA1在输出状态下可以稳定的输出高低电平信号。
      2. 设置PA1引脚为低电平,相当于对TPAD引脚进行放电操作。
      3. 延时5ms,确保放电操作完成。
      4. 清除定时器状态寄存器和计数器。
      5. 配置PA1引脚为输入模式,并且设置为无上下拉电阻,这样,TPAD引脚可以正常接收外部输入信号。

      在嵌入式系统中,尤其是在涉及触摸传感器或类似的硬件操作时,先将引脚设置为推挽输出模式再进行放电是一个常见的做法。这种方法可以确保引脚能够快速且有效地放电,从而为后续的操作(例如测量或重新配置引脚为输入模式)提供一个已知的初始状态。

      为什么要先设置为推挽输出模式再进行放电?

      1. 强制性放电
      • 推挽输出模式能够提供较强的驱动能力。通过将引脚设置为推挽输出模式并输出低电平,能够确保引脚上的电容或残留电荷能够迅速放电至0。这对于某些敏感的电路来说是必要的,确保电路在重新配置为输入模式之前没有残余电荷影响测量精度。
      1. 可靠的初始状态
      • 直接将引脚设置为低电平进行放电在某些情况下可能并不能保证完全的放电,特别是在引脚上有较大的寄生电容时。推挽模式可以提供更可靠的低电平输出,确保引脚电位完全放电至0。
      1. 硬件保护
      • 通过推挽输出模式放电,可以避免因高阻抗状态导致的浮动电平问题。高阻抗状态下,外界噪声可能会干扰引脚电平,从而影响后续的测量。
    • 扫描触摸按键

      uint8_t tpad_scan(uint8_t mode)
      {static uint8_t keyen = 0;   /* 0, 可以开始检测;  >0, 还不能开始检测; */uint8_t res = 0;uint8_t sample = 3;         /* 默认采样次数为3次 */uint16_t rval;if (mode){sample = 6;             /* 支持连按的时候,设置采样次数为6次 */keyen = 0;              /* 支持连按, 每次调用该函数都可以检测 */}rval = tpad_get_maxval(sample);if (rval > (g_tpad_default_val + 100))    /* 大于tpad_default_val+TPAD_GATE_VAL,有效 */{if (keyen == 0){res = 1;            /* keyen==0, 有效 */}//printf("r:%d\r\n", rval);   /* 输出计数值, 调试的时候才用到 */keyen = 3;              /* 至少要再过3次之后才能按键有效 */}if (keyen) keyen--;return res;
      }
      
    • 读取的数据取最大值

      uint16_t tpad_get_maxval(uint8_t n)
      {uint16_t temp = 0;uint16_t maxval = 0;while (n--){temp = tpad_get_val();  /* 得到一次值 */if (temp > maxval) maxval = temp;}return maxval;
      }
      
    • 主函数

      int main(void)
      {uint8_t t = 0;HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟, 72Mhz */delay_init(72);                             /* 延时初始化 */usart_init(115200);                         /* 串口初始化为115200 */led_init();                                 /* 初始化LED */tpad_init(6);while (1){if (tpad_scan(0))   /* 成功捕获到了一次上升沿(此函数执行时间至少15ms) */{LED1_TOGGLE();  /* LED1翻转 */}t++;if (t == 10){t = 0;LED0_TOGGLE();  /* LED0翻转 */}delay_ms(200);}
      }
      
  • 程序运行流程
    在这里插入图片描述

声明:资料来源(战舰STM32F103ZET6开发板资源包)

  1. Cortex-M3权威指南(中文).pdf
  2. STM32F10xxx参考手册_V10(中文版).pdf
  3. STM32F103 战舰开发指南V1.3.pdf
  4. STM32F103ZET6(中文版).pdf
  5. 战舰V4 硬件参考手册_V1.0.pdf

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch环境配置2.0.1+ Cuda11.7

查找cuda、cudnn、Pytorch(GPU)及cuda和NVIDIA显卡驱动对应关系 查询可支持的最高cuda版本 nvidia-smi查看支持的cuda的版本 CUDA版本对应表 我的显卡驱动是Driver Version&#xff1a;535.40.&#xff0c;那么左边对应的CUDA都可以兼容 右上角为CUDA 版本&#xff0c;可以看…

Linux 防火墙 firewalld 常用命令

1 防火墙 - firewalld 1.1 开启防火墙 # 临时性开启&#xff0c;服务器重启后会恢复为原来的状态 systemctl start firewalld # 永久性开启&#xff08;即开机启动&#xff09;&#xff0c;重启服务器后生效 systemctl enable firewalld1.2 关闭防火墙 # 临时性关闭&#xf…

基于ViutualBox+Ubuntu(Linux)的开发环境搭建

实际在选择虚拟机的时候纠结了要用virualbox还是vmware&#xff0c;初步比较结果&#xff1a; 1.virualbox能够使用vmware的硬盘格式&#xff0c;因此可以自由选择。 2.都能够实现主机和宿主机之间的文件夹共享。 3.virualbox是自由软件&#xff0c;vmware是商业软件。 在功能上…

LuatOS学习

开发顺序 Lua是脚本语言中运行速度最快的语言 资源占用极低 脚本语言运行方式 脚本语言是从上往下一行一行运行的 变量 coun 123456 a,b,c 1,2,3交换 a,b b,a在测试环境中&#xff0c;用print(a,b)打印 nil类型 未声明的变量就是nil&#xff0c;nil用来表示此变量为空…

5G工厂长啥样

5G工厂是一种新型的工业互联网基础设施&#xff0c;利用5G为代表的新一代信息通信技术集成&#xff0c;打造新型工业互联网基础设施。在5G工厂中&#xff0c;自动化和智能化设备广泛使用&#xff0c;高度互联的工厂网络得以实现&#xff0c;远程监控和管理成为可能&#xff0c;…

学习笔记——动态路由协议——OSPF(OSPF网络类型2)

2、OSPF网络类型 常见链路层协议对应的默认网络类型 网络类型 描述 常见链路层协议 Hello报文间隔 报文类型 有无DR、BDR选举 P2P 点对点网络 HDLC、PPP、LAPB 10s 以组播方式发送OSPF报文 有 P2MP 点对多点网络 无 30s 以组播方式发送Hello报文&#xff0c;单…

春秋云境CVE-2018-20604

简介 雷风影视CMS是一款采用PHP基于THINKPHP3.2.3框架开发&#xff0c;适合各类视频、影视网站的影视内容管理程序&#xff0c;该CMS存在缺陷&#xff0c;可以通过 admin.php?s/Template/edit/path/*web*..*..*..*..*1.txt 的方式读取任意文件。 正文 1.进入靶场 2./admin…

移动应用程序设计详解:基本概念和原理

移动应用程序设计是什么&#xff1f; 一般来说&#xff0c;应用程序设计师的核心职责是让用户有体验应用的欲望&#xff0c;而开发者负责让它正常工作。移动应用程序设计包括用户界面 (UI) 和用户体验 (UX)。设计者负责应用程序的整体风格&#xff0c;包括配色方案、字体选择、…

c语言游戏实战(3):三子棋

前言&#xff1a; 三子棋是一种民间传统游戏&#xff0c;又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏规则是双方对战&#xff0c;双方依次在9宫格棋盘上摆放棋子&#xff0c;率先将自己的三个棋子走成一条线就视为胜利。但因棋盘太小&#xff0c;三子棋在很多时候会出现和…

【记录】网络|没有路由器没有网线,分别使用手机或Windows电脑共享网络给ARM64开发板,应急连接

事情是这样的&#xff0c;我的开发板明明已经选择了记住热点 WiFi 密码&#xff0c;但是却没有在开机的时候自动连接&#xff0c;我又没有放显示器在身边&#xff0c;又不想为了这点事去找个显示器来&#xff0c;就非常难受。 我手边有的设备是&#xff1a; 笔记本电脑&#…

蓝桥杯物联网竞赛_STM32L071_18_长短按键检测

长短按键的检测是国赛题里面遇到的&#xff0c;省赛没出过有两种实方法 定时器配置&#xff1a; 定时器的话要比delay准确&#xff0c;其中tim7定时器的准度最高 定时器预分配配置32 - 1&#xff0c;计数周期是10000 - 1这样做那么32MHZ/32也就是一秒钟记录10^6的数&#xf…

重置服务器之后 SSH 登录报错:REMOTE HOST IDENTIFICATION HAS CHANGED!

问题原因&#xff1a; 报错是由于远程的主机的公钥发生了变化导致的。ssh服务是通过公钥和私钥来进行连接的&#xff0c;它会把每个曾经访问过计算机或服务器的公钥&#xff08;public key&#xff09;&#xff0c;记录在~/.ssh/known_hosts 中&#xff0c;当下次访问曾经访问…

【机器学习300问】102、什么是混淆矩阵?

一、混淆矩阵的定义 混淆矩阵是一种用于评估分类模型性能的评估指标。当模型对数据进行预测并将数据分配到预定义的类别时&#xff0c;混淆矩阵提供了一种直观的方式来总结这些预测与数据实际类别之间的对应关系。具体来说&#xff0c;它是一个表格。 二、分类模型性能评估一级…

[AIGC] Nginx常用变量详解

Nginx非常强大&#xff0c;其主要功能包括HTTP服务器、反向代理、负载均衡等。Nginx的配置中有许多内置的变量&#xff0c;你可以在配置文件中使用这些变量进行灵活的配置。在本篇文章中&#xff0c;我们将介绍一些Nginx中常见的变量&#xff0c;包括proxy_add_header。 常见变…

【windows】Total Uninstall:一款功能强大的完全卸载软件

软件介绍 Total Uninstall是一款专业的软件卸载工具&#xff0c;旨在帮助用户彻底地清除计算机上的应用程序&#xff0c;包括与应用程序相关的所有文件和注册表项。以下是Total Uninstall的一些主要功能和特点&#xff1a; 完全卸载&#xff1a;软件可以监视应用程序的安装过程…

Linux-CentOS7-解决vim修改不了主机名称(无法打开并写入文件)

Linux-CentOS7-修改主机名称 修改之后使用强制保存退出也不行。 解决办法&#xff1a; 使用hostnamectl命令进行修改 查看系统主机名和信息&#xff1a; hostnamectl这条命令会显示当前系统的主机名、操作系统信息、内核版本、架构信息等相关信息。 修改系统主机名&#xff1…

行为设计模式之状态模式

文章目录 概述定义结构图 2.代码示例小结 概述 定义 状态模式(state pattern)的定义: 允许一个对象在其内部状态改变时改变它的行为。 对象看起来似乎修改了它的类。 状态模式就是用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题.。状态模式将一个对象的状态…

免费插件集-illustrator插件-Ai插件-文本对象分行

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件4.功能解释5.总结 1.介绍 本文介绍一款免费插件&#xff0c;加强illustrator使用人员工作效率&#xff0c;进行文本对象分行。首先从下载网址下载这款插件 https://download.csdn.net/download/m0_67316550/87890501&…

ubuntu-24.04系统静态Mac和IP配置

操作系统版本&#xff08;桌面版&#xff09;&#xff1a;ubuntu-24.04-desktop-amd64.iso 原因说明&#xff1a;因网络的IP地址和Mac是预分配的&#xff0c;所以ubuntu系统需要修改网卡的mac地址和IP才能访问&#xff0c;网络查了半天资料都没成功&#xff0c;后再界面提示&a…

IC618 虚拟机 EDA Calibre2019 Hspice2018 Spectre19.1

虚拟机包含 CentOS 7.9 Cadence IC618 Calibre 2019 Hspice 2018 Spectre19.1 下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1aMtPO2G5ad-x5BtIJjCDig?pwdxcii 提取码&#xff1a;xcii