打印
[STM32F1]

stm32f103VE timer3捕获比较被毛刺干扰,求高人指点。

[复制链接]
3819|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zengcamel|  楼主 | 2014-6-4 21:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我使用了timer3的通道2来捕获外部的脉冲信号。
main()函数中的程序如下:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;    //GPIO??
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

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

  /* TIM enable counter */
  TIM_Cmd(TIM3, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);

  while (1);



中断程序如下:

void TIM3_IRQHandler(void)
{
  unsigned int Port;
       
  if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET)
  {
    /* Clear TIM3 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
    if(CaptureNumber == 0)
    {
      /* Get the Input Capture value */
      IC3ReadValue1 = TIM_GetCapture2(TIM3);
      CaptureNumber = 1;
    }
    else if(CaptureNumber == 1)
    {
      /* Get the Input Capture value */
      IC3ReadValue2 = TIM_GetCapture2(TIM3);

      /* Capture computation */
      if (IC3ReadValue2 > IC3ReadValue1)
      {
        Capture = (IC3ReadValue2 - IC3ReadValue1);
      }
      else
      {
        Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2);
      }
      /* Frequency computation */
      TIM3Freq = (uint32_t) SystemCoreClock / Capture;
      CaptureNumber = 0;
    }
  }
      //翻转PC.10口,作为示波器的调试观测引脚。
      //
      Port = GPIOC->IDR & GPIO_Pin_10;
      if (Port)
      {
        GPIOC->BRR = GPIO_Pin_10;
      } else {
                               
        GPIOC->BSRR = GPIO_Pin_10;
      }
}

硬件连接:
1.将信号源连接PA.07脚,信号源输出1KHz的方波。
2.示波器一个探头接PA.07,另一个接PC.10,观测捕获比较中断的执行情况,得到波形请看附件。

IMG_20140604_172958.rar (880.63 KB)







沙发
zengcamel|  楼主 | 2014-6-4 21:21 | 只看该作者
PA.07设置为上升沿捕获,图中白色线为外部输入信号,红色线为PC.07翻转调试脚,从图中可以看出,在外部信号正常的上升沿没有产生中断,PC.07脚没有翻转,而是在外部信号的毛刺处触发了中断,IO脚翻转了,不知道为什么没有在正常的上升沿触发中断,请高手帮忙分析下。谢谢!

使用特权

评论回复
板凳
mmuuss586| | 2014-6-5 08:19 | 只看该作者
用STM32的输入捕获滤波功能试试

使用特权

评论回复
地板
zengcamel|  楼主 | 2014-6-5 09:19 | 只看该作者
版主,我试过滤波功能了,没法滤除毛刺,只能滤除比设置频率高的方波,比我说我设置滤波频率为200K,则当信号源的输入频率为100K时,就没有中断产生了,只有小于200K的方波信号才能触发中断。

使用特权

评论回复
5
zengcamel|  楼主 | 2014-6-5 09:22 | 只看该作者
而且我感觉很奇怪的是,正常的上升沿没有触发中断,反而在毛刺处产生了中断,怎么会这样,版主这是啥原因啊

使用特权

评论回复
6
zengcamel|  楼主 | 2014-6-5 10:03 | 只看该作者
是不是程序哪个地方设置的不对啊

使用特权

评论回复
7
icecut| | 2014-6-5 10:17 | 只看该作者
不是毛刺...毛刺是高频的信号.发示波器毛刺截图

使用特权

评论回复
8
zengcamel|  楼主 | 2014-6-5 10:26 | 只看该作者
file:///e:/PROGRA~1/360se6/USERDA~1/Temp/IMG_20~1.JPGfile:///e:/PROGRA~1/360se6/USERDA~1/Temp/IMG_20~1.JPG不知道怎么直接粘贴图片,我只好发附件了,请版主查看。
IMG_20140604_172958.rar (880.63 KB)


使用特权

评论回复
9
zengcamel|  楼主 | 2014-6-5 10:30 | 只看该作者
刚刚用stm32f103VE的开发板又做了一遍试验,信号源频率从50调到500KHz,发现信号源的上升沿和IO翻转的边沿一直相差1.6us左右,我突然想到,是不是捕获触发中断存在1.6us左右的硬件延时,请版主确认,谢谢。

使用特权

评论回复
10
中断处理程序执行了不少指令,你的pc.10一进中断,就翻转再看看呢~

使用特权

评论回复
11
玄德| | 2014-6-5 11:21 | 只看该作者
zengcamel 发表于 2014-6-5 10:26
不知道怎么直接粘贴图片,我只好发附件了,请版主查看。

左起第三个工具图标
或者用“高级模式”


使用特权

评论回复
12
zengcamel|  楼主 | 2014-6-5 11:25 | 只看该作者
把中断函数改成了这样:
void TIM3_IRQHandler(void)
{
        unsigned int Port;       

        //debug code
        //
        Port = GPIOC->IDR & GPIO_Pin_10;
        if (Port)
        {
                GPIOC->BRR = GPIO_Pin_10;
        } else {
                               
                GPIOC->BSRR = GPIO_Pin_10;
        }                       
       
         if ((TIM3->SR & TIM_IT_CC2) == TIM_IT_CC2)
        {
                TIM3->SR = ~TIM_IT_CC2;
       
         }
}

IO脚会误翻转,改成这样就好点:
void TIM3_IRQHandler(void)
{
        unsigned int Port;                               
       
         if ((TIM3->SR & TIM_IT_CC2) == TIM_IT_CC2)
        {
                TIM3->SR = ~TIM_IT_CC2;
       
         }

        //debug code
        //
        Port = GPIOC->IDR & GPIO_Pin_10;
        if (Port)
        {
                GPIOC->BRR = GPIO_Pin_10;
        } else {
                               
                GPIOC->BSRR = GPIO_Pin_10;
        }
}
这时的中断延时有1us左右。


使用特权

评论回复
13
zengcamel|  楼主 | 2014-6-5 11:31 | 只看该作者
望继续解答

使用特权

评论回复
14
看bus-matrix,定时器和gpio在不同的总线上(apb1,apb2),是不是由于这个造成的1us呢。。。

使用特权

评论回复
15
zengcamel|  楼主 | 2014-6-5 12:15 | 只看该作者
是不是芯片本身就存在硬件延时啊,还是我程序的问题,或是外面信号的问题?

使用特权

评论回复
16
ljhtj| | 2014-6-5 14:02 | 只看该作者
中断存在延时应该到不了us,你的晶体多大频率

使用特权

评论回复
17
zengcamel|  楼主 | 2014-6-5 14:22 | 只看该作者
有900多ns延时,接近1us了,晶振72M的。

使用特权

评论回复
18
gxliu08| | 2014-6-5 19:45 | 只看该作者
想做大牛的小马 发表于 2014-6-5 12:06
看bus-matrix,定时器和gpio在不同的总线上(apb1,apb2),是不是由于这个造成的1us呢。。。 ...

bus-matrix,不同的总线上(apb1,apb2)上的延迟没有us级

使用特权

评论回复
19
zengcamel|  楼主 | 2014-6-6 09:48 | 只看该作者
gxliu08 发表于 2014-6-5 19:45
bus-matrix,不同的总线上(apb1,apb2)上的延迟没有us级

那我这1us左右的中断延迟是正常的吗,请帮忙解答下

使用特权

评论回复
20
xiaostm| | 2015-5-10 15:08 | 只看该作者
本帖最后由 xiaostm 于 2015-5-10 15:10 编辑

恩,最近我也在写这个程序,的确是干扰很严重,示波器观察出来的波形和你的差不多。后来不得已手动滤波,设置了波动的上下限,看论坛上有个思路不错,使用内部的函数捕获PWM的频率和周期,频率值可以拿来用,楼主,可以参考下,也可以交流下后来是怎么处理的。
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;                                                                                                                        //|TIM_ICPolarity_Falling
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;                                                                                                                                                                                                                                                        
  TIM_ICInitStructure.TIM_ICFilter =0x03;
  TIM_ICInit(TIM3,&TIM_ICInitStructure);
  
        TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);                                                                                                                                                         
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);                                                                                                                                          
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);                                                                                                                                   
  TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);                                                                                                                                                   
  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);                        
不过这样占用了两个通道                                                                                                                                                        
        貌似这个是官方给的例子,挺给力的

使用特权

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

本版积分规则

1

主题

14

帖子

1

粉丝