定时器输入捕获是一种嵌入式开发中常用的技术,主要用于测量外部信号的时间特性,例如信号的高电平宽度、低电平宽度、周期、频率等。这种功能通常由微控制器(MCU)的定时器模块提供。
以下是有关定时器输入捕获的简介及其工作原理、配置方法、应用场景等内容:
1. 定时器输入捕获的工作原理
输入捕获的核心思想是:当外部信号的边沿(上升沿或下降沿)触发时,记录定时器的当前计数值。通过比较多个捕获事件的计数值,可以计算信号的时间特性。
- 外部信号输入:外部信号通过特定管脚连接到定时器模块的输入捕获通道。
- 边沿触发:可以设置捕获触发的类型,例如上升沿、下降沿或双边沿(上升沿和下降沿均触发)。
- 捕获计数值:当触发事件发生时,定时器会将当前计数值保存到捕获寄存器中。
- 计算时间:通过捕获的计数值差值和定时器的时钟频率,可以计算出信号的时间特性。
2. 输入捕获的配置步骤
以常见的 STM32 微控制器为例,以下是输入捕获功能的基本配置步骤:
1. 配置定时器时钟
定时器需要一个时钟源,通常由主时钟(例如 HSI、HSE)分频后提供。需要根据捕获的信号特性,选择适当的定时器时钟频率。
2. 配置输入捕获通道
在定时器的输入捕获模块中,选择要使用的通道。例如,TIMx_CH1 表示定时器 x 的通道 1。
3. 设置触发边沿
根据需求选择触发类型:
- 上升沿捕获
- 下降沿捕获
- 双边沿捕获
4. 启用中断或 DMA(可选)
当发生捕获事件时,可以选择通过中断或 DMA 的方式读取捕获寄存器的值。
5. 计算时间
读取捕获的定时器计数值,将计数值差转化为时间。计算公式为: [ \text{时间} = \frac{\text{捕获值差}}{\text{定时器频率}} ]
3. 输入捕获的应用场景
输入捕获功能有着广泛的应用场景,包括但不限于以下内容:
测量信号频率
- 通过捕获连续两个上升沿(或下降沿)的时间差,可以计算信号的周期,从而得到频率。 [ \text{频率} = \frac{1}{\text{周期}} ]
测量信号占空比
- 捕获信号的高电平时间和周期,计算占空比: [ \text{占空比} = \frac{\text{高电平时间}}{\text{周期}} ]
编码器信号处理
- 捕获旋转编码器的脉冲信号,用于测量电机的速度和位置。
超声波测距
- 利用超声波信号的发射和接收时间差,计算距离。
红外信号解码
- 捕获红外遥控信号的脉冲时间,解码出按键值。
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. 注意事项
- 定时器溢出问题:当输入信号的周期较长,超过定时器的计数范围时,需要处理定时器重载(溢出)问题。
- 分辨率与时钟频率:定时器频率越高,捕获的时间精度越高,但测量周期范围会变小。
- 噪声干扰:外部信号可能包含噪声,需要硬件滤波或软件去抖动处理。
总结来说,定时器输入捕获是非常强大和常用的功能,可以帮助开发者高效地测量信号的时间特性。通过合理的配置和计算,可以满足多种嵌入式应用的需求。