STM32 输入捕获工作过程(通道1为例)

通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。

输入捕获1滤波器 ICIF[3:0],这个用来设置输入采样频率和数字滤波器长度。其中,fck_INT
是定时器的输入频率(TIMxCLK),一般为 84Mhz,而fDTS则是根据 TIMx_CRI 的 CKD[1:0]
的设置来确定的,如果 CKD[1:0]设置为 00,那么fDTS=fcx_INT。N 值就是滤波长度,举个简
单的例子;假设 IC1F[3:0]=0011,并设置IC1映射到通道1上,且常g升沿触发。那么在捕获
到上升沿的时候,再以fck_INT的频率,连续采样到8次通道1 的电平,如果都是高电平,则说
明却是一个有效的触发,就会触发输入捕获中断(如果开启了的话)。这样可以滤除那些高电平
脉宽低于 8 个采样周期的脉冲信号,从而达到滤波的效果。这里,我们不做滤泼处理,所以设
置ICIF(3:0]=0000,只要采集到上升沿,就触发捕获。


 通过设置CC1P的值来设置输入捕获的极性(上升沿/下降沿)。

通过设置CC1S[1:0]的值来设置输入捕获映射通道可以来自通道2。

 输入捕获通道初始化函数:

void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);

typedef struct
{uint16_t TIM_Channel; //捕获通道1-4   uint16_t TIM_ICPolarity; //捕获极性uint16_t TIM_ICSelection; //映射关系uint16_t TIM_ICPrescaler; //分频系数uint16_t TIM_ICFilter;  //滤波器
} TIM_ICInitTypeDef;TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM5_ICInitStructure.TIM_ICFilter = 0x00;
TIM_ICInit(TIM5, &TIM5_ICInitStructure);

通道极性设置独立函数:

void TIM_OCxPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);

获取通道捕获值

uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx);

输入捕获的一般配置步骤:

① 初始化定时器和通道对应IO的时钟。

② 初始化IO口,模式为复用:GPIO_Init();

③设置引脚复用映射: GPIO_PinAFConfig();

④初始化定时器ARR,PSC

TIM_TimeBaseInit();

⑤初始化输入捕获通道

TIM_ICInit();

⑥如果要开启捕获中断,

TIM_ITConfig();

NVIC_Init();

⑦使能定时器:TIM_Cmd();

⑧编写中断服务函数:TIMx_IRQHandler();

程序

实验目的:测量信号的脉冲宽度

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
u8 TIM5CH1_CAPTURE_STA=0; //输入捕获状态
u32 TIM5CH1_CAPTURE_VAL;//输入捕获值(TIM2/TIM5 是 32 位)void TIM_Init(u32 arr,u32 psc)
{GPIO_InitTypeDef GPIO_Initer;TIM_TimeBaseInitTypeDef TIM_TimeBaseIniter;TIM_ICInitTypeDef TIM_ICIniter;NVIC_InitTypeDef NVIC_Initer;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);GPIO_Initer.GPIO_Mode=GPIO_Mode_AF;GPIO_Initer.GPIO_OType=GPIO_OType_PP;GPIO_Initer.GPIO_Pin=GPIO_Pin_0;GPIO_Initer.GPIO_PuPd=GPIO_PuPd_DOWN;GPIO_Initer.GPIO_Speed=GPIO_Speed_100MHz;GPIO_Init(GPIOA,&GPIO_Initer);GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5);TIM_TimeBaseIniter.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseIniter.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseIniter.TIM_Period=arr;TIM_TimeBaseIniter.TIM_Prescaler=psc;TIM_TimeBaseInit(TIM5,&TIM_TimeBaseIniter);TIM_ICIniter.TIM_Channel = TIM_Channel_1;TIM_ICIniter.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM_ICIniter.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICIniter.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM_ICIniter.TIM_ICFilter = 0x00;TIM_ICInit(TIM5,&TIM_ICIniter);TIM_ITConfig(TIM5,TIM_IT_CC1|TIM_IT_Update,ENABLE);NVIC_Initer.NVIC_IRQChannel=TIM5_IRQn;NVIC_Initer.NVIC_IRQChannelCmd=ENABLE;NVIC_Initer.NVIC_IRQChannelPreemptionPriority=2;NVIC_Initer.NVIC_IRQChannelSubPriority=2;NVIC_Init(&NVIC_Initer);TIM_Cmd(TIM5,ENABLE);
}
void TIM5_IRQHandler()
{if((TIM5CH1_CAPTURE_STA&0x80)==0)//未完成捕获{if(TIM_GetITStatus(TIM5, TIM_IT_Update))//溢出中断{if((TIM5CH1_CAPTURE_STA&0x40)==1)//捕获到高电平{if(TIM5CH1_CAPTURE_STA==0x7f){TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获了一次TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;}else TIM5CH1_CAPTURE_STA++;}}if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获 1 发生捕获事件{if(TIM5CH1_CAPTURE_STA&0X40)//捕获到一个下降沿{ TIM5CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//获取当前的捕获值.TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //设置上升沿捕获}else //还未开始,第一次捕获上升沿{TIM5CH1_CAPTURE_STA=0;//清空TIM5CH1_CAPTURE_VAL=0;TIM5CH1_CAPTURE_STA|=0X40;//标记捕获到了上升沿TIM_Cmd(TIM5,ENABLE ); //使能定时器 5TIM_SetCounter(TIM5,0); //计数器清空TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);//设置下降沿捕获TIM_Cmd(TIM5,ENABLE ); //使能定时器 5}}}TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}
int main(void)
{ long long temp=0;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);LED_Init();               KEY_Init();delay_init(168);uart_init(115200);   TIM_Init(0xffffffff,84-1);LED0=0;                 while(1){//delay_ms(10);if(TIM5CH1_CAPTURE_STA&0x80){temp=TIM5CH1_CAPTURE_STA&0x3f; temp=TIM5CH1_CAPTURE_VAL+temp*0xffffffff; printf("HIGH:%lld us\r\n",temp);TIM5CH1_CAPTURE_STA=0;}}
}

在中断服务函数TIM5_IRQHandler用到了两个全局变量,用于辅助实现 高电平捕获。其中 TIM5CH1_CAPTURE_STA,是用来记录捕获状态,该变量类似我们在 usart.c 里面自行定义的 USART_RX_STA 寄存器(其实就是个变量,只是我们把它当成一个寄存器那样 来使用)。

另外一个变量 TIM5CH1_CAPTURE_VAL,则用来记录捕获到下降沿的时候,TIM5_CNT 的值。捕获高电平脉宽的思路:首先,设置 TIM5_CH1 捕获上升沿,这在 TIM5_Cap_Init 函数执行的时候就设置好了,然后等待上升沿中断到来,当捕获到上升沿中断, 此时如果 TIM5CH1_CAPTURE_STA 的第 6 位为 0,则表示还没有捕获到新的上升沿,就先把 TIM5CH1_CAPTURE_STA、TIM5CH1_CAPTURE_VAL 和计数器值 TIM5->CNT 等清零,然后 再设置 TIM5CH1_CAPTURE_STA 的第 6 位为 1,标记捕获到高电平,最后设置为下降沿捕获, 等待下降沿到来。如果等待下降沿到来期间,定时器发生了溢出(对 32 位定时器来说,很难溢 出),就在 TIM5CH1_CAPTURE_STA 里面对溢出次数进行计数,当最大溢出次数来到的时候, 就强制标记捕获完成(虽然此时还没有捕获到下降沿)。当下降沿到来的时候,先设置 TIM5CH1_CAPTURE_STA 的第 7 位为 1,标记成功捕获一次高电平,然后读取此时的定时器 值到 TIM5CH1_CAPTURE_VAL 里面,最后设置为上升沿捕获,回到初始状态。 这样,就完成一次高电平捕获了,只要 TIM5CH1_CAPTURE_STA 的第 7 位一直为 1, 那么就不会进行第二次捕获,在main函数处理完捕获数据后,将TIM5CH1_CAPTURE_STA 置零,就可以开启第二次捕获。

运行视频

输入捕获实验

STM32输入捕获实验相关推荐

  1. stm32f401 边沿捕获_STM32_capture 基于 设计的输入捕获实验,通过对边沿跳变的采集,得到外部接口 据。 SCM 单片机开发 261万源代码下载- www.pudn.com...

    文件名称: STM32_capture下载  收藏√  [ 5  4  3  2  1 ] 所属分类: SCM 开发工具: Visual C++ 文件大小: 447 KB 上传时间: 2016-07- ...

  2. cc2530定时器和捕获比较_ALIENTEK 阿波罗 STM32F767 开发板资料连载十四章 输入捕获实验...

    1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 http://weixi ...

  3. stm32 输入捕获 测量脉宽

    选用通用定时器TIM5的CH1. PA0接一个按键,默认接GND,当按键按下时,IO口被拉高,此时,可利用定时器的输入捕获功能,测量按键按下的这段高电平的时间. 宏定义方便程序升级.移植,举个例子: ...

  4. stm32f767串口下载软件_ALIENTEK 阿波罗 STM32F767 开发板资料连载十四章 输入捕获实验...

    1)实验平台:alientek 阿波罗 STM32F767 开发板2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第十四章 输入捕获实验 ...

  5. STM32输入捕获测试频率和正负脉宽

    @STM32输入捕获测试频率和正负脉宽 本博客相关程序调用转载正点原子 正点原子@ALIENTEK 广州市星翼电子科技有限公司 这次做的主要是测试频率,但系,也趁此机会捕获了高低脉宽的时间,题目所说的 ...

  6. STM32输入捕获模式设置并用DMA接收数据

    参考: STM32的PWM输入模式设置并用DMA接收数据 Input capture mode The input stage samples the corresponding TIx input ...

  7. STM32 输入捕获 测量频率 PWM占空比

    看了网上关于STM32输入捕获的资料,有几篇介绍的很不错,但是内容上还有一点问题,稍加修改,大家可以参考一下. 重要概念理解(对于理解输入捕获功能很重要,特别看了数据手册CCR1\CCR2\CCR3\ ...

  8. STM32-定时器输入捕获实验(捕获PWM方波的频率和占空比)

    STM32-定时器输入捕获实验(捕获PWM方波的频率和占空比) 一.输入捕获模式 在输入捕获模式下,当检测到ICx信号上相应的边沿后,计数器的当前值被锁存到捕获/比较寄存器(TIMx_CCRx)中.当 ...

  9. 通用定时器-输入捕获实验

    知识回顾 前置技能 : 通用定时器原理 我们将通用定时器分为四个部分:1,选择时钟2,时基电路3,输入捕获4,输出比较 本节定时器PWM输出主要涉及到定时器框图左下方部分,即输入捕获部分 输入捕获工作 ...

最新文章

  1. 特斯拉员工自曝:为应付产能不惜偷工减料,出厂测试得过且过
  2. hdu3768 spfa+全排列
  3. storm UI解释
  4. LeetCode - 3Sum Closest
  5. c#中abstract与virtual的区别
  6. python template languages_Python template.TemplateSyntaxError方法代碼示例
  7. BEC translation exercise 4
  8. chkconfig: command not found
  9. Linux-CentOS上一些快捷键的使用
  10. Tomcat和JBoss都是服务器,有什么区别呢
  11. java jstl标签库_JSTL标签库
  12. kafka sqs 与_RabbitMQ和Kafka的比较
  13. FastGitHub for Mac(GitHub下载扩展工具)
  14. java读取某一行_java 读取指定某一行的文本
  15. java 富文本 过滤xss_富文本XSS过滤
  16. dataframe两个表合并_DataFrame踩坑整理(一)
  17. 不同版本的Fiddler功能说明
  18. 单片机设计资料,仿真、程序、原理图收集好资料分享,stm32、8086、单片机方案
  19. TI官方代码中的任务状态机
  20. SAP FICO 如何看一个总账科目的修改记录?

热门文章

  1. EK1100和EK1110简介
  2. 吃鸡自定义服务器在哪买,内马尔沉迷《绝地求生大逃杀》难自拔!申请自定义服务器获官方如此回复...
  3. 16281053_杨瑷彤_操作系统第五次实验-文件系统
  4. Unhandled exception at 0x000007FEFD5C9E5D in OpenCV3.3_TestDemo.exe: Microsoft C++ exception: cv::Ex
  5. (三十一)论文阅读 | 文本检测之EAST
  6. 初中生关于计算机的科幻作文600字,关于科幻的作文初中集锦5篇
  7. Delphi2010 的Google在线翻译
  8. 根据Spring-Security安全框架搭建问答论坛系统(更新中.....)
  9. servlet:生命周期,tomcat装载,获取初始化参数
  10. 蒙牛与现代牧场就问题奶相互推诿 调查至今无果