2016-12-21 66 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