TIM定时器输入捕获

TIM定时器输入捕获

1. 输入捕获

输入捕获是STM32定时器的一项重要功能,它允许微控制器捕捉外部信号的变化(通常是边沿变化),并将当前计数器的值锁定到捕获/比较寄存器中。这项功能非常有用,可以用来测量外部信号的周期、频率、脉宽等参数。

1. 输入捕获的工作原理

  1. 配置捕获通道

    • 选择定时器的某个捕获/比较通道作为输入捕获通道。
    • 配置该通道的触发条件,如上升沿、下降沿或双边沿触发。
  2. 检测外部信号

    • 当输入信号的电平发生变化(如上升沿或下降沿)时,定时器会捕获当前计数器的值。
    • 这个值随后被锁存到对应的捕获/比较寄存器(TIMx_CCRx)中。
  3. 读取捕获值

    • 用户可以通过读取TIMx_CCRx寄存器来获取捕获到的值。
    • 根据计数器的频率和预分频器的设置,可以计算出信号的周期或频率。

2. 输入捕获的应用场景

  • 测量信号周期:通过捕获连续两次上升沿的时间差来计算信号周期。
  • 测量信号频率:根据信号周期计算信号频率。
  • 测量脉冲宽度:测量单个脉冲的持续时间。
  • 测量占空比:测量高电平相对于整个周期的比例。

2.输入捕获配置流程

这段代码配置了STM32的通用定时器TIM3以进行输入捕获,并提供了两个函数来计算输入信号的频率和占空比。下面是详细的配置流程解释:

  1. 启用时钟:

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    

    这两行代码分别启用了TIM3定时器和GPIOA端口的时钟。

  2. 配置GPIO引脚:

    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);
    

    这里配置了GPIOA.6引脚为上拉输入模式。

  3. 配置TIM3内部时钟:

    TIM_InternalClockConfig(TIM3);
    

    这一行配置TIM3使用内部时钟源。

  4. 配置TIM3基本定时器设置:

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		// ARR
    TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;		// PSC
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
    

    这里设置了TIM3的基本定时器特性:

    • TIM_ClockDivision: 设置时钟分割因子为1,即不分频。
    • TIM_CounterMode: 设置向上计数模式。
    • TIM_Period: 设置自动装载寄存器值为65535,意味着每65536个计数周期后会重新加载。
    • TIM_Prescaler: 设置预分频器值为71,意味着实际的预分频器值为72。假设APB1时钟频率为72MHz,则预分频后的频率为1MHz。
    • TIM_RepetitionCounter: 设置重复计数器为0,不使用重复计数功能。
  5. 配置TIM3输入捕获通道:

    TIM_ICInitTypeDef TIM_ICInitStructure;
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
    TIM_ICInitStructure.TIM_ICFilter = 0xF;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
    

    这里配置了TIM3的输入捕获通道1 (CH1):

    • TIM_Channel_1: 选择通道1。
    • TIM_ICFilter: 设置滤波器为16个采样点。
    • TIM_ICPolarity: 设置触发极性为上升沿。
    • TIM_ICPrescaler: 设置输入捕获分频器为1,即不分频。
    • TIM_ICSelection: 选择直接TI模式。
    • TIM_PWMIConfig:传入其中一个通道,将另外一个通道配置为该通道的相反模式。
  6. 选择输入触发源:

    TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
    TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
    

    这两行代码配置了TIM3的输入触发源为TI1FP1,并选择了重置模式作为从模式。这意味着每当捕获到TI1FP1的上升沿时,定时器将被重置。

  7. 使能TIM3:

    TIM_Cmd(TIM3, ENABLE);
    

    最后,使能TIM3定时器。

测量频率和占空比的函数

  1. 测量频率:

    uint32_t IC_GetFreq(void)
    {
        return 1000000 / (TIM_GetCapture1(TIM3) + 1);
    }
    

    这个函数通过读取TIM3的捕获1寄存器的值来计算输入信号的频率。

  2. 测量占空比:

    uint32_t IC_GetDuty(void)
    {
        return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);
    }
    

    这个函数通过读取TIM3的捕获2寄存器的值来计算输入信号的占空比。

完整代码:

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	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);
	
	TIM_InternalClockConfig(TIM3);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);

	TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	TIM_Cmd(TIM3, ENABLE);
}

uint32_t IC_GetFreq(void)
{
	return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}

uint32_t IC_GetDuty(void)
{
	return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FightingLod

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值