你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 1644|回复: 1

【HAL库每天一例】第019例:TIM-通用定时器输入捕获(电容按...

[复制链接]

122

主题

129

回帖

0

蝴蝶豆

论坛元老

最后登录
2019-5-28
发表于 2016-5-26 09:13:21 | 显示全部楼层 |阅读模式
本帖最后由 haohao663 于 2016-6-16 11:25 编辑

【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。
例程下载:
资料包括程序、相关说明资料以及软件使用截图
链接:https://pan.baidu.com/s/1i574oPv
密码:r3s3
(硬石YS-F1Pro开发板HAL库例程持续更新\1. 软件设计之基本裸机例程(HAL库版本)\YSF1_HAL-019. TIM-通用定时器输入捕获(电容按键)

/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: YSF1_HAL-019. TIM-通用定时器输入捕获(电容按键)
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:硬石电子社区
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */
【1】例程简介
  系统滴答定时器一般用来提供“心跳”作用,而STM32定时器最基本功能也是定时,可以设置不同
时间长度的定时。定时器除了最基本的定时功能外,定时器与GPIO有挂钩使得它可以发挥强大的作用,
比如可以输出不同频率、不同占空比的方波信号、PWM信号,同时做为输入捕获功能时,可以测量脉冲
宽度、实现电容按键检测等等。
  STM32F103ZET6总共有8个定时器,TIM1和TIM8是高级控制定时器,TIM2、3、4、5是通用定时器,
TIM6和TIM7是基本定时器。
电容按键在有和没有手指按下时充电时间有所不同,我们可以先对电容按键放电,测出没有手指按下
时充电时间,然后以它为基准,不断测出充电时间,如果有手指按下时得到的充电比没有手指按下有较
大不同,这样就可以判断电容按键状态。

【2】跳线帽情况
******* 为保证例程正常运行,必须插入以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP1        PA10        TXD(CH340G)          已接入
  JP2        PA9         RXD(CH340G)          已接入
  
【3】操作及现象
  使用开发板配套的MINI USB线连接到开发板标示“调试串口”字样的MIMI USB接口,在PC端打开
串口调试助手,设置参数为118200 8-NO-1。下载完程序之后,在串口调试助手可接收到提示信息,当
我们手指按下电容按键时,蜂鸣器响一声,在串口调试助手可以看到充电时间较没有按下时大。
/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
CubeMX_1.jpg
CubeMX_2.jpg
CubeMX_3.jpg
CubeMX_4.jpg
CubeMX_5.jpg
CubeMX_6.jpg
CubeMX_7.jpg
CubeMX_8.jpg
bsp_touchpad.h文件内容:
  1. #ifndef __TOUCHPAD_KEY_H__
  2. #define __TOUCHPAD_KEY_H__

  3. /* 包含头文件 ----------------------------------------------------------------*/
  4. #include "stm32f1xx_hal.h"

  5. /* 类型定义 ------------------------------------------------------------------*/

  6. /* 宏定义 --------------------------------------------------------------------*/
  7. #define TOUCHPAD_TIMx                        TIM5
  8. #define TOUCHPAD_TIM_RCC_CLK_ENABLE()        __HAL_RCC_TIM5_CLK_ENABLE()
  9. #define TOUCHPAD_TIM_RCC_CLK_DISABLE()       __HAL_RCC_TIM5_CLK_DISABLE()

  10. #define TOUCHPAD_GPIO_RCC_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
  11. #define TOUCHPAD_GPIO_PIN                    GPIO_PIN_1
  12. #define TOUCHPAD_GPIO                        GPIOA
  13. #define TOUCHPAD_TIM_CHANNEL                 TIM_CHANNEL_2
  14. #define TOUCHPAD_TIM_FLAG_CCR                TIM_FLAG_CC2

  15. // 定义定时器预分频,定时器实际时钟频率为:72MHz/(TOUCHPAD_TIMx_PRESCALER+1)
  16. #define TOUCHPAD_TIM_PRESCALER              47 //1.5MHz

  17. // 定义定时器周期
  18. #define TOUCHPAD_TIM_ARR                     0xFFFF

  19. /* 扩展变量 ------------------------------------------------------------------*/
  20. extern TIM_HandleTypeDef htimx;

  21. /* 函数声明 ------------------------------------------------------------------*/
  22. uint8_t TOUCHPAD_Init(void);
  23. uint8_t TOUCHPAD_Scan(uint8_t mode);

  24. #endif        /* __TOUCHPAD_KEY_H__ */
  25. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

bsp_touchpad.c文件内容:
  1. /* 包含头文件 ----------------------------------------------------------------*/
  2. #include "touchpad/bsp_touchpad.h"

  3. /* 私有类型定义 --------------------------------------------------------------*/
  4. /* 私有宏定义 ----------------------------------------------------------------*/
  5. //触摸的门限值,也就是必须大于tpad_default_val+TOUCHPAD_GATE_VAL,才认为是有效触摸.
  6. #define TOUCHPAD_GATE_VAL         80

  7. /* 私有变量 ------------------------------------------------------------------*/
  8. TIM_HandleTypeDef htimx;
  9. __IO  uint16_t tpad_default_val=0;/* 空载的时候(没有手按下),计数器需要的时间  */

  10. /* 扩展变量 ------------------------------------------------------------------*/
  11. /* 私有函数原形 --------------------------------------------------------------*/
  12. /* 函数体 --------------------------------------------------------------------*/
  13. /**
  14.   * 函数功能: 通用定时器初始化并配置通道PWM输出
  15.   * 输入参数: 无
  16.   * 返 回 值: 无
  17.   * 说    明: 无
  18.   */
  19. static void TOUCHPAD_TIMx_Init(void)
  20. {
  21.   TIM_ClockConfigTypeDef sClockSourceConfig;
  22.   TIM_MasterConfigTypeDef sMasterConfig;
  23.   TIM_IC_InitTypeDef sConfigIC;
  24.   
  25.   htimx.Instance = TOUCHPAD_TIMx;
  26.   htimx.Init.Prescaler = TOUCHPAD_TIM_PRESCALER;
  27.   htimx.Init.CounterMode = TIM_COUNTERMODE_UP;
  28.   htimx.Init.Period = TOUCHPAD_TIM_ARR;
  29.   htimx.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
  30.   HAL_TIM_Base_Init(&htimx);

  31.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  32.   HAL_TIM_ConfigClockSource(&htimx, &sClockSourceConfig);

  33.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  34.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  35.   HAL_TIMEx_MasterConfigSynchronization(&htimx, &sMasterConfig);
  36.   
  37.   sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  38.   sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  39.   sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  40.   sConfigIC.ICFilter = 3;
  41.   HAL_TIM_IC_ConfigChannel(&htimx, &sConfigIC, TOUCHPAD_TIM_CHANNEL);
  42. }

  43. /**
  44.   * 函数功能: 基本定时器硬件初始化配置
  45.   * 输入参数: htim_base:基本定时器句柄类型指针
  46.   * 返 回 值: 无
  47.   * 说    明: 该函数被HAL库内部调用
  48.   */
  49. void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
  50. {
  51.   GPIO_InitTypeDef GPIO_InitStruct;
  52.   if(htim_base->Instance==TOUCHPAD_TIMx)
  53.   {
  54.     /* 基本定时器外设时钟使能 */
  55.     TOUCHPAD_TIM_RCC_CLK_ENABLE();
  56.     /* 定时器通道引脚时钟使能 */
  57.     TOUCHPAD_GPIO_RCC_CLK_ENABLE();
  58.     /* 定时器通道引脚配置:捕获功能设置为输入模式 */
  59.     GPIO_InitStruct.Pin = TOUCHPAD_GPIO_PIN;
  60.     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  61.     GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  62.     HAL_GPIO_Init(TOUCHPAD_GPIO, &GPIO_InitStruct);
  63.   }
  64. }

  65. /**
  66.   * 函数功能: 基本定时器硬件反初始化配置
  67.   * 输入参数: htim_base:基本定时器句柄类型指针
  68.   * 返 回 值: 无
  69.   * 说    明: 该函数被HAL库内部调用
  70.   */
  71. void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
  72. {
  73.   if(htim_base->Instance==TOUCHPAD_TIMx)
  74.   {
  75.     /* 基本定时器外设时钟禁用 */
  76.     TOUCHPAD_TIM_RCC_CLK_DISABLE();
  77.    
  78.     HAL_GPIO_DeInit(TOUCHPAD_GPIO, TOUCHPAD_GPIO_PIN);
  79.   }
  80. }

  81. /**
  82.   * 函数功能: 复位一次,为电容按键放电
  83.   * 输入参数: 无
  84.   * 返 回 值: 无
  85.   * 说    明:无
  86.   */
  87. static void TOUCHPAD_Reset(void)
  88. {
  89.    /* 定义IO硬件初始化结构体变量 */
  90.   GPIO_InitTypeDef GPIO_InitStruct;
  91.         
  92.         /* 使能电容按键引脚对应IO端口时钟 */  
  93.   TOUCHPAD_GPIO_RCC_CLK_ENABLE();
  94.   
  95.   /* 设置引脚输出为低电平 */
  96.   HAL_GPIO_WritePin(TOUCHPAD_GPIO, TOUCHPAD_GPIO_PIN, GPIO_PIN_RESET);  
  97.   
  98.   /* 设定电容按键对应引脚IO编号 */
  99.   GPIO_InitStruct.Pin = TOUCHPAD_GPIO_PIN;
  100.   /* 设定电容按键对应引脚IO为输出模式 */
  101.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  102.   /* 设定电容按键对应引脚IO操作速度 */
  103.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  104.   /* 初始化电容按键对应引脚IO */
  105.   HAL_GPIO_Init(TOUCHPAD_GPIO, &GPIO_InitStruct);  

  106.         HAL_Delay(5);

  107.         __HAL_TIM_SET_COUNTER(&htimx,0); // 清零定时器计数  
  108.   __HAL_TIM_CLEAR_FLAG(&htimx, TIM_FLAG_UPDATE|TIM_FLAG_CC2);//清除中断标志
  109.   
  110.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  111.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  112.   HAL_GPIO_Init(TOUCHPAD_GPIO, &GPIO_InitStruct);
  113.   
  114.   HAL_TIM_IC_Start(&htimx,TOUCHPAD_TIM_CHANNEL);  
  115. }

  116. /**
  117.   * 函数功能: 得到定时器捕获值,如果超时,则直接返回定时器的计数值.
  118.   * 输入参数: 无
  119.   * 返 回 值: uint16_t:定时器捕获值
  120.   * 说    明:无
  121.   */
  122. static uint16_t TOUCHPAD_Get_Val(void)
  123. {
  124.         TOUCHPAD_Reset();
  125.         while(__HAL_TIM_GET_FLAG(&htimx,TOUCHPAD_TIM_FLAG_CCR)==RESET)
  126.   {   
  127.     uint16_t count;
  128.     count=__HAL_TIM_GET_COUNTER(&htimx);
  129.                 if(count>(TOUCHPAD_TIM_ARR-500))
  130.       return count;//超时了,直接返回CNT的值
  131.         };        
  132.         return HAL_TIM_ReadCapturedValue(&htimx,TOUCHPAD_TIM_CHANNEL);         
  133. }

  134. /**
  135.   * 函数功能: 读取n次,取最大值
  136.   * 输入参数: n:连续获取的次数
  137.   * 返 回 值: n次读数里面读到的最大读数值
  138.   * 说    明:无
  139.   */
  140. static uint16_t TOUCHPAD_Get_MaxVal(uint8_t n)
  141. {
  142.         uint16_t temp=0;
  143.         uint16_t res=0;
  144.         while(n--)
  145.         {
  146.                 temp=TOUCHPAD_Get_Val();//得到一次值
  147.                 if(temp>res)res=temp;
  148.         };
  149.         return res;
  150. }  

  151. /**
  152.   * 函数功能: 初始化触摸按键,获得空载的时候触摸按键的取值.
  153.   * 输入参数: 无
  154.   * 返 回 值: 0,初始化成功;1,初始化失败
  155.   * 说    明:无
  156.   */
  157. uint8_t TOUCHPAD_Init(void)
  158. {
  159.         uint16_t buf[10];
  160.         uint16_t temp;
  161.         uint8_t i,j;
  162.   /* 以1.5Mhz的频率计数  */
  163.         TOUCHPAD_TIMx_Init();
  164.   HAL_TIM_IC_Start(&htimx,TOUCHPAD_TIM_CHANNEL);
  165.   
  166.   /* 连续读取10次 */
  167.         for(i=0;i<10;i++)
  168.         {                                 
  169.                 buf[i]=TOUCHPAD_Get_Val();
  170.                 HAL_Delay(10);            
  171.         }
  172.   /* 排序 */
  173.         for(i=0;i<9;i++)
  174.         {
  175.                 for(j=i+1;j<10;j++)
  176.                 {
  177.       /* 升序排列 */
  178.                         if(buf[i]>buf[j])
  179.                         {
  180.                                 temp=buf[i];
  181.                                 buf[i]=buf[j];
  182.                                 buf[j]=temp;
  183.                         }
  184.                 }
  185.         }
  186.         temp=0;
  187.   /* 取中间的6个数据进行平均 */
  188.         for(i=2;i<8;i++)temp+=buf[i];
  189.         tpad_default_val=temp/6;
  190.         printf("tpad_default_val:%d\r\n",tpad_default_val);        
  191.   /* 初始化遇到超过TPAD_ARR_MAX_VAL/2的数值,不正常! */
  192.         if(tpad_default_val>TOUCHPAD_TIM_ARR/2)return 1;
  193.         return 0;                                                                           
  194. }

  195. /**
  196.   * 函数功能: 扫描触摸按键
  197.   * 输入参数: mode:0,不支持连续触发(按下一次必须松开才能按下一次);1,支持连续触发(可以一直按下)
  198.   * 返 回 值: 0,没有按下;1,有按下;        
  199.   * 说    明:无
  200.   */
  201. uint8_t TOUCHPAD_Scan(uint8_t mode)
  202. {
  203.         static uint8_t keyen=0;        //0,可以开始检测;>0,还不能开始检测         
  204.         uint8_t res=0;
  205.         uint8_t sample=3;                //默认采样次数为3次         
  206.         uint16_t rval;
  207.         if(mode)
  208.         {
  209.                 sample=6;        //支持连按的时候,设置采样次数为6次
  210.                 keyen=0;        //支持连按         
  211.         }
  212.         rval=TOUCHPAD_Get_MaxVal(sample);
  213.         printf("scan_rval=%d\n",rval);
  214.         if(rval>(tpad_default_val+TOUCHPAD_GATE_VAL))//大于tpad_default_val+TPAD_GATE_VAL,有效
  215.         {                                                
  216.                   rval=TOUCHPAD_Get_MaxVal(sample);                 
  217.                 if((keyen==0)&&(rval>(tpad_default_val+TOUCHPAD_GATE_VAL)))//大于tpad_default_val+TPAD_GATE_VAL,有效
  218.                 {
  219.                         res=1;
  220.                 }                                                                  
  221.                 keyen=5;                                //至少要再过5次之后才能按键有效   
  222.         }else if(keyen>2)keyen=2;         //如果检测到按键松开,则直接将次数将为2,以提高响应速度
  223.         if(keyen)keyen--;                                                                                                                                                         
  224.         return res;
  225. }         
复制代码

串口调试助手截图.jpg

stm32f103zet6定时器功能引脚.png
<
回复

使用道具 举报

0

主题

153

回帖

0

蝴蝶豆

中级会员

最后登录
2020-1-5
发表于 2016-7-2 12:44:43 | 显示全部楼层
多谢楼主分享!
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版