void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM2){
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){
cap1=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
cap1_2=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);
TIM2->CNT=0;//清零
R40_frq=80000000/80/cap1;
R40_duty=(1.0*cap1_2)/(1.0*cap1)*100;
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
}
}
if(htim->Instance==TIM3){
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){
cap2=HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1);
cap2_2=HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_2);
TIM2->CNT=0;//清零
R39_frq=80000000/80/cap2;
R39_duty=(1.0*cap2_2)/(1.0*cap2)*100;
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);
}
}
}
在输入捕获模式下,计数器 CNT
并不会只在检测到上升沿时才开始计时。计数器是 持续运行 的,无论是否发生捕获事件,计数器都会根据定时器的时钟频率不断累加,直到溢出或手动清零。
1. 计数器 CNT
的工作方式
-
计数器是持续运行的:
-
定时器的计数器
CNT
会一直累加,直到达到自动重装载寄存器ARR
的值,然后溢出并重新从 0 开始。 -
计数器的运行不受捕获事件的影响,捕获事件只会将当前的
CNT
值保存到捕获寄存器(如CCR1
或CCR2
)中。
-
-
捕获事件的作用:
-
当输入信号的边沿(上升沿或下降沿)触发捕获事件时,当前的
CNT
值会被保存到对应的捕获寄存器中。 -
捕获事件不会停止或重置计数器,计数器仍然会继续运行。
-
2. 代码中的逻辑
在你的代码中:
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { cap1 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1); // 读取上升沿的捕获值 cap1_2 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2); // 读取下降沿的捕获值 TIM2->CNT = 0; // 清零计数器 }
-
cap1
:保存了上升沿触发时CNT
的值。 -
cap1_2
:保存了下降沿触发时CNT
的值。 -
TIM2->CNT = 0
:在捕获到上升沿后,手动将计数器清零。
3. 为什么需要手动清零计数器?
虽然计数器是持续运行的,但在输入捕获模式下,手动清零计数器有以下几个原因:
3.1 确保周期测量的准确性
-
在输入捕获模式下,通常通过两次上升沿之间的时间差来计算信号的周期。
-
如果在每次捕获后不清零计数器,
CNT
会继续累加,可能导致计数器溢出(超过ARR
的值),从而影响周期计算的准确性。 -
清零计数器后,计数器从 0 开始重新计数,确保每次测量的周期都是基于一个已知的起点。
3.2 简化计算
-
清零计数器后,捕获寄存器(
CCR1
或CCR2
)的值直接表示从 0 开始到捕获事件发生的时间。 -
这样计算周期和占空比时,公式更加简单直观:
-
周期:
cap1
(上升沿的捕获值)。 -
占空比:
(cap1_2 / cap1) * 100
(高电平时间与周期的比值)。
-
清零计数器的情况
第一次捕获:
上升沿:CNT = 1000,cap1 = 1000。
清零计数器:CNT = 0。
下降沿:CNT = 300,cap1_2 = 300。
第二次捕获:
上升沿:CNT = 1000,cap1 = 1000。
清零计数器:CNT = 0。
下降沿:CNT = 300,cap1_2 = 300。
结果:
周期计算正确(cap1 = 1000)。
占空比计算正确((300 / 1000) * 100 = 30%)
3.3 避免计数器溢出
-
如果不清零计数器,
CNT
可能会超过ARR
的值,导致计数器溢出,从而影响测量结果。
总结
-
计数器
CNT
是持续运行的,不会因为捕获事件而停止或重置。 -
手动清零计数器 的目的是确保每次测量的周期和占空比基于一个已知的起点,避免计数器溢出和累积误差。
-
清零计数器后,捕获寄存器的值直接表示从 0 开始到捕获事件发生的时间,简化了周期和占空比的计算。
因此,在输入捕获模式下,手动清零计数器是一个重要的操作,能够确保测量结果的准确性和可靠性