datasheet

STM32学习笔记一一输入捕获

2019-01-09来源: eefocus 关键字:STM32  输入捕获

1.概述

输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能。 STM32 的输入捕获,简单的说就是通过检测 TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。


2.思路

高电平捕获:先设置输入捕获为上升沿检测,记录发生上升沿的时候 TIM2_CNT 的值。然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的 TIM2_CNT 值。这样,前后两次 TIM2_CNT 之差,就是高电平的脉宽,同时 TIM2 的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。


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



3.寄存器介绍

3.1 TIMx_ARR 和 TIMx_PSC

这两个寄存器用来设自动重装载值和 TIMx 的时钟分频。 

介绍—->STM32学习笔记一一定时器中断


3.2 TIMx_CCMR1

捕获/比较模式寄存器:各位描述如图:



当在输入捕获模式下使用的时候,对应图 第二行描述,从图中可以看出,TIMx_CCMR1 是针对 2 个通道的配置,低八位[7: 0]用于捕获/比较通道 1 的控制,而高八位[15: 8]则用于捕获/比较通道 2 的控制,因为 TIMx 还有 CCMR2 这个寄存器,可知道CCMR2 是用来控制通道 3 和通道 4。


实验使用TIM2 的捕获/比较通道 1,重点介绍 TIMx_CMMR1 的[7:0]位:



CC1S[1:0]:这两个位用于 CCR1 的通道方向配置, 这里我们设置 IC1S[1:0]=01,即 

是配置为输入,且 IC1 映射在 TI1 上, CC1 即对应 TIMx_CH1。


IC1PSC[1:0]:输入捕获 1 预分频器。这里是 1 次边沿就触发 1 次捕获,所以选择 00 就是了。


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


3.3 TIMx_CCER:

捕获/比较使能寄存器,此处使用到这个寄存器的最低 2 位, CC1E 和 CC1P 位。如下图:



3.4 TIMx_DIER:

DMA/中断使能寄存器。



我们同样仅关心它的第 0 位, 该位是更新中断允许位, 当定时器的更新中断, 该位要设置为 1,来允许由于更新事件所产生的中断。


3.5 TIMx_CCR1:

捕获/比较寄存器 1。该寄存器用来存储捕获发生时, TIMx_CNT的值,我们从 TIMx_CCR1 就可以读出通道 1 捕获发生时刻的 TIMx_CNT 值,通过两次捕获(一次上升沿捕获,一次下降沿捕获)的差值,就可以计算出高电平脉冲的宽度。


4. 配置步骤

4.1 开启 TIM2 时钟,配置 PA0 为下拉输入。

要使用 TIM2,我们必须先开启 TIM2 的时钟。这里我们还要配置 PA0 为下拉输入,因为 

我们要捕获 TIM2_CH1 上面的高电平脉宽,而 TIM2_CH1 是连接在 PA0 上面的。


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能 TIM2 时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟


4.2 初始化 TIM2, 设置 TIM2 的 ARR 和 PSC

在开启了 TIM2 的时钟之后,我们要设置 ARR 和 PSC 两个寄存器的值来设置输入捕获的自动重装载值和计数频率。 这在库函数中是通过 TIM_TimeBaseInit 函数实现的。


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


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

TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // TDTS = Tck_tim

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

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化 Tim2


4.3 设置 TIM2 的输入比较参数,开启输入捕获

输入比较参数的设置包括映射关系,滤波,分频以及捕获方式等。这里我们需要设置通道 1为输入模式,且 IC1 映射到 TI1(通道 1)上面,并且不使用滤波(提高响应速度)器,上升沿捕获。库函数是通过 TIM_ICInit 函数来初始化输入比较参数的:


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


参数设置结构体 TIM_ICInitTypeDef 的定义:



typedef struct

{

uint16_t TIM_Channel;

uint16_t TIM_ICPolarity;

uint16_t TIM_ICSelection;

uint16_t TIM_ICPrescaler;

uint16_t TIM_ICFilter;

} TIM_ICInitTypeDef;


参数 TIM_Channel :用来设置通道。我们设置为通道 1,为 TIM_Channel_1。


参 数 TIM_ICPolarity :是 用 来 设 置 输 入 信 号 的 有 效 捕 获 极 性 , 这 里 我 们 设 置 为 

TIM_ICPolarity_Rising,上升沿捕获。同时库函数还提供了单独设置通道 1 捕获极性的函数为:


TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling)


这表示通道 1 为上升沿捕获,同时对于其他三个通道也有一个类似的函数,使用的时候一定要分清楚使用的是哪个通道该调用哪个函数,格式为 TIM_OCxPolarityConfig()。


参数 TIM_ICSelection: 是用来设置映射关系,我们配置 IC1 直接映射在 TI1 上,选择 

TIM_ICSelection_DirectTI。


参 数 TIM_ICPrescaler: 用 来 设 置 输 入 捕 获 分 频 系 数 , 我 们 这 里 不 分 频 , 所 以 选 中TIM_ICPSC_DIV1,此外,还有 2,4,8 分频可选。


参数 TIM_ICFilter: 设置滤波器长度,这里我们不使用滤波器,所以设置为 0。


配置代码:


TIM_ICInitTypeDef TIM2_ICInitStructure;


TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端 IC1 映射到 TI1 上

TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获

TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上

TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频

TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波

TIM_ICInit(TIM2, &TIM2_ICInitStructure);


4.4 使能捕获和更新中断(设置 TIM2 的 DIER 寄存器)

因为我们要捕获的是高电平信号的脉宽,所以,第一次捕获是上升沿,第二次捕获时下降 

沿,必须在捕获上升沿之后, 设置捕获边沿为下降沿,同时,如果脉宽比较长,那么定时器就会溢出,对溢出必须做处理,否则结果就不准了。这两件事,我们都在中断里面做,所以必须 

开启捕获中断和更新中断。这里我们使用定时器的开中断函数 TIM_ITConfig 即可使能捕获和更新中断:


TIM_ITConfig( TIM2,TIM_IT_Update"TIM_IT_CC1,ENABLE);//允许更新中断和捕获中断

1

4.5 设置中断分组,编写中断服务函数

设置中断分组主要是通过函数 NVIC_Init()来完成。分组完成后,还需要在中断函数里面完成数据处理和捕获设置等关键操作,从而实现高电平脉宽统计。在中断服务函数里面,在中断开始的时候要进行中断类型判断,在中断结束的时候要清除中断标志位。使用到的函数分别为 : 

TIM_GetITStatus()函数和 TIM_ClearITPendingBit()函数。


if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){}//判断是否为更新中断

if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET){}//判断是否发生捕获事件

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update);//清除中断和捕获标志位


4.6 使能定时器(设置 TIM2 的 CR1 寄存器)

最后,必须打开定时器的计数器开关, 启动 TIM5 的计数器,开始输入捕获TIM_Cmd(TIM2,ENABLE ); //使能定时器 2通过以上 6 步设置,定时器 2 的通道 1 就可以开始输入捕获了。


5.实现代码

5.1 定时器 2 通道 1 输入捕获配置:


TIM_ICInitTypeDef TIM2_ICInitStructure;


void TIM2_Cap_Init(u16 arr,u16 psc)

{

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能 TIM2 时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0 清除之前设置

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA0 下拉


//初始化定时器 2 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_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化 TIMx 的时间基数单位


//初始化 TIM2 输入捕获参数

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

TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获

TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上

TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频

TIM2_ICIni

[1] [2]

关键字:STM32  输入捕获

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

上一篇:STM32学习笔记一一DMA传输
下一篇:最后一页

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

推荐阅读

STM32程序移植技巧总结

1. 工程更换不同的STM32芯片eg:stm32f103rct6 ---->stm32f103c8t6:1.1. 修改芯片点击魔术棒,在出来的菜单栏里,Device 选项重新选择芯片1.2. 修改启动文件此处举例是 RCT6 修改为 C8T6,因为 flash 容量大小不一样,所以需要对应修改启动文件,如果是 flash 大小相同,此步骤不需要。此处由:startup_stm32f10x_hd.s修改为startup_stm32f10x_md.s1.3. 修改全局宏定义同样先点击魔术棒,在菜单栏选择 C/C++。进而修改全局宏定义。此处:STM32F10X_HD–>STM32F10X_MD1.4. 重新添加FLASH
发表于 2019-01-09
STM32程序移植技巧总结

STM32学习笔记一一FLASH 模拟 EEPROM

1. 简述STM32 本身没有自带 EEPROM,但是 STM32 具有在应用编程(IAP:In Application Programming)功能,可以把它的 FLASH 当成 EEPROM 来使用。不同型号的 STM32,其 FLASH 容量也有所不同,最小的只有 16K 字节,最大的则达到了1024K 字节。MiniSTM32 开发板选择的 STM32F103RCT6 的 FLASH 容量为 256K 字节,属于大容量产品,闪存模块组织如下图:1.1 主存储器:该部分用来存放代码和数据常数(如 const 类型的数据)。对于大容量产品,其被划分为 256 页,每页 2K 字节。**注意:**小容量和中容量产品则每页
发表于 2019-01-09
STM32学习笔记一一FLASH 模拟 EEPROM

STM32学习笔记一一HEX文件和BIN文件格式

1. 引言今天看串口的 IAP ,平时我们通过 JTAG 等工具下载的都是 HEX 文件,都没有思考一下 HEX 的文件组成。而串口 IAP 下载的是 BIN 文件,刚好在这里区分学习一下。我们平时烧写 HEX 文件是不需要设置地址信息的,因为已经包含在文件里面,而使用 BIN 烧写,需要在程序中指定地址。2. 简述Intel hex 文件是记录文本行的 ASCII 文本文件,在 Intel HEX 文件中,每一行是一个 HEX 记录,由十六进制数组成的机器码或者数据常量。Intel HEX 文件经常被用于将程序或数据传输存储到 ROM、EPROM,大多数编程器和模拟器使用Intel HEX文件。2.1 HEX文件HEX 文件是包括
发表于 2019-01-09
STM32学习笔记一一HEX文件和BIN文件格式

STM32学习笔记一一串口 IAP

(Bootloader 程序)必须通过其它手段,如 JTAG 或 ISP 烧入;第二部分代码(APP 程序)可以使用第一部分代码 IAP 功能烧入,也可以和第一部分代码一起烧入,以后需要程序更新时再通过第一部分 IAP代码更新。他们存放在 STM32 FLASH 的不同地址范围,一般从最低地址区开始存放 Bootloader,紧跟其后的就是 APP 程序。2 .STM32程序流程2.1 STM32 正常的程序运行流程下图为 STM32 正常的程序运行流程:STM32 的内部闪存(FLASH)地址起始于 0x08000000,一般情况下,程序文件就从此地址开始写入。此外STM32是基于Cortex-M3内核的微控制器,其内部通过一张
发表于 2019-01-09
STM32学习笔记一一串口 IAP

STM32学习笔记一一待机唤醒

1. 简述1.1 低功耗模式:在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功耗模式来节省功耗,例如:等待某个外部事件时,常见的按键唤醒。用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。1.2 STM32F10X系列的低功耗模式STM32F10xxx有三种低功耗模式:–模式– –特点—睡眠模式 Cortex-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时钟(SysTick)等仍在运行停止模式 所有的时钟都已停止待机模式 1.8V电源关闭在这三种低功耗模式中,最低功耗的是待机模式,在此模式下,最低只需 2uA 左右的电流。停机模式
发表于 2019-01-09
STM32学习笔记一一待机唤醒

STM32学习笔记一一红外遥控

}2.2 中断捕获u8 RmtSta=0;u16 Dval;u32 RmtRec=0;u8 RmtCnt=0;void TIM5_IRQHandler(void){ if(TIM_GetITStatus(TIM5,TIM_IT_Update)!= RESET) { if(RmtSta&0x80)//数据接收到标志位 { RmtSta &= ~0x10;//取消上升沿捕获标记 if((RmtSta&0x0F)==0x00) RmtSta |= 1<<6; if((RmtSta&0x0F)<14) RmtSta++; else { RmtSt
发表于 2019-01-09
STM32学习笔记一一红外遥控

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,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">