datasheet

STM32f4电容触摸按键实验代码(02)

2018-10-05来源: eefocus 关键字:STM32f4  电容触摸  按键实验

STM32f4————电容触摸按键实验代码(02)

 

//定时器 2通道2 输入捕获配置    

//arr:自动重装值

//psc:时钟预分频数

void TIM2_CH1_Cap_Init(u32 arr,u16 psc)

{

  GPIO_InitTypeDef  GPIO_InitStructure;  

      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

  TIM_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复用位定时器2

 

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //GPIOA5

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//速度 100MHz

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//不带上下拉  

  GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA5

 

    //初始化 TIM2   

  TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值    

  TIM_TimeBaseStructure.TIM_Prescaler =psc;    //预分频器        

  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //  初始化定时器2

  //初始化通道 1

     TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端  IC1映射到TIM2

     TIM2_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;//IC2F=0000 配置输入滤波器 不滤波

     TIM_ICInit(TIM2, &TIM2_ICInitStructure);//初始化 TIM2 IC1

                              

  TIM_Cmd(TIM2,ENABLE );    //使能定时器 2

}

此部分代码包含 6 个函数,我们将介绍其中 4 个比较重要的函数:TIM2_CH1_Cap_Init、TPAD_Get_Val、TPAD_Init和 TPAD_Scan。

首先介绍TIM2_CH1_Cap_Init函数,该函数和上一章的输入捕获函数基本一样,不同的是,这里我们设置的是 TIM2 上一章是 TIM5。通过该函数的设置,我们将可以捕获 PA5 上的上升沿,同样TIM2也是 32 位定时器。

我们再来看看 TPAD_Get_Val 函数,该函数用于得到定时器的一次捕获值。该函数先调用TPAD_Reset,将电容放电,同时设置通过调用函数TIM_SetCounter(TIM2,0)将计数值TIM2_CNT设置为 0,然后死循环等待发生上升沿捕获(或计数溢出),将捕获到的值(或溢出值)作为返回值返回。

接着我们介绍 TPAD_Init 函数,该函数用于初始化输入捕获,并获取默认的 TPAD 值。该函数有一个参数,用来传递系统时钟,其实是为了配置 TIM2_CH1_Cap_Init 为 1us 计数周期。在该函数中连续 10 次读取TPAD 值,将这些值升序排列后取中间 6 个值再做平均(这样做的目的是尽量减少误差),并赋值给tpad_default_val,用于后续触摸判断的标准。  

最后,我们来看看 TPAD_Scan 函数,该函数用于扫描 TPAD 是否有触摸,该函数的参数mode,用于设置是否支持连续触发。返回值如果是 0,说明没有触摸,如果是 1,则说明有触摸。该函数同样包含了一个静态变量,用于检测控制,类似第八章的KEY_Scan 函数。所以该函数同样是不可重入的。在函数中,我们通过连续读取 3 次(不支持连续按的时候)TPAD 的值,取这他们的最大值,和tpad_default_val+TPAD_GATE_VAL 比较,如果大于则说明有触摸,如果小于,则说明无触摸。其中tpad_default_val 是我们在调用 TPAD_Init 函数的时候得到的值,而TPAD_GATE_VAL则是我们设定的一个门限值(这个大家可以通过实验数据得出,根据实际情况选择适合的值就好了),这里我们设置为 100。该函数,我们还做了一些其他的条件限制,

让触摸按键有更好的效果,这个就请大家看代码自行参悟了。

tpad.h 头文件部分代码比较简单,这里不做介绍。

接下来我们看看主函数代码如下:

int main(void)

{     

u8 t=0;  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2

  delay_init(168);     //初始化延时函数

  uart_init(115200);    //初始化串口波特率为115200

  LED_Init();            //初始化 LED

  TPAD_Init(8);        //初始化触摸按键,以 84/4=21Mhz频率计数

     while(1)

  {                                  

      if(TPAD_Scan(0))  //成功捕获到了一次上升沿(此函数执行时间至少15ms)

    {

      LED1=!LED1;    //LED1取反

    }

    t++;

    if(t==15)      

    {

      t=0;   LED0=!LED0;    //LED0取反,提示程序正在运行

    }

    delay_ms(10);

  }

}

该 main函数比较简单,TPAD_Init(8)函数执行之后,就开始触摸按键的扫描,当有触摸的时候,对DS1 取反,而DS0 则有规律的间隔取反,提示程序正在运行。注意在修改main函数之后,还需要在main.c里面添加tpad.h头文件,否则会报错哦。

这里还要提醒一下大家,不要把uart_init(115200);去掉,因为在TPAD_Init函数里面,我们有用到 printf,如果你去掉了uart_init,就会导致printf无法执行,从而死机。  

至此,我们的软件设计就完成了。


关键字:STM32f4  电容触摸  按键实验

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2018/ic-news100541481.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:单片机AD转换汇总
下一篇:STM32f4输入捕获实验代码

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32F10x系列UART中断异常调试经历

硬件环境: STM32F105RCT6软件环境:FreeRTOSV8问题描述:采用中断方式接收数据,然后将收到的一帧数据放入消息队列,然后有专门的一个任务用来从消息队列中取数据并处理。jlink调试以及烧录运行都是可以的,但是当随着通信频率的增加以及运行时间的加长,系统会出现“死机”(即,不停的进入中断而致使主程序流程无法执行);问题分析:根据现象猜测   1、是否为堆栈溢出了呢?  2、是否频率太高了呢? 3、是否标志位忘记没有清除呢?然后逐项进行测试:1、查htm文件确定大概需要的堆栈,发现确实存在溢出的可能:而我分配的为:然后更改为0x00000800,烧录测试,还是存在同样问题,然后在调试串口
发表于 2018-12-03
STM32F10x系列UART中断异常调试经历

STM32F103做从机SPI通信SPI3中断异常

在做AM335D板子与STM32F103使用SPI通信时,需要用到STM32的从机模式,所以特别对于ST的从机模式进行了研究,由于硬件上使用的是STM32F103的SPI3,所以过程中遇到了一点麻烦,这里记录一下过程,以备查阅:使用SPI3通信时,从机时钟产生不了中断,经过查阅资料,是因为spi3的nss口与JTAG有共用引脚,所以配置错误会导致SPI3无法使用。需要注意以下两点就可以了:1.开启GPIO时钟的同时,开启AFIO时钟,如下:RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE ); 
发表于 2018-12-03

STM32F030使用RTC周期性唤醒STOP模式

首先,F030与F072的RTC唤醒功能是不一样的,在相关定义文件stm32f0xx_exti.h中有如下定义:#define EXTI_Line17      ((uint32_t)0x00020000)  /*!< Internal interrupt line 17                                            
发表于 2018-12-03

STM32F429之中断服务函数名

以下内容在startup_stm32f429_439xx.s文件内;******************** (C) COPYRIGHT 2015 STMicroelectronics ********************;* File Name          : startup_stm32f429_439xx.s;* Author             : MCD Application Team;* @version           
发表于 2018-12-03

STM32F407学习笔记——Systick中断

#include <stm32f4xx.h> GPIO_TypeDef* io_led=GPIOC;const u16 pin_led=GPIO_Pin_1; static __IO uint32_t TimingDelay; void Led_Init(){ GPIO_InitTypeDef GPIO_init_l; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); GPIO_init_l.GPIO_Pin=GPIO_Pin_1; GPIO_init_l.GPIO_Mode=GPIO_Mode_OUT
发表于 2018-12-01

stm32f103 rcc时钟寄存器设置和usart寄存器

这几天把rcc时钟搞明白了。其实主要是流程 看错了计算器1到31位,结果是错位了,一直找不到原因。原来mac 自带编程计算器也是从0到31stm32中文手册讲得比较明白自己摸索下设置了串口发送数据自己用的是蓝色药丸 (blue pill )淘宝10块不到一小块 stm32f103c8t6led灯是portc 13脚本程序全部是用寄存器方式设置#include "stm32f10x_lib.h"#include#include "sys.h"//测试c++ class LED{public:  LED();  ~LED();  }; 
发表于 2018-11-30
stm32f103 rcc时钟寄存器设置和usart寄存器

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved
pt type="text/javascript" src="//v3.jiathis.com/code/jia.js?uid=2113614" charset="utf-8">