Skip to content

定时器输入捕获是一种嵌入式开发中常用的技术,主要用于测量外部信号的时间特性,例如信号的高电平宽度、低电平宽度、周期、频率等。这种功能通常由微控制器(MCU)的定时器模块提供。

以下是有关定时器输入捕获的简介及其工作原理、配置方法、应用场景等内容:


1. 定时器输入捕获的工作原理

输入捕获的核心思想是:当外部信号的边沿(上升沿或下降沿)触发时,记录定时器的当前计数值。通过比较多个捕获事件的计数值,可以计算信号的时间特性。

  1. 外部信号输入:外部信号通过特定管脚连接到定时器模块的输入捕获通道。
  2. 边沿触发:可以设置捕获触发的类型,例如上升沿、下降沿或双边沿(上升沿和下降沿均触发)。
  3. 捕获计数值:当触发事件发生时,定时器会将当前计数值保存到捕获寄存器中。
  4. 计算时间:通过捕获的计数值差值和定时器的时钟频率,可以计算出信号的时间特性。

2. 输入捕获的配置步骤

以常见的 STM32 微控制器为例,以下是输入捕获功能的基本配置步骤:

1. 配置定时器时钟

定时器需要一个时钟源,通常由主时钟(例如 HSI、HSE)分频后提供。需要根据捕获的信号特性,选择适当的定时器时钟频率。

2. 配置输入捕获通道

在定时器的输入捕获模块中,选择要使用的通道。例如,TIMx_CH1 表示定时器 x 的通道 1。

3. 设置触发边沿

根据需求选择触发类型:

  • 上升沿捕获
  • 下降沿捕获
  • 双边沿捕获

4. 启用中断或 DMA(可选)

当发生捕获事件时,可以选择通过中断或 DMA 的方式读取捕获寄存器的值。

5. 计算时间

读取捕获的定时器计数值,将计数值差转化为时间。计算公式为: [ \text{时间} = \frac{\text{捕获值差}}{\text{定时器频率}} ]


3. 输入捕获的应用场景

输入捕获功能有着广泛的应用场景,包括但不限于以下内容:

  1. 测量信号频率

    • 通过捕获连续两个上升沿(或下降沿)的时间差,可以计算信号的周期,从而得到频率。 [ \text{频率} = \frac{1}{\text{周期}} ]
  2. 测量信号占空比

    • 捕获信号的高电平时间和周期,计算占空比: [ \text{占空比} = \frac{\text{高电平时间}}{\text{周期}} ]
  3. 编码器信号处理

    • 捕获旋转编码器的脉冲信号,用于测量电机的速度和位置。
  4. 超声波测距

    • 利用超声波信号的发射和接收时间差,计算距离。
  5. 红外信号解码

    • 捕获红外遥控信号的脉冲时间,解码出按键值。

4. 输入捕获的实际代码示例

下面是一个基于 STM32 的简单输入捕获代码示例,测量信号的周期和频率:

c
#include "stm32f4xx_hal.h"

TIM_HandleTypeDef htim2;
uint32_t captured_value1 = 0; // 第一次捕获值
uint32_t captured_value2 = 0; // 第二次捕获值
uint32_t difference = 0;     // 捕获值差值
uint8_t is_captured = 0;     // 捕获标志
float frequency = 0.0;       // 计算的频率

// 定时器中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM2 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
    {
        if (is_captured == 0)
        {
            // 第一次捕获
            captured_value1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
            is_captured = 1;
        }
        else if (is_captured == 1)
        {
            // 第二次捕获
            captured_value2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
            if (captured_value2 > captured_value1)
            {
                difference = captured_value2 - captured_value1;
            }
            else
            {
                difference = (htim->Instance->ARR - captured_value1) + captured_value2;
            }

            // 计算频率
            float timer_clock = 84000000; // 假设定时器时钟频率为 84 MHz
            frequency = timer_clock / difference;
            is_captured = 0; // 重置捕获标志
        }
    }
}

// 主函数
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_TIM2_Init();

    HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // 开启输入捕获中断

    while (1)
    {
        // 主循环
    }
}

5. 注意事项

  1. 定时器溢出问题:当输入信号的周期较长,超过定时器的计数范围时,需要处理定时器重载(溢出)问题。
  2. 分辨率与时钟频率:定时器频率越高,捕获的时间精度越高,但测量周期范围会变小。
  3. 噪声干扰:外部信号可能包含噪声,需要硬件滤波或软件去抖动处理。

总结来说,定时器输入捕获是非常强大和常用的功能,可以帮助开发者高效地测量信号的时间特性。通过合理的配置和计算,可以满足多种嵌入式应用的需求。