• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

stm32定时器实现捕获脉宽的方法

利用定时器测量脉冲宽度有两种方法。

  方法1:

  在捕获中断函数里改变捕获信号的触发沿(上升沿触发改为下降沿触发,或者下降沿触发改为上升沿触发),通过两次触发得到的计数器的差值,来计算出脉冲宽度。这种

  方法需要定时器的配置方法是一样的,不同的地方在中断函数里修改触发沿,以TIM2, 捕获通道2为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
if(CapState == 0)
        {
             
            /* First time capture */
            Val1         = TIM_GetCapture2(TIM2);
            CapState     = 1;
             
            /* Change the trigger */
            TIM2->CCER         |=    1UL << 5;
        }
 
        else if(CapState == 1)
        {
            /* Second time capture */
            Val2 = TIM_GetCapture2(TIM2);
             
            /* Change the trigger */
            TIM2->CCER         &=    ~(1UL << 5);
 
            /* Capture computation */
            if (Val2 > Val1)
            {
                CapVal = Val2 - Val1;
            }
            else
            {
                CapVal = ((0xFFFF - Val1) + Val2);
            }
 
        CapState = 0;
     }

  当然,在第一次捕获的时候将计数器清零,然后第二次捕获直接读取捕获值也是一个不错的选择,如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
if(CapState == 0)
        {
             
            /* First time capture */
           TIM_GetCapture2(TIM2);
           CapState     = 1;
             
            /* Change the trigger */
            TIM2->CCER         |=    1UL << 5;
 
            /* Clear CNT */
            TIM_SetCounter(TIM2, 0);
        }
 
        else if(CapState == 1)
        {
            /* Second time capture */
            CapVal = TIM_GetCapture2(TIM2);
             
            /* Change the trigger */
            TIM2->CCER         &=    ~(1UL << 5);
 
 
        CapState = 0;
     }

触发沿的配置在CCER这个寄存器里面,这里直接对寄存器进行操作,具体请查阅STM32F10x的参考说明书。

 

  方法2:

  利用定时器的PWM输入模式(PWM input mode)。所谓的PWM模式,其实就是利通了定时器捕获单元映射功能,定时器捕获单元1(IC1)和捕获单元2(IC2)可以映射

  到同一个捕获通道,一个捕获单元配置成捕获上升沿信号,另一个捕获单元配置成捕获下降沿信号,那么两个捕获值的差就是脉冲宽度的值。还是以TIM2, 捕获通道2

  为例,配置代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void CaptureConfig(void)
{
    TIM_ICInitTypeDef  TIM_ICInitStructure;
     
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter    = 0x0;
    TIM_ICInitStructure.TIM_Channel     = TIM_Channel_1;
    TIM_ICInitStructure.TIM_ICPolarity  = TIM_ICPolarity_Rising;
    TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
     
    /* TIM enable counter */
    TIM_Cmd(TIM2, ENABLE);
 
    /* Enable the CC1, CC2 Interrupt Request */
    TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_CC1, ENABLE);
}

各行代码的意思:

    L2:  指定捕获单元的映射方式,TIM_ICSelection_IndirectTI 说明捕获单元1(IC1)和捕获单元2(IC2)映射到捕获通道2(TI2,这里是指捕获通道2,区别

        定时器TIM2),假如该值为TIM_ICSelection_DirectTI,则捕获单元1(IC1)和捕获单元2(IC2)映射到捕获通道1(TI1)。

    L8, L9:  指定捕获单元触发的信号沿(上升沿还是下降沿)。TIM_Channel_1对应捕获单元1(IC1),TIM_Channel_2对应捕获单元2(IC2)注意这里

          只需要指定一个捕获单元,另一个捕获单元将会在调用初始化函数TIM_PWMICConfig时设定为相反的边沿。

    L16:  允许捕获单元1和捕获单元2的中断。

  这样,当捕获通道2(TI2)检测到上升沿时,捕获单元1(IC1)将会记录下计数器的值,同时捕获单元1的中断标志位(CC1IF)将置位;

  当捕获通道2(TI2)检测到下降沿时,捕获单元2(IC2)将会记录下计数器的值,同时捕获单元2的中断中断标志位(CC2F)将置位。

  中断处理函数示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
if(TIM_GetITStatus(DEMOD_CAPTURE_TIM, TIM_IT_CC1) == SET)
    {
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
        TIM_GetCapture1(TIM2);
        TIM_SetCounter(TIM2, 0);
                
    }   
    else if(TIM_GetITStatus(DEMOD_CAPTURE_TIM, TIM_IT_CC2) == SET)
    {
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
        CapVal = TIM_GetCapture2(TIM2);
    }
}

总结:  

      STM32F10x系列的定时器是一个很灵活的东西,想灵活应用它首先要理解它的原理和运作的过程。定时器的捕获单元和捕获通道是比较容易混淆的两个东西

    简单来说,STM32F10x的每个通用定时器有4个捕获通道(TI1, TI2, TI3, TI4, 对应4个GPIO口),每个捕获通道对应一个捕获单元,即IC1, IC2, IC3, IC4,

    其中捕获单元1和捕获单元2可以映射到同一个捕获通道,TI1或者TI2。

全部回复(3)
正序查看
倒序查看
2020-10-28 10:27
0
回复
jsapin
LV.5
3
2020-10-28 21:18
@电源网-fqd
[图片]
学习
0
回复
2022-03-10 16:18

大概了解上述小点后,这里说明我们本次测试使用到的PWM输入模式,它是最便捷的测量脉宽和频率的方法。当使用PWM 输入模式的时候,因为一个输入通道

    (TIx)会占用两个捕获通道(ICx),所以一个定时器在使用PWM输入的时候最多只能使用两个输入通道(TIx)。本次试验就是使用TIM1的CH1 和CH2。

    工作原理是这样的:

      PWM 信号由输入通道TI1 进入,因为是PWM 输入模式的缘故,信号会被分为两路,一路是TI1FP1,另外一路是TI2FP2。其中一路是周期,另一路是占空比,

    具体哪一路信号对应周期还是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是周期,另一路就是对应占空比。作为触发

    输入的那一路信号还需要设置极性,是上升沿还是下降沿捕获,一旦设置好触发输入的极性,另外一路硬件就会自动配置为相反的极性捕获,无需软件配置。一句

    话概括就是:选定输入通道,确定触发信号,然后设置触发信号的极性即可,因为是PWM 输入的缘故,另一路信号则由硬件配置,无需软件配置。

      当使用PWM 输入模式的时候必须将从模式控制器配置为复位模式(配置寄存器SMCR 的位SMS[2:0]来实现),即当我们启动触发信号开始进行捕获的时候,

0
回复