2016-12-21 67 views
1

我想测量一个PWM信号的频率。为此,我使用STM-F401RE及其Timer_Input_Capture功能。stm32F4 pwm输入捕捉高频信号约。 2MHz的?

的问题是:

  • 输入信号具有相当高的频率(大约为2MHz。)和,
  • 的STM-F401RE控制器只有一个80MHz的时钟

因此,当使用中断程序对输入信号的上升沿进行计数,它会丢失许多上升沿(取决于输入信号的频率)。当使用示波器并切换I/O引脚时,我发现当频率低于400kHz时,它只能捕获所有的上升沿。

问题是:如何克服这个问题?还是有另一种方法来测量高频输入PWM信号?

感谢

+0

如果您的硬件中有计数器,请按固定间隔监视其计数。 – linuxfan

回答

4

你需要设置你的计时器作为PWM输入,而不是捕捉输入(TIM1例如可以做到这一点)。这样,使用2个通道(但只有一个物理连接)。基本上,第一个频道会给你的时间,第二个频道会给你的脉搏。计数器会自动重置。

初始化函数:

void tim_init() 
{ 
    TIM_SlaveConfigTypeDef sSlaveConfig; 
    TIM_IC_InitTypeDef sConfigIC; 
    TIM_MasterConfigTypeDef sMasterConfig; 

    htim1.Instance = TIM1; 
    htim1.Init.Prescaler = 0; 
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP; 
    htim1.Init.Period = 65535; 
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 
    htim1.Init.RepetitionCounter = 0; 
    HAL_TIM_IC_Init(&htim1); 

    sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; 
    sSlaveConfig.InputTrigger = TIM_TS_TI2FP2; 
    sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING; 
    sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; 
    sSlaveConfig.TriggerFilter = 0; 
    HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig); 

    sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; 
    sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; 
    sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; 
    sConfigIC.ICFilter = 0; 
    HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1); 

    sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; 
    sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; 
    HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2); 

    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; 
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 
    HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig); 

    //Enable interrupt 
    HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2); 
    HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1); 
} 

和中断处理程序

void tim_irq() 
{ 
    period = HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_2); 
    pulse = HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_1); 

    //First irq to be ignored 
} 
1

就可以计算出你的代码需要在你的中断循环,并添加额外周期的中断延迟(10-20 ?)。然后你可以看到你的最大捕捉频率是多少。我敢打赌它将接近400Khz。

我认为在80Mhz下运行的STM-F401RE无法做到这一点。

+0

嗨,在我的中断,只有一个变量递增。 'void HAL_TIM_IC_CaptureCallback(* htim) { edgeCounter ++; }' 我不认为这样做需要太多的周期。我让程序运行大约100ms,然后根据'edgeCounter'的数量来计算频率。它能够感应2.9MHz的频率,但总是存在5kHz左右的不确定性。正如我从代码中看到的,检测到的边的数量有很大的变化。 – bienle