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);
}
### STM32 TIM 定时器输入捕获使用方法 对于STM32微控制器中的TIM定时器,其输入捕获功能可以用来精确测量信号的时间特性,比如脉冲宽度或周期。为了实现这一目标,需要配置特定的寄存器来设定捕捉条件以及处理方式。 #### 初始化配置 在开始之前,需先完成基本的外设初始化工作,这通常涉及到RCC(重置和时钟控制)模块以确保所使用的定时器能够获得合适的时钟源。接着是对GPIO端口进行设置以便它们能作为外部信号进入路径的一部分[^1]。 #### 设置输入捕获参数 当准备就绪后,下一步就是定义具体的输入捕获属性: - **通道选择**:指定哪一个通道将被用于接收待测信号; - **极性选择**:决定是在上升沿还是下降沿发生时触发捕获动作; - **预分频系数**:通过`TIM_ICPrescaler`选项调整内部计数频率相对于APB总线的速度比例关系;例如可以选择每遇到一个事件(`TIM_ICPSC_DIV1`)、两个连续事件(`TIM_ICPSC_DIV2`)等才更新一次捕获值[^3]。 #### 启动与停止操作 一旦所有必要的参数都已正确配置完毕,则可以通过调用相应的API函数使能该定时器并开启实际的数据采集过程。值得注意的是,在某些应用场景下可能还需要额外考虑同步机制或其他高级特性如DMA传输的支持[^4]。 下面给出一段简单的C语言代码片段展示如何利用标准固件库来进行上述提到的各项设置: ```c #include "stm32f1xx_hal.h" // 假定已经完成了系统级和其他硬件资源的相关初始化... void setup_TIM_InputCapture(void){ __HAL_RCC_TIM2_CLK_ENABLE(); // 开启TIM2时钟 GPIO_InitTypeDef GPIO_InitStruct = {0}; /* 配置PA0为TIM2 CH1 */ __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA,&GPIO_InitStruct); TIM_HandleTypeDef htim2; htim2.Instance = TIM2; htim2.Init.Prescaler = 79; // APB1=8MHz,所以这里除以80得到100KHz采样率 htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; // ARR最大值防止溢出 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim2) != HAL_OK){ Error_Handler(); } TIM_OC_InitTypeDef sConfigIC={0}; sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;// 上升沿触发 sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; // TI1FP1映射至CH1 sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; // 不做分频 sConfigIC.ICFilter = 0x0F; // 数字滤波器长度为15个时钟周期 if(HAL_TIM_IC_ConfigChannel(&htim2,&sConfigIC,TIM_CHANNEL_1)!=HAL_OK){ Error_Handler(); } } ``` 这段程序展示了针对STM32系列MCU中TIM2定时器的一个典型输入捕获场景下的初始化流程。其中包含了对外部中断引脚(PA0)的功能切换、定时器本身的工作模式选定及其各个子项的具体数值赋予等内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

FightingLod

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

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

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

打赏作者

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

抵扣说明:

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

余额充值