1.电容触摸按键原理

R:外接电容充放电电阻;Cs:TPAD和PCB间的杂散电容;Cx:手指按下时,手指和TPAD之间的电容;开关:电容放电开关,由STM32IO口代替。

2.电容充电时间与电容大小的关系

同样的条件下,电容值C跟时间t成正比关系,电容越大,充电到达某个临界值的时间越长。

3.检测电容触摸按键过程

(1)TPAD引脚设置为推挽输出,输出0,实现电容放电到0;

(2)TPAD引脚设置为浮空输入(IO口复位后的状态),电容开始充电;

(3)同时开启TPAD引脚的输入捕获,开始捕获;

(4)等待充电完成(充电到底Vx,检测到上升沿);

(5)计算充电时间。

没有按下的时候,充电的时间为T1(default)。按下TPAD,电容变大,所以充电时间为T2。我们可以

通过检测充放电的时间,来判断是否按下。如果T2-T1大于某个值,就可以有按键按下。

实验内容

手触摸按键后,LED1灯翻转。

硬件连接 

 软件设计

1.相关库函数

(1)void TPAD_Reset(void)函数:复位TPAD

设置IO口为推挽输出输出0,电容放电。等待放电完成之后,设置为浮空输入,从而开始充电。同时把计数器的CNT设置为0;

(2)TPAD_Get_Val()函数:获取一次捕获值(得到充电时间)

复位TPAD,等待捕获上升沿,捕获之后,得到定时器的值,计算充电时间;

(3)TPAD_Get_MaxVal()函数:

多次调用TPAD_Get_Val函数获取充电时间。获得最大值。

(4)TPAD_Init()函数:初始化TPAD

在系统初启动后,初始化输入捕获。先10次调用TPAD_Get_Val()函数获取10次充电时间,然后获取中间N(N=8或者6)次的平均值,作为在没有电容触摸按键按下时的时候的充电时间缺省值tpad_default_val;

(5)TPAD_Scan()函数:扫描TPAD

调用TPAD_Get_MaxVal()函数获取多次充电中最大的充电时间,跟tpad_default_val比较,如果大于某个阈值,则认为有触摸动作;

(6)void TIM5_CH2_Cap_Init(u16 arr,u16 psc)函数:输入捕获通道初始化

2.程序思路

3.实验代码

tpad.h

#ifndef __TPAD_H__
#define __TPAD_H__
#include "sys.h"void TPAD_Reset(void);
u16 TPAD_Get_Val(void);
u16 TPAD_Get_MaxVal(u8 n);
u8 TPAD_Init(u8 psc);
u8 TPAD_Scan(u8 mode);
void TIM2_CH1_Cap_Init(u32 arr,u16 psc);#endif

tpad.c

#include "tpad.h"
#include "usart.h"
#include "sys.h"
#include "delay.h"#define TPAD_ARR_MAX_VAL 0xFFFFFFFF        //最大的ARR值
vu16 tpad_default_val=0;                   //空载的时候,计数器需要的时间void TPAD_Reset(void)                      //TPAD复位
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;    //PA5GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//普通输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度100MHzGPIO_InitStructure.GPIO_OType=GPIO_OType_pp;    //推挽GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;    //下拉GPIO_Init(GPIOA,&GPIO_InitStructure)            //初始化PA5GPIO_ResetBits(GPIOA,GPIO_Pin_5);               //输出0,放电delay_ms(5);TIM_ClearITPendingBit(TIM2,TIM_IT_CC1|TIM_IT_Update);//清除中断标志TIM_SetCounter(TIM2,0);                         //归0GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;    //复用输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度100MHzGPIO_InitStructure.GPIO_OType=GPIO_OType_PP;    //推挽GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;  //不带上下拉GPIO_Init(GPIOA,&GPIO_InitStructure);           //初始化PA5}u16 TPAD_Get_Val(void)        //得到定时器捕获值
{TPAD_Reset();while(TIM_GetFlagStatus(TIM2,TIM_IT_CC1)==RESET)//等待捕获上升沿{    if(TIM_GetCounter(TIM2)>TPAD_ARR_MAX_VAL-500)return TIM_GetCounter(TIM2);//超时了,直接返回CNT的值}return TIM_GetCapture1(TIM2);//若没超时,返回TIM2_CCR2的值
}u16 TPAD_Get_MaxVal(u8 n)        //读取n次,取最大值
{u16 temp=0,res=0;while(n--){temp=TPAD_Get_Val();    //得到一次值if(temp>res)res=temp;}return res;
}u8 TPAD_Init(u8 psc)           //初始化触摸按键
{u16 buf[10],temp;u8 j,i;TIM2_CH1_Cap_Init(TPAD_ARR_MAX_VAL,psc-1);    //设置分频系数for(i=0;i<10;i++){buf[i]=TPAD_Get_Val();delay_ms(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++)//取中间的6个数据进行平均tpad_default_val=temp/6;printf("tpad_default_val:%d\r\n",tpad_default_val);if(tpad_default_val>TPAD_ARR_MAX_VAL/2)return 1;//初始化遇到超过TPAD_ARR_MAX_VAl/2的数值,不正常return 0;
}#define TPAD_GATE_VAL 100    //触摸的门限值
u8 TPAD_Scan(u8 mode)  //扫描触摸按键
{static u8 keyen=0;    //0,可以开始检测;>0,还不能开始检测u8 res=0;             //res=0说明按键无效,res=1说明按键有效sample=3;             //默认采样次数为3次u16 rval;            if(mode)              //mode:0,不支持连续触发{sample=6;         //支持连按的时候,设置采样次数为6次keyen=0;          //支持连按}rval=TPAD_Get_MaxVal(sample);    //连续采样3次,取最大值if(rval>(tpad_default_val+TPAD_GATE_VAL)&&rval<(10*tpad_default_val)){if((keyen==0)&&(rval>(tpad_default_val+TPAD_GATE_VAL)))res=1;keyen=3;}if(keyen)keyen--;return res;
}void TIM2_CH1_Cap_Init(u32 arr,u16 psc) //定时器2通道2输入捕获
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM2_ICInitTypeDef TIM2_ICInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);    //TIM2时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);    //使能PORTA时钟GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_TIM2);    //PA5复用为定时器2GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;    //GPIOA5GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;  //复用功能GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;    //速度100MHzGPIO_InitStructure.GPIO_OType=GPIO_OType_PP;        //推挽复用输出GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;      //不带上下拉GPIO_Init(GPIOA,&GPIO_InitStructure);               //初始化PA5TIM_TimeBaseInitStructure.TIM_Period=arr;            //设计定时器自动重装载值TIM_TimeBaseInitStructure.TIM_Prescaler=psc;         //预分频器TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//TIM向上计数TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);   //初始化定时器2TIM2_ICInitStructure.TIM_Channel=TIM_Channel_1;    //选择输入端IC1映射到TIM2TIM2_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising    //上升沿捕获TIM2_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;TIM2_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;    //配置输入分频,不分频TIM2_ICInitStructure.TIM_ICFilter=0x00;                //不滤波TIM_ICInit(TIM2,TIM2_ICInitStructure);                //使能定时器2TIM_Cmd(TIM2,ENABLE);    //使能定时器2
}

main.c

#include "sys.h"
#include "tpad.h"
#include "led.h"
#include "usart.h"
#include "delay.h"int main(void)
{U8 t=0;NVIC_PriorityGroupConfig(NVIC_PriorityGruop_2);//设置系统中断优先级分组2delay_init(168);    //初始化延时函数uart_init(115200);    //初始化串口波特率115200LED_Init();    //初始化LEDTPAD_Init(8);    //初始化触摸按键while(1){if(TPAD_Scan(0)) //成功捕获到了一次上升沿{LED1=!LED1;    //LED1取反}t++;if(t==15){t=0;LED0=!LED0;    //LED0取反,提示程序正在运行}delay_ms(10);}
}

STM32学习(电容触摸按键)相关推荐

  1. 【STM32】电容触摸按键控制模块详解(代码、流程图、每行均有注释)

    STM32-电容触摸按键控制模块详解(代码.每行均有注释) 阿汪先生用的开发板是正点原子的战舰板,但本部分代码通用于STM32的各个开发板. 本文是针对正点原子提供的例程的详细补充,重点是扫描触摸按键 ...

  2. STM32精英版(正点原子STM32F103ZET6开发板)学习篇12——电容触摸按键实验

    电容触摸按键原理 RC充放电电路原理:   RC充放电原理,其实就是电(R)和电容(C)组成的串联电路.   按键开关未按下时,电路两端电压都是0V,无法形成电势差,也就无法形成电流.但当按键开关按下 ...

  3. STM32学习心得十九:电容触摸按键实验及相关代码解读

    记录一下,方便以后翻阅~ 主要内容 1) 电容触摸按键原理: 2)部分实验代码解读. 实验内容 手触摸按键后,LED1灯翻转. 硬件原理图 上图,TPAD与STM_ADC用跳线帽相连,即TPAD与PA ...

  4. stm32按键矩阵代码_STM32学习日志——电容触摸按键实验(20-06-27)

    昨天在公司值班学习的,敲完代码笔记本没电了,没更新日志,今天补更新.学习应持之以恒,谁都会有惰性,应尽力克服. 这次的代码很有意思,可以学到很多编程的思想. 首先,电容触摸按键是基于模电的RC充放电电 ...

  5. 判断按键值_「正点原子NANO STM32开发板资料连载」第十六章电容触摸按键实验...

    1)实验平台:ALIENTEK NANO STM32F411 V1开发板2)摘自<正点原子STM32F4 开发指南(HAL 库版>关注官方微信号公众号,获取更多资料:正点原子 第十六章电容 ...

  6. 【STM32】(10) 电容触摸按键实验(含代码)、电容触摸按键过程和相关函数介绍

    一.电容触摸按键简介 我们只要能够区分Tcs和Tcs+Tcx,就已经可以实现触摸检测了,当充电时间在Tcs附近,就可以认为没有触摸,而当充电时间大于Tcs+Tx时,就认为有触摸按下(Tx为检测阀值). ...

  7. 基于STM32F103ZET6主控平台实现电容触摸按键 [基于TIM5_CH2(PA1)的输入捕获]

    一个热爱代码的工程师,唯有凭借双手不断敲打,才可以快速提升实力! 本文谨以记录,日后相忘时再作复习,代码没有贵贱,既来之则安之. 本次实验中我们将用 TIM5 的通道 2( PA1)来做输入捕获,并实 ...

  8. STM32学习笔记(八)丨ADC模数转换器(ADC单、双通道转换)

    本篇文章包含的内容 一.ADC 模数转换器 1.1 ADC简介 1.2 逐次逼近型ADC工作原理 1.3 STM32中的ADC基本结构 1.4 STM32中ADC的输入通道 1.5 STM32中的AD ...

  9. STM32学习——TFTLCD原理

    STM32学习--TFTLCD原理 一.TFTLCD 简介 TFT-LCD 即薄膜晶体管液晶显示器(Thin Film Transistor-Liquid Crystal Display) TFT-L ...

  10. STM32学习笔记:FLASH读写之一

    因为关于STM32的Flash相关的知识点比较多,所以该内容的学习我们分为以下4个部分 1.RAM和ROM的一些基本概念 -- STM32学习笔记:FLASH读写之一 2.STM32的Flash寄存器 ...

最新文章

  1. XML专题:使用NSXMLParser解析xml文件
  2. python画曲线图例-如何使用python画曲线图
  3. lambda表达式_Lambda表达式详解
  4. 疑问:关于Microsoft Office InfoPath 2003 Toolkit for Visual Studio 2005 Beta 2
  5. java线程“生产/消费”模型2
  6. Java输出特定时间段特定格式时间信息
  7. 面试必会之HashMap源码分析
  8. 【Qt串口波形绘图】基于QCustomPlot的串口波形绘图上位机,源码开放
  9. CISCO安全 ×××技术
  10. python大作业报告(爬虫 分析 可视化)_python第四次周末大作业
  11. 用c语言莲花,用荷花为寓意的网名-网名搜索
  12. jenkins+svn+脚本实现CIDI
  13. Impala graceful shutdown功能介绍
  14. 第三代CAN-XL通信技术CiA 610有什么特点
  15. 借助 usb转rs232 模块实现两台电脑文件的传输
  16. pg 百万数据表 添加序号 20秒轻松搞定
  17. 4K Stogram Mac版(Instagram照片下载工具)中文版
  18. DNS欺骗与钓鱼网站
  19. dann的alpha torch_win10安装NVIDIA驱动 + cuda +cundann+pytorch
  20. python os模块(1)

热门文章

  1. android horizontalscrollview顶部导航,带有居中效果的HorizontalScrollView使用说明
  2. JLink引脚定义、JTAG引脚定义、SWD引脚定义
  3. 证件管理系统开发1 :明确需求
  4. 微信小程序怎么字体鼠标放上去变颜色?_【干货】CDR快捷键常识小技巧大全,记得收藏!...
  5. 视频教程-Mugeda(木疙瘩)H5案例课—快闪制作-HTML5/CSS
  6. vs2013 update5离线升级包下载地址
  7. g729语音编码 matlab,Case7 FreeSwitch配置开启转码功能及安装G729语音编码
  8. 深度学习 简介 综述
  9. 华为浏览器工具箱 html修改,华为手机修改浏览器模式为电脑浏览模式的方法
  10. 静态链表 ( 数据结构 )