stm32学习总结:定时器(2)通用定时器之输入捕获(IC)

一、 相关概念

通用定时器在输入捕获(Input Capture, IC)模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,常被用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。每个高级定时器和通用定时器都拥有4个输入捕获通道,并且可配置为PWMI模式,用来同时测量频率和占空比。可配合主从触发模式,实现硬件全自动测量。下图为输入捕获内部结构图,共有4个通道,由输入、滤波及CCR共同组成。
在这里插入图片描述

二、 结构及原理

如下图所示为STM32通用定时器的输入捕获部分的结构图,该图以通道1为例。
在这里插入图片描述

其中输入信号是TI1,来自外部待测信号,fDTS为采样时钟源,ICF[3:0]用来控制滤波器参数,其采样原理类似于按键去抖,以一定频率在某段时间对输入信号进行采样,若被采样点均为同一类型信号时,对该时间段信号进行平滑处理后输出为TI1F,如下图所示,滤波后的信号进入边沿检测器,使用CC1P进行极性选择,选择触发后续动作的边沿(上升沿或下降沿),该信号输出至分频器和从模式控制器,使用从模式控制器可以实现CNT的自动重置,是使用测周法测量频率的基础,分频器可控制每N个事件触发一次捕捉,捕捉后可以触发中断,从而完成一些附加功能,最后IC1PS输出,使得当前计数值CNT转运到CCR,完成一次输入捕捉。
在这里插入图片描述

三、 测频方法

常见的测频方法有两种,分别是测频法和测周法。

  1. 测频法
    设定一个较长的闸门时间,对闸门时间T内的有效边沿(如上升沿)进行采样,计算上升沿个数N,则被测频率为单位时间内上升沿个数,即f=N/T。该方法常被用于高频信号测量,测量原理如图。
    在这里插入图片描述

  2. 测周法
    当被测频率较低时,通常使用测周法,即设定一个标准频率fc,从一个上升沿开始计数,到下一个上升沿停止计数,得到计数值N,被测频率就等于标准频率的N分频,即f=fc/N,测量原理如图。
    在这里插入图片描述

四、 主从触发模式

主从触发模式是一个合成概念,其中包含了是主模式,从模式和触发源选择这三个功能,其中主模式就是定时器通道作为信号源,可以将定时器的内部信号,映射到TRGO引脚,用于触发别的外设;从模式就是接收其他外设或者自身外设的一些信号,用于控制自身定时器的运行,也就是被别的信号控制;触发源选择,就是对选择从模式的触发信号源,可以认为是从模式的一部分,选择指定的一个信号作为触发源TRGI,TRGI去触发从模式,从模式可以在列表里面选择一项来自动执行。
在测周法中,我们需要在下一个有效沿到来时将计数器重置,而触发模式中刚好包含了在触发后初始化计数器的功能(Reset),在将CNT转运至CCR后将CNT清零。主从触发模式所含内容如图所示。
在这里插入图片描述

五、 代码分析

本文使用文章stm32学习总结:定时器(2)通用定时器之输出比较(OC)及PWM-CSDN博客中的PWM部分作为待测信号源,使用TIM3进行频率检测。

  1. IC.c
#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
    //第一个老朋友,外设时钟使能
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    //第二个老朋友,设置外设接口,Pin6复用上拉输入,输入待测信号;Pin5推挽输出,当检测到输入信号频率在指定范围内时给出动作
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    TIM_InternalClockConfig(TIM3);//TIM3参数表
    
    //配置时基单元
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//定义在定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;       //ARR,防止溢出将寄存器值拉满
    TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;       //PSC,输出频率= 72MHz / (72 * 10)= 100KHz,即标准频率
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);//初始化TIM3
    
    TIM_ICInitTypeDef TIM_ICInitStructure;
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//选用TIM3的通道1
    TIM_ICInitStructure.TIM_ICFilter = 0xF;//用于选择输入捕获的滤波器,一般地值越大滤波效果越好
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//边沿检测极性选择
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//此处不分频,不分频就是每次触发都有效,2分频就是每两次上升沿有效一次,以此类推
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//此处选择直连通道,配置数据选择器,可以选择直连通道或者交叉通道
    TIM_ICInit(TIM3, &TIM_ICInitStructure);
    
    TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);//配置触发模式TRGI的触发源为TI1FP1
    TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);//配置从模式为Reset,给计数器清零,以便重新计数
    
    TIM_Cmd(TIM3, ENABLE);
}

uint32_t IC_GetFreq(void)
{
    //fc=72/(PSC + 1)= 1MHZ
    //执行公式fx = fc / N
    //输出比较模式下,CCR是只写的,要用setCompare写入
    //输入捕获模式下,CCR是只读的,要用GetCapture读出
    return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}
  1. Main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "PWM.h"
#include "IC.h"

#define TEST_FREQ 100000//被测频率期望值

char flag = 0;//频率检测标志位

int main(void)
{
    GPIO_init();
    PWM_Init();
    IC_Init();  
    while (1)
    {
        if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 1)
        {
            TIM_Cmd(TIM2, ENABLE);
            PWM_SetCompare1(5);
        }
        else TIM_Cmd(TIM2, DISABLE);
        if(IC_GetFreq() <= (TEST_FREQ * 1.05) && IC_GetFreq() >= (TEST_FREQ * 0.95)) //当被测信号频率在该范围内时,标志位置1
        {
            flag = 1;           
        }
        if(flag == 1)//标志位为1时,输出高电平
        {
            GPIO_SetBits(GPIOA, GPIO_Pin_5);
        }
        else GPIO_ResetBits(GPIOA, GPIO_Pin_5);
    }
}

六、 总结

本文主要围绕通用定时器的输入捕获功能进行了介绍,探讨了其结构及测频原理,使用PWM进行输入,并对其进行检测,围绕代码对该功能的使用做出了说明。

参考链接

  1. 嵌入式学习之通用定时器输入捕获和库函数小总结_tim_dmaconfig-CSDN博客
  2. 笔记 13:STM32F4的输入捕获_stm32tim4输入捕获-CSDN博客
  3. 定时器—输入捕获-CSDN博客
  4. 【嵌入式学习-STM32F103-TIM-输入捕获】-CSDN博客
  5. stm32通用定时器的输入捕获_stm32定时器输入捕获-CSDN博客
  6. STM32通用定时器TIMx_stm32定时器互联同步电路-CSDN博客
  7. STM32——输入捕获_stm32输入捕获-CSDN博客
  8. 【STM32】标准库 TIM输入捕获_tim_icfilter-CSDN博客
  9. 【STM32】输入捕获实验原理_定时器输入捕获原理-CSDN博客
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值