電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 29|回復(fù): 0
收起左側(cè)

STM32實(shí)現(xiàn)等精度測(cè)頻

[復(fù)制鏈接]

454

主題

454

帖子

2398

積分

三級(jí)會(huì)員

Rank: 3Rank: 3

積分
2398
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2020-3-17 23:21:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
上一章介紹了利用STM32的TIM的捕獲功能實(shí)現(xiàn)頻率測(cè)量的方法,但測(cè)量誤差受被測(cè)信號(hào)頻率的影響,不適合測(cè)量頻率變化較大的 。本章將介紹等精度測(cè)頻的方法以及STM32的實(shí)現(xiàn)。

  •     STM32硬件電路板及仿真器(以STM32F072C8單片機(jī)為例)
  •     Keil v5以上版本(MDK-ARM)

    基本原理
    首先看一張圖:

    傳統(tǒng)的測(cè)頻方式,閘門(mén)放時(shí)間是固定的,閘門(mén)時(shí)間內(nèi)被測(cè)信號(hào)的計(jì)數(shù)個(gè)數(shù)Nx不一定是整數(shù)個(gè),因此會(huì)有一定的誤差,且誤差與被測(cè)信號(hào)頻率有關(guān)。而等精度測(cè)頻的方法,閘門(mén)時(shí)間不是固定的,而是被測(cè)信號(hào)的整數(shù)倍。 因此消除了對(duì)被測(cè)信號(hào)計(jì)數(shù)的±1誤差,其誤差只與標(biāo)準(zhǔn)信號(hào)的計(jì)數(shù)個(gè)數(shù)Ns的±1誤差有關(guān)?梢钥闯觯l門(mén)時(shí)間越長(zhǎng),標(biāo)準(zhǔn)頻率Fs越大,Ns的計(jì)數(shù)值越大,±1誤差的影響就小。在相同的閘門(mén)時(shí)間內(nèi),被測(cè)信號(hào)的頻率Fx=Nx*Fs/Ns。

    STM32的實(shí)現(xiàn)
    實(shí)現(xiàn)等精度測(cè)頻用到兩個(gè)定時(shí)器,其中一個(gè)定時(shí)器用于產(chǎn)生閘門(mén)時(shí)間,另外一個(gè)用于捕獲被測(cè)信號(hào)和標(biāo)準(zhǔn)信號(hào)計(jì)數(shù)。
    實(shí)現(xiàn)步驟:
    TIM1設(shè)置約1秒的閘門(mén)時(shí)間。TIM3捕獲到被測(cè)信號(hào)上升沿后,將TIM1計(jì)數(shù)器清零。閘門(mén)時(shí)間開(kāi)始,TIM3開(kāi)始捕獲計(jì)數(shù)同時(shí)本身計(jì)數(shù)器也開(kāi)始計(jì)數(shù)。閘門(mén)時(shí)間到后,標(biāo)志置位。TIM3檢測(cè)到標(biāo)志置位且捕獲到上升沿后,記錄當(dāng)前捕獲計(jì)數(shù)的值Nx和本身計(jì)數(shù)器的計(jì)數(shù)值Ns。計(jì)算被測(cè)信號(hào)頻率Fx=Nx*Fs/Ns,其中Fs為定時(shí)器時(shí)鐘頻率48MHz。[/ol]
    STM32CubeMX的TIM配置如下:

    TIM1作為產(chǎn)生閘門(mén)時(shí)間的定時(shí)器,其計(jì)數(shù)周期設(shè)置為47999,時(shí)鐘為系統(tǒng)時(shí)鐘,1000分頻。則溢出周期即閘門(mén)時(shí)間為1秒,打開(kāi)溢出中斷:

    TIM3作為捕獲被測(cè)信號(hào)的定時(shí)器,其配置如下,通道1設(shè)置為捕獲模式,捕獲上升沿,定時(shí)周期設(shè)置為最大65535,時(shí)鐘為系統(tǒng)時(shí)鐘,不分頻。打開(kāi)中斷(TIM3捕獲和溢出為同一個(gè)中斷)。




    程序?qū)崿F(xiàn):
    按照之前介紹的步驟設(shè)置其它外設(shè),并生成代碼。初始化后,啟動(dòng)TIM1和TIM3中斷。
  •   HAL_TIM_Base_Start_IT(&htim1);  HAL_TIM_Base_Start_IT(&htim3);  HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);編寫(xiě)中斷回調(diào)函數(shù)。
  • #define Fs 48000000L  //定時(shí)器時(shí)鐘頻率uint32_t TIM3_Cnt_Value[2];//定時(shí)器3捕獲值uint32_t TIM3_Over_Cnt=0;//定時(shí)器3溢出次數(shù)uint32_t TIM1_Over_Flag=0;//定時(shí)器1溢出標(biāo)志uint32_t Ns,Nx;//標(biāo)志信號(hào)計(jì)數(shù)值  被測(cè)信號(hào)計(jì)數(shù)值double Fx;//被測(cè)頻率
    //定時(shí)器溢出中斷 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
      if(htim->Instance == TIM1)  {    TIM1_Over_Flag = 1;  }  if(htim->Instance == TIM3)  {    TIM3_Over_Cnt++;    if(TIM3_Over_Cnt==0xffffffff)TIM3_Over_Cnt=0xfffffffe;  }
    }
    //定時(shí)器捕獲中斷void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){  if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)  {    if(TIM1_Over_Flag == 0)    {      __HAL_TIM_SET_COUNTER(&htim1,0);//TIM1清零 開(kāi)始閘門(mén)時(shí)間      TIM3_Cnt_Value[0] = __HAL_TIM_GET_COUNTER(&htim3);      Nx++;    }    else if(TIM1_Over_Flag == 1)//閘門(mén)時(shí)間到    {      Nx++;      TIM3_Cnt_Value[1] = __HAL_TIM_GET_COUNTER(&htim3);      Ns = (TIM3_Over_Cnt16) + TIM3_Cnt_Value[1] - TIM3_Cnt_Value[0];//計(jì)算標(biāo)準(zhǔn)信號(hào)的計(jì)數(shù)值      TIM1_Over_Flag = 2;//一次測(cè)量完成 標(biāo)志置位    }  }}//計(jì)算被測(cè)頻率void CalcFx(void){  if(TIM1_Over_Flag == 2)  {    Fx = (double)Nx * Fs / Ns;//計(jì)算頻率    Nx=0; //計(jì)數(shù)清零    TIM1_Over_Flag = 0;//標(biāo)志清零,可以開(kāi)始下一次測(cè)量  }}
    在主函數(shù)中調(diào)用CalcFx()函數(shù)即可獲取被測(cè)信號(hào)的頻率。
    以上即為利用STM32定時(shí)器實(shí)現(xiàn)等精度測(cè)頻的全部?jī)?nèi)容,STM32定時(shí)器的功能還有很多,如觸發(fā)ADC采樣、編碼器模式等。不再一一做介紹,下一章開(kāi)始介紹STM32串口的使用方法,敬請(qǐng)期待。
  • 發(fā)表回復(fù)

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表