CH32单定时器捕获多个通道PWM频率与占空比方法
定时器捕获单个通道
- 在第一次捕获到上升沿的时候,记录下当前的计数值TIM2_IC2_ReadValue1,然后将触发变为下降沿触发。
-
紧接着捕获到了下降沿的时候,此刻的时间和上一次的时间之差应该为TIM2_IC2_ReadValue2 = TIM2_IC2_OverCnt * 65535 + TIM_GetCapture2(TIM2) - TIM2_IC2_ReadValue1(TIM2_IC2_OverCnt 就是溢出的次数,TIM2_IC2_ReadValue1是在第一次捕获到上升沿的时刻的计数值)。这一段时间就是一个周期中高电平所占的时间。然后将触发的方式又更换为上降沿。
- 此时,第二次捕获到上升沿,就是已经是一个完整的周期了,然后我们就可以得到一个周期的时间是TIM2_IC2_ReadValue1 = TIM2_IC2_OverCnt * 65535 + TIM_GetCapture2(TIM2) - TIM2_IC2_ReadValue1;
到此,一个周期中高电平所占的时间和一个周期的所有时间都知道了,那么方波的频率和占空比也就出来了。
并且可以注意到,在这个程序中,我们没有对计数值进行改变,那么每个通道直接读取当前捕获到的计数值即可,所以就不会产生通道之间的相互干扰的问题了。
- 程序
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
TIM2_IC2_OverCnt++;
}
if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
{
/* Clear TIM2 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
if(TIM2_IC2_CaptureNumber == 0)
{
/* Get the Input Capture value */
TIM2_IC2_ReadValue1 = TIM_GetCapture2(TIM2);
TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Falling);
TIM2_IC2_CaptureNumber = 1;
TIM2_IC2_OverCnt = 0;
}
else if(TIM2_IC2_CaptureNumber == 1)
{
/* Get the Input Capture value */
TIM2_IC2_ReadValue2 = TIM2_IC2_OverCnt * 65535 + TIM_GetCapture2(TIM2) - TIM2_IC2_ReadValue1;
TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);
TIM2_IC2_CaptureNumber = 2;
}
else if(TIM2_IC2_CaptureNumber == 2)
{
/* Get the Input Capture value */
TIM2_IC2_ReadValue1 = TIM2_IC2_OverCnt * 65535 + TIM_GetCapture2(TIM2) - TIM2_IC2_ReadValue1;
TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);
TIM2_IC2_Freq = (uint32_t) (SystemCoreClock * 1.0 / TIM2_IC2_ReadValue1 + 0.5);
TIM2_IC2_Duty = (float)TIM2_IC2_ReadValue2 * 1.0 / TIM2_IC2_ReadValue1;
TIM2_IC2_CaptureNumber = 0;
}
}
}
定时器捕获多个通道
有了上面的例子,就可以依次捕获其他通道。//增加通道1与通道3的捕获计算。
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
TIM2_IC2_OverCnt++;
TIM2_IC3_OverCnt++;
}
if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
{
/* Clear TIM2 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
if(TIM2_IC2_CaptureNumber == 0)
{
/* Get the Input Capture value */
TIM2_IC2_ReadValue1 = TIM_GetCapture2(TIM2);
TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Falling);
TIM2_IC2_CaptureNumber = 1;
TIM2_IC2_OverCnt = 0;
}
else if(TIM2_IC2_CaptureNumber == 1)
{
/* Get the Input Capture value */
TIM2_IC2_ReadValue2 = TIM2_IC2_OverCnt * 65535 + TIM_GetCapture2(TIM2) - TIM2_IC2_ReadValue1;
TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);
TIM2_IC2_CaptureNumber = 2;
}
else if(TIM2_IC2_CaptureNumber == 2)
{
/* Get the Input Capture value */
TIM2_IC2_ReadValue1 = TIM2_IC2_OverCnt * 65535 + TIM_GetCapture2(TIM2) - TIM2_IC2_ReadValue1;
TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);
TIM2_IC2_Freq = (uint32_t) (SystemCoreClock * 1.0 / TIM2_IC2_ReadValue1 + 0.5);
TIM2_IC2_Duty = (float)TIM2_IC2_ReadValue2 * 1.0 / TIM2_IC2_ReadValue1;
TIM2_IC2_CaptureNumber = 0;
}
}
else if(TIM_GetITStatus(TIM2, TIM_IT_CC3) == SET)
{
/* Clear TIM2 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
if(TIM2_IC3_CaptureNumber == 0)
{
/* Get the Input Capture value */
TIM2_IC3_ReadValue1 = TIM_GetCapture3(TIM2);
TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Falling);
TIM2_IC3_CaptureNumber = 1;
TIM2_IC3_OverCnt = 0;
}
else if(TIM2_IC3_CaptureNumber == 1)
{
/* Get the Input Capture value */
TIM2_IC3_ReadValue2 = TIM2_IC3_OverCnt * 65535 + TIM_GetCapture3(TIM2) - TIM2_IC3_ReadValue1;
TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising);
TIM2_IC3_CaptureNumber = 2;
}
else if(TIM2_IC3_CaptureNumber == 2)
{
/* Get the Input Capture value */
TIM2_IC3_ReadValue1 = TIM2_IC3_OverCnt * 65535 + TIM_GetCapture3(TIM2) - TIM2_IC3_ReadValue1;
TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising);
TIM2_IC3_Freq = (uint32_t) (SystemCoreClock * 1.0 / TIM2_IC3_ReadValue1 + 0.5);
TIM2_IC3_Duty = (float)TIM2_IC3_ReadValue2 * 1.0 / TIM2_IC3_ReadValue1;
TIM2_IC3_CaptureNumber = 0;
}
}
}