定时器捕获的"事件"本质上是一个硬件级别的中断信号。当定时器的计数器达到特定条件(如溢出、匹配比较值等)时,硬件会自动触发中断机制,这个瞬间的触发动作就是我们所说的"捕获事件"。就像百米赛跑中发令枪响的瞬间,运动员(CPU)会立即对枪声(中断信号)做出反应。
现代微控制器中,定时器单元通常包含多个独立的捕获/比较通道。以STM32的TIMx定时器为例,每个通道都有专用的输入引脚和寄存器组。当配置为捕获模式时,引脚上的电平跳变会触发以下硬件级操作:
关键细节:捕获事件的时间精度取决于定时器时钟源。72MHz主频下,基本定时器理论上能达到约13.89ns的分辨率(1/72MHz)。
通过捕获两个相邻上升沿的时间差,可以精确计算PWM信号频率。具体实现需要:
c复制// STM32 HAL库示例代码片段
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); // 启动输入捕获中断
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
static uint32_t first_value = 0;
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
if(is_first_capture == 0) {
first_value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);
} else {
uint32_t diff = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) - first_value;
float frequency = SystemCoreClock / (float)(diff * htim3.Init.Prescaler);
}
}
}
正交编码器模式下,定时器会自动根据A/B相脉冲的边沿变化增减计数器。捕获事件在这里表现为:
| 时钟类型 | 适用场景 | 典型精度 |
|---|---|---|
| 内部RC振荡器 | 低功耗模式 | ±1% ~ ±5% |
| 外部晶体振荡器 | 高精度测量 | ±10 ~ ±50ppm |
| 锁相环(PLL) | 需要灵活分频的系统 | 同参考源精度 |
数字滤波器能有效消除毛刺,但会引入延迟。以STM32为例:
经验值:对于10kHz信号,建议N=6;100kHz以上信号建议N≤2
c复制__HAL_AFIO_REMAP_TIM3_PARTIAL(); // 必要时要重映射
c复制__HAL_RCC_TIM3_CLK_ENABLE();
某些高端定时器支持多个通道的联动捕获:
对于超长周期信号,可以结合捕获中断和溢出中断:
c复制volatile uint32_t overflow_count = 0;
void TIM3_IRQHandler(void) {
if(__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE)) {
overflow_count++;
__HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);
}
// 捕获中断处理...
}
// 最终周期计算:
total_ticks = (overflow_count * ARR) + captured_value;
定时器捕获功能就像电子系统的"感官神经",能否准确捕捉这些"事件"直接决定了系统对外部信号的响应能力。经过多个项目的实战验证,我发现捕获精度的优化往往需要硬件和软件的协同设计——从PCB布局的电磁兼容到固件中的中断优先级管理,每个环节都可能成为影响最终性能的关键因素。