打印
[应用相关]

理解STM32定时器中的输入捕获滤波器

[复制链接]
18177|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 wangkaichao2 于 2012-5-13 17:23 编辑

关于STM32定时器中的输入捕获滤波器的功能描述,在中文参考手册中描述如下:

我不理解官方的说明,在网上搜了老半天,基本都是下面这几句话:
1)当滤波器连续采样到N次个有效电平时,认为一次有效的输入电平。
2)该数字滤波器实际上是个事件计数器,它记录到N个事件后会产生一个输出的跳变。
例如:当f(CK_INT) = 72MHz, CKD[1:0] = 01时,选择f(DTS) = f(CK_INT)/2 = 36MHz;
而ETF[3:0] = 0100,则采样频率f(SAMPLING) = f(DTS) / 2 = 18MHz, N = 6,此时高于3MHz的信号
将被这个滤波器滤除,这样就有效地屏蔽了高于3MHz的干扰。

看了这些说法,我还是不理解这个数字滤波器到底是如何工作的,问题如下:
问题1:当滤波器连续采样到N次个有效电平时,是输出这个电平?还是输出一个跳变?
问题2:当滤波器没有连续采样到N次个有效电平时,输出是的什么?

带着这两个问题,我们来分析一下,下面以TIM3为例:
首先可以肯定输入捕获过程如下:详细信息见参考手册中的14.2节,通用定时器框图
TIM3_CH1(PA.6) ----> TI1(外部信号) ------->  输入滤波器IC1F[3:0] ----->  IC1(滤波器输出信号) -------> 输入捕获预分频器IC1PSC[1:0] ----> 捕获/比较1寄存器CCR1
从上面的过程可以知道,
1)发生输入捕获所需要的跳变沿是由滤波器输出产生的。
2)滤波器和预分频器可软件编程,如果IC1F[3:0] = 0x0,则滤波器全通,即TI1 和 IC1是同一个信号。

借助这两点分析,我假设的滤波器的工作原理是:
问题1猜测答案:当滤波器连续采样到N次个有效电平时,就输出这个有效电平。
问题2猜测答案:当滤波器没有连续采样到N次个有效电平时,再从0开始计数,输出一直保持上一次输出的有效电平。例如:滤波器上一次输出是高电平,本次连续采样到N-1个高低平,但第N是个低电平,那么滤波器仍然保持上次输出的高电平,并重新开始计数,记录1次低电平,如果在其后采样的N-1个也是低电平,此时滤波才输出低电平,于是一个下降沿才出现在IC1上。

举例:如果我们产生一个f = 1MHz的占空比为50%的方波信号,滤波器的采样频率f(SAMPLING) = 18MHz,那么如果滤波器要想监测的1MHz信号,并且滤除高频干扰,则理论上 N <= 9 ,
即 f(SAMPLING) / N  >= 2 * f,这让我想起了《信号与系统》中的“奈圭斯特采样频率”。
如下图所示:

从上图中我们可以看到,对于1MHz的信号,当采样频率为18MHz时,N最大为9。当N大于9时,是不可能连续采样到大于10个的有效电平的。

下面我们验证这个猜测:
按照这个猜想,我们先求一下这个数字低通滤波器的最小通带截止频率。
令 CKD[1:0] = 01b, 即f(DTS) = f(CK_INT) / 4 = 18MHz;
    IC1F[3:0] = 1111b, 即f(SAMPLING) = f(DTS) / 32 = 562.5KHz,   N = 8;
由公式 f(SAMPLING) / N  >= 2 * f 可得: f <= 35.156KHz,
也就是说理论上:滤波器可以监测到输入信号频率小于35.156KHz,占空比为50%的方波信号的跳变沿,换句话说,大于35.156KHz的此类信号将被滤除掉。
下面是STM32定时器输出频率的计算公式:f(OC1) = 72,000,000 / (ARR - 1)*(PSC - 1);
50%的PWM波不同频率的计算值如下表:
_______________________________________________________________________
  f Hz           |         ARR        |        PSC      |       理论上                 |      实际上
40K             |      1800 - 1     |         0        |       监测不到跳变沿      |      监测不到跳变沿
36K             |      2000 - 1     |         0        |       监测不到跳变沿      |      监测到跳变沿
35.156K       |      2048 - 1     |         0        |       临界值                 |      监测到跳变沿
35K             |      2057 - 1     |         0        |       可检测到跳变沿      |      监测到跳变沿
_______________________________________________________________________

下面是源代码:
配置TIM3的通道1(PA.6)输出不同频率的占空比50%的方波,配置TIM3的通道2(PA.7)为输入捕获模式,并使能捕获中断,在中断中输出捕获的值,将PA.6和PA.7短接。
在测试时请注意修改:宏定义ARR的常量值。
==========================================================

void RCC_Configure(void)
{
        /* 开启辅助时钟 */        
        /* 使能GPIOA,Pin8 50MHz 推免输出 LED0*/
        /* 使能GPIOD,Pin2 50MHz 推免输出 LED1*/
        /* 使能GPIOA.9 GPIOA.10串口时钟 */
        /* GPIOA_Pin_0~3 for ADC1_Channel_10~13 */
        /* GPIOC_Pin_6~10 and GPIOB.all for TFT_LCD */
        RCC->APB2ENR  |= RCC_APB2Periph_GPIOA;

        /* 复位USART1,再结束复位 */
        RCC->APB2RSTR |= RCC_APB2Periph_USART1;
        RCC->APB2RSTR &= ~RCC_APB2Periph_USART1;
        RCC->APB2ENR  |= RCC_APB2Periph_USART1;        

        /* TIM3 */
        RCC->APB1ENR  |= RCC_APB1Periph_TIM3;
        RCC->APB1RSTR |= RCC_APB1Periph_TIM3;
        RCC->APB1RSTR &= ~RCC_APB1Periph_TIM3;

        }


void GPIO_Configure(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 设置USART1复用端口----------------------------------------------------- */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;    /* TXD */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;    /* RXD */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void NVIC_Configure(void)
{
    NVIC_InitTypeDef NVIC_InitStruct;
   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    /* TIM3_CC_IRQHandler  */
    NVIC_InitStruct.NVIC_IRQChannel =TIM3_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);
}

#define ARR                     //1800, 2000, 2048, 2057

void Tim_Configure( void )
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef        TIM_OCInitStructure;
    TIM_ICInitTypeDef        TIM_ICInitStucture;
   
    /*  TIM3 Configration */
    /* Time Base configuration f =  */
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = ARR - 1;   //ARR = 1800, 2000, 2048, 2057
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV4;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
   
    /* Channel 1 Configuration in PWM mode */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = ARR / 2;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);

    TIM_ICInitStucture.TIM_Channel = TIM_Channel_2;
    TIM_ICInitStucture.TIM_ICFilter = 0x0F;
    TIM_ICInitStucture.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStucture.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStucture.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInit(TIM3, &TIM_ICInitStucture);

    TIM3->CR1  |= TIM_CR1_CEN;
    TIM3->DIER |= TIM_IT_CC2;        
}

void TIM3_IRQHandler ( void )
{
    if (TIM3->DIER & TIM_IT_CC2)
    {
        TIM3->SR = (uint16_t)~TIM_IT_CC2;
        printf("%d\r\n", TIM3->CCR2);     
    }
}

void main (void)
{
        //初始化RCC
        //初始化NVIC
        //初始化GPIO
        //初始化USART
        //初始化TIM
        while(1){}
}
================================================================================
在串口输出的数据中,我们捕获的数值不等于 ARR / 2, 这是因为输入捕获发生在上升沿,这个上升沿来自滤波器的输出,而滤波器在第一次监测
到由高到低的电平后,还要再连续确认N = 8次,才最终输出低电平,这很显然滤波器输出给捕获器预分频的上升沿要比原始信号延时了,那么这个
延时到底有多大哪?
在上面我们计算数字滤波器的最小通带截止频率 f 时,3个公式中的所有分母依次是:4, 32, N,
已知N = 8,则最大延迟为: 4 * 32 * N = 1024,所以我们捕获到的值 < ARR / 2  + 1024
沙发
gaochy1126| | 2012-5-13 20:09 | 只看该作者
我以为里面内部嵌入的滤波算法呢……

使用特权

评论回复
板凳
probug| | 2012-5-14 11:37 | 只看该作者
板凳

使用特权

评论回复
地板
hw5226349| | 2012-5-20 22:23 | 只看该作者
没懂

使用特权

评论回复
5
630511630511| | 2012-5-23 21:09 | 只看该作者
额  能不能用库函数的方式讲一下历程。。

使用特权

评论回复
6
LAORUAN| | 2012-7-19 15:58 | 只看该作者
讲得很好,谢谢了。

使用特权

评论回复
7
xzhui00| | 2013-1-5 10:17 | 只看该作者
谢谢,学习了

使用特权

评论回复
8
gonghaixu| | 2013-7-15 11:15 | 只看该作者
有深度的帖子 还想请问 我要做过零检测的抗干扰 用捕获滤波器 效果好吗

使用特权

评论回复
9
justloveu| | 2013-8-27 20:09 | 只看该作者
讲得让我总算明白一些了 官方手册也是看不懂这个CKD

使用特权

评论回复
10
cyfcgj| | 2013-10-28 15:19 | 只看该作者
这里有用到采样定理吗,18兆采样频率,N=6,滤波的截止频率为3兆,这明显和采样定理冲突,采样定理的作用是,采样频率>=输入波形最高频率的两倍,采样后的离散信号可以还原原输入波形。stm32捕获输入波形的电压都是相同的,可以把这种波形当成离散的了。所以楼主想多了,采样定理在这里不适用。stm32的滤波的截止频率就是至于这个CKD的两位,个人理解基本没什么用,就是配合后面CCMR寄存器或者SMCR寄存器计算采样频率的。手册上的原话为:这些位定义了对ETRP信号采样的频率和对ETRP数字滤波的带宽。实际上,数字滤波器是一个事件计数器,它记录到N个事件后会产生一个输出的跳变。

使用特权

评论回复
评论
hlcewdwe 2022-7-6 17:51 回复TA
但是为什么定时器频率配为输入捕获滤波截止频率的一半及以下才能捕获到数值呢 按理说定时器频率大于等于输入捕获滤波频率才捕获不到 
11
jackzmh| | 2014-3-20 17:32 | 只看该作者
不错,解释的很清楚

使用特权

评论回复
12
tianhaolan| | 2014-12-9 10:45 | 只看该作者
mark

使用特权

评论回复
13
1342785168| | 2015-3-10 13:33 | 只看该作者
牛X,彻底懂了~

使用特权

评论回复
14
foxglove| | 2015-3-10 15:43 | 只看该作者
STM32定时器中的输入捕获滤波器

使用特权

评论回复
15
张仁良| | 2015-3-12 23:35 | 只看该作者
楼主我这是这样理解的,数字滤波器检测电平信号,N=8,检测八次输出一次有效电平,那么那个预分频器是怎么回事啊。一个,两个,三个,四个事件进行一次捕获怎么理解啊。

使用特权

评论回复
16
奋斗青槐| | 2015-5-6 22:40 | 只看该作者
手册上有这句话请注意:
       根据输入信号的特点,配置输入滤波器为所需的带宽(即输入为TIx时,输入滤波器控制位是TIMx_CCMRx寄存器中的ICxF位)。假设输入信号在最多5个内部时钟周期的时间内抖动,我们须配置滤波器的带宽长于5个时钟周期。因此我们可以(以f DTS频率)连续采样8次,以确认在TI1上一次真实的边沿变换,即在TIMx_CCMR1寄存器中写入IC1F=0011。
也就是在配置的滤波器的带宽内无论尖峰有多少个,只要连续采样8次就记录一次真是的边沿变换

使用特权

评论回复
17
yinhaix| | 2015-5-7 14:10 | 只看该作者
没太明白,朦胧

使用特权

评论回复
18
碧螺春_123| | 2017-8-25 16:12 | 只看该作者
写的很好,感谢分享。

使用特权

评论回复
19
山东电子小菜鸟| | 2017-8-25 20:49 | 只看该作者
感谢分享

使用特权

评论回复
20
xhuaihe| | 2017-9-7 15:17 | 只看该作者
学习了,最近在看PWM输入捕获

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

1

帖子

1

粉丝