STM32F4如何进行PWM输入捕获高频信号,大约2MHz?

3
我想测量PWM信号的频率。为此,我正在使用STM-F401RE及其Timer_Input_Capture函数。
问题在于:
输入信号具有相当高的频率(约2MHz),而STM-F401RE控制器仅具有80MHz时钟。
因此,当使用中断例程计算输入信号上升沿数量时,它会错过许多上升沿(取决于输入信号的频率)。当使用示波器并切换I/O引脚时,我发现只有当频率低于400kHz时才能捕获所有上升沿。
问题是:如何解决这个问题?或者是否有另一种方法来测量高频率的输入pwm信号?
谢谢

如果您的硬件中有一个计数器,请在固定间隔内监视其计数。 - linuxfan says Reinstate Monica
2个回答

7

您需要将定时器设置为PWM输入,而不是捕获输入(例如TIM1可以实现此功能)。这样,将使用两个通道(但您只有一个物理连接)。基本上,第一个通道将提供给您周期,而第二个通道将提供给您脉冲。计数器会自动重置。

初始化函数如下:

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
}


0

您可以计算您的中断代码所需的周期,并添加中断延迟的额外周期(10-20个?)。然后,您就可以看到您的最大捕获频率是多少。我敢打赌它会接近400Khz。

我认为在80Mhz下运行的STM-F401RE无法完成这项任务。


嗨,在我的中断例程中只有一个变量被递增。void HAL_TIM_IC_CaptureCallback( *htim) { edgeCounter++; }我认为这不需要太多的周期。我让程序运行约100毫秒,然后根据edgeCounter的数量计算频率。它能够感知到2.9MHz的频率,但总是存在大约5kHz的不确定性。 从代码中我看到,检测到的边缘数目有很大的变化。 - BL_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接