|
使用mcu對脈沖頻率進行測量有多種方法,最基本的是定時長脈沖計數法和周期測量法。其中定時長計數法適合高頻脈沖測量,其測量能力和精度由Mcu的端口速度和系統時鐘限定。周期測量法適合低頻端脈沖測量。這兩種方式在中間頻率上都存在明顯的誤差。
本例程給出了一種基于stc32g12k128的頻率測量方法。采用系統時鐘11059200HZ時適合頻率是200HZ——900KHZ。根據需要可以向高端或低端擴展,是一種簡單的寬頻率范圍的測量程序。
本例程在提高測量精度方面是從三個角度著手。一是兩端對齊,就像用尺子測量棍子時所做的,把棍子兩端與尺子的刻度對齊,方能測量準確。在測量時把脈沖信號與時鐘信號正確對齊,來提高測量精度。二是采用雙精度時鐘,這與游標卡尺的原理相似,一個大刻度尺子粗測,一個小刻度尺子用來精測。三是增加測量時間長度。取較長的時間測量,可以使誤差相對去減小。
例程中使用PWMA的ccp1通道的外時鐘模式一對脈沖信號進行計數,信號輸入在P1.0口,定時器T0做主時間定時,使用12T模式,初值為0,以獲得更多測量時長。定時器T1進行精測計時,采用1T模式,以提高測量精度。利用PWMA的上升沿中斷來啟動和結束計數和計時,獲得好的對齊效果。
在需要向高頻端擴展時,可以提高系統時鐘頻率(如改為33177600)和對被測信號進行分頻(當前未開分頻,可以分頻值為2—8分頻),把測量頻率的上限擴展到20M以上,這時的限制在于mcu端口本身的速度。需要向低頻端擴展時,可以把T1定時器改為12T模式,測量頻率下限則為15HZ。
擴展時還需要修改程序內的兩個計算常數。如果想同時向兩個方向擴展,則需要修改程序流程,增加頻段選擇的相關操作。
如果想進一步提高測量精度,則需要采用外置高精度高穩定度晶振。并對程序中影響測量精度的語句進行補償(給T1定時器設一個初值)。相信該例程本身能夠滿足專業測量頻率的需要。
下面給出例程主體,包括主程序和配置程序。未列出的程序包括顯示屏的驅動程序和各種頭文件。在附件中有完整程序供初學者參考和使用。
附圖中顯示屏上的第二行為被測頻率的計數值,第三行為兩個定時器的計數值之和。被測頻率的計數值會出現正負一個數的變動,定時器測量值也會隨之變動,但測結果不受影響。
單片機源程序如下:
#include "STC32G.H"
#include "stc32_12864driver.h"
#include "mcu_initial.h"
#include "initial_lcd.h"
#include "chinese_zhouqi.h"
unsigned long int cnt1=10,cnt2,cnt3;//cnt1的初值是為指示程序是否進入測量狀態。cnt2,cnt3是調試時用到的參數
bit first=0;//程序走向控制參數,初值不影響測量結果
void main(void)
{
mcu_initial();
initial_lcd();
clear_screen();
transfer_chine_word(1,0,pin);
transfer_chine_word(1,16,lu);
PWMA_SR1=0;//中斷標志位清零
PWMA_CR1|=0x01; //使能計數器
PWMA_IER=0x02;//開捕獲中斷,用于捕獲第一次中斷
while (1)
{
digit6_display(1,32,(cnt1*(1105920000/(cnt3+1)))/100);//輸出頻率
digit6_display(3,32,cnt1);//顯示精確捕獲計數
digit6_display(5,32,cnt3);//顯示總計時器值,該值以1T的精度顯示超過12T的定時計數值
}
}
void t0_isr() interrupt 1 //定時
{
TR1=1;
TR0=0;
PWMA_SR1=0;//中斷標志位清零
PWMA_IER=0x02;//開捕獲中斷,用于捕獲第二次中斷
}
void PWMA_isr() interrupt 26//用來啟動和停止計數器,輸出測量數值
{
first=!first;
if(first)
{
TR1=0;//停定時器
cnt1=(PWMA_CCR1H<<8)+PWMA_CCR1L; //CCp1 捕獲值輸出
cnt2=(TH1<<8)+TL1;//讀計時器
/*
cnt2=TH1;
cnt2=(cnt2<<8);
cnt2=cnt2+TL1;
*/
cnt3=cnt2+(65535*12); //兩個定時器的計時值之和
//下一次測量的初始化
TL1 = 0x00; //設置定時初始值
TH1 = 0x00; //設置定時初始值
TL0 = 0x00; //設置定時初始值
TH0 = 0x00; //設置定時初始值
PWMA_EGR|=0x01;//產生一次更新事件,可用來使計數器初始化,硬件自動清零
PWMA_SR1=0;//中斷標志位清零
PWMA_IER=0x02;//開捕獲中斷,用于捕獲第一次中斷
PWMA_CR1|=0x01; //使能計數器
}
else
{
TR0=1;//開T0定時器
PWMA_SR1=0;//中斷標志位清零
PWMA_IER=0;//關捕獲中斷
}
}
#include "mcu_initial.h"
#include "STC32G.H"
void mcu_initial(void)
{
P_SW1=0x04;//選擇P2.2,2.4,2.4.2.5輸出SPI
EAXFR = 1; //使能訪問 XFR
CKCON = 0x00; //設置外部數據總線速度為最快
WTST = 0x00; //設置程序代碼等待參數,
P1M0=0x00; //P1配置為高阻,其中的P1.6為雙向。P1.0輸入被檢測脈沖
P1M1=0xbf;
P2M0=0xFF;//P2為推挽,其實雙向模式也可
P2M1=0x00;
P3M1|=0x04;
P3M0&=0xfb;//把P3.2設置為高阻端,用于外部模式二輸入被測信號,本程序中沒用到
AUXR &= 0x7F; //定時器0時鐘12T模式
TMOD &= 0xF0; //設置定時器模式
TL0 = 0; //設置定時初始值
TH0 = 0; //設置定時初始值4ms,11M
TF0 = 0; //清除TF0標志
AUXR |= 0x40; //定時器1時鐘1T模式
TMOD &= 0x0F; //設置定時器T1模式
TL1 = 0x00; //設置定時初始值
TH1 = 0x00; //設置定時初始值
TF1 = 0; //清除TF1標志
HSSPI_CFG2=0X20;//開高速SPI模式,方便使用33M時鐘
SPSTAT=0x00;
SPCTL=0xd3;
MCLKOCR=0x82;//P1.6輸出2分頻系統時鐘,提供一個方便的測試信號源
//外部模式一
PWMA_PS=0x00;//選擇P1.0輸入外部信號
PWMA_CCER1=0x00;//關cc1通道,準備寫CCMR1
PWMA_CCMR1=0x01;//PWMA_CCMR1.CC1S=01//IC1映射在TI1FP1上。設置為輸入模式,關濾波,關預分頻器
PWMA_CCER1=0X01;//選擇cc1p上升沿極性.使能cc1p
PWMA_SMCR=0x57;//選中外部觸發輸入。上升沿觸發,復位模式,輸入通道在TI1FP1,資料參考值為0x57
PWMA_SR1=0;//中斷標志位清零
PWMA_SR2=0;//重復捕獲中斷標志位清零
EA=1;
ET0=1;
}
|
-
信號源設置8400HZ顯示
-
信號源設置8400HZ示波器顯示
-
信號源設置3萬HZ顯示
-
信號源設置3萬HZ示波器顯示
-
30萬測量顯示
-
240HZ測量顯示
-
-
Keil代碼.7z
2022-10-9 19:30 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
49.02 KB, 下載次數: 26, 下載積分: 黑幣 -5
評分
-
查看全部評分
|