導航:首頁 > 操作系統 > 單片機頻率計匯編

單片機頻率計匯編

發布時間:2024-12-17 13:45:51

A. 做用51單片機做一個頻率計,測量范圍為0.1Hz~10kHz

在不改變定時時間的前提下,也就是0.5秒定時,是不能實現0.1~2Hz頻率的測量的。
你所謂2Hz~10KHz易實現也是基於這個道理。但這個也是理論情況。
當你0.5s內剛好檢測到一個脈沖,你認為這個時候是2Hz而不是2.5hz或者3.9hz?
這中間存在一個測量精度的問題。實際上你所測到的信號是在2hz到4hz之間。

實際上我們在測量信號的時候,低頻一般會採用測周期,高頻用測頻才能提高測量的准確性。
至於高低頻的臨界點,跟你的計數頻率有關,感興趣的話可以去看《電子測量原理》。

下面我來講下測周實現的方法,可以使用邊沿觸發的D觸發器輸出作為單片機的外部定時控制,測量信號作為觸發時鍾,計數值作為該信號的周期。

B. 單片機頻率計原理程序代碼

#include <AT89X51.H>
//********數碼管位代碼表(P0口)**********//
unsigned char code dispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//********數碼管段代碼表(P2口,共陰且高位接a,低位接h筆段)**********//
unsigned char code dispcode[]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,
0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x00};
//********8位數據緩沖器**********//
unsigned char dispbuf[8];
unsigned char temp[8];
unsigned char dispcount;
unsigned char T0count;
unsigned char timecount;
bit flag;
unsigned long x;

//*********初始化模塊**********//
void initial(void){
TMOD=0x15;
TH0=0;
TL0=0;
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
TR1=0;
TR0=0;
ET0=1;
ET1=1;
EA=1;
}
//******************************************************//

//*********顯示模塊**********//
void dataDisplay(){
unsigned char i;
for(i=0;i<8;i++){
temp[i]=0;
}
i=0;
while(x/10){
temp[i]=x%10;
x=x/10;
i++;
}
temp[i]=x;
for(i=0;i<8;i++){
dispbuf[i]=temp[i];
}
P2=dispcode[dispbuf[dispcount]];
P0=dispbit[dispcount];
dispcount++;
if(dispcount==8){
dispcount=0;
}
}
//******************************************************//

//*********信號頻率測量模塊**********//
float frequency(float freq){
initial();
TR0=1;TR1=1;
if(timecount==250){
TR0=0;
freq=T0count*65536+TH0*256+TL0;
return(freq);
}
}
//******************************************************//

//*********信號周期測量模塊**********//
float cycle(float count){
initial();
if(P3_4==1){
TR0=1;TR1=1;
if(P3_4==0){
TR0=0;
count=1000000/(timecount*4000+TH1*256+TL1-61536);
}
}
return(count);
}
//******************************************************//

//*********定時中斷服務程序1**********//
void t1(void) interrupt 3 using 0{
//initial();
//TR0=1;
//TR1=1;
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
timecount++;
}
//******************************************************//

//*********定時中斷服務程序2**********//
void t0(void) interrupt 1 using 0{
//initial();
//TR0=1;
//TR1=1;
T0count++;
}
//******************************************************//

//*********主函數**********//
void main(void){
while(1){
x=frequency(x);
if(x<100){
x=cycle(x);
}
dataDisplay();
}
}
//******************************************************//

C. 51單片機用定時器計數器測量頻率

定時器1對外部脈沖計數時TMOD高4位設置應該是5
因此TMOD=0x51;
以下我的頻率計程序:
#include <reg52.h>//因沒用到STC12C5410專有特殊功能寄存器,此處用52或51的頭文件均可
#define unit unsigned int
#define uchar unsigned char
//定義以I/O口的功能
sbit beiguang=P3^2;//液晶屏背光
sbit rs=P1^3;//液晶屏寫選擇,0命令 1數據
sbit rw=P1^4;//液晶屏讀寫選擇
sbit lcden=P1^5;//液晶屏使能
sbit fm=P1^7;//蜂鳴器

#define db P2 //定義P2為數據輸出口,寫數據時用db代替P2,增加液晶屏程序的通用性

//更改硬體接線時,只更改此處,而不必去更改液晶屏讀寫子程序
uchar aa,bb,cc;//變數聲明
unit dd,ee;
void Delay1ms(unsigned int i) //1ms延時程序

{
unsigned int j;
for(;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}
void init()//初始化設置

{
TMOD=0x15;//定時器0作為計數器,定時器1作為定時器用
TH0=0;//計數器清0
TL0=0;
EA=1;//開總中斷
ET1=1;//允許定時器1中斷
TH1=0x4c;
TL1=0x5c;
TR0=1;//啟動計數器
TR1=1;//啟動定時器
aa=0;
}
void write_com(uchar com)//向液晶屏寫命令

{
db=com;
rs=0;
rw = 0;
lcden=0;
Delay1ms(10*12);
lcden=1;
Delay1ms(10*12);
lcden=0;
}
void write_date(uchar date)//向液晶屏寫數據

{
db=date;
rs=1;
rw = 0;
lcden=0;
Delay1ms(10*12);
lcden=1;
Delay1ms(10*12);
lcden=0;
}
void init2()//液晶屏初始化
{
beiguang=0;
rw=0;
write_com(0x38);
Delay1ms(10*12);
write_com(0x0f);
Delay1ms(10*12);
write_com(0x06);
Delay1ms(10*12);
write_com(0x01);
Delay1ms(10*12);
}
void display4(unsigned int number) //單行多位顯示程序
{
uchar A1,A2,A3,A4,A5;
init2();//液晶屏初始化
A1=number/10000%10;//分離出萬,千,百,十,個,對於int型數據,最大不超過65535
A2=number/1000%10;
A3=number/100%10;
A4=number/10%10;
A5=number%10;
write_com(0x80);//第1個數據的位置設定,第1行第1列
Delay1ms(10);
write_date(0x30+A1);//寫數據
Delay1ms(10);
write_date(0x30+A2);
Delay1ms(10);
write_date(0x30+A3);
Delay1ms(10);
write_date(0x30+A4);
Delay1ms(10);
write_date(0x30+A5);
Delay1ms(10);

write_com(0x87);//第6個數據'H'的位置,中間空85和86 二格
write_date('H');
Delay1ms(10);
write_date('z');
Delay1ms(10);
}
void main()//主程序很簡單
{
init();//初始化
while(1)//循環程序
{
dd=bb*256+cc;//0.5S的計數值
ee=2*dd;//換算為1秒鍾的計數值
if(aa==1)
{
if(TH0>12)//預判斷,50ms內TH0>12,1s內計數值將超過可計數的最大值65535
fm=0;//報警
}
display4(ee);//顯示
fm=1;//報警停止
}
}
void timer1()interrupt 3//注意:定時器1的中斷序號為3
{
aa++;
TH1=0x4c;//11.0592Mhz
TL1=0x5c;
if(aa==10)//中斷10次,共0.5S
{
TR0=0;//暫停計數
aa=0;
bb=TH0;//讀出計數器數據
cc=TL0;
TL0=0;//計數器清0
TH0=0;
TR0=1;//重新啟動
}
}

D. 基於51單片機上的頻率計怎麼設計頻率量程轉換 例如通過按鍵切換Hz~kHz,程序怎麼編寫

通過不同的埠控制外接的分頻器。或接外接與門和二進制計數器。

E. 求51單片機設計數字頻率計,附帶Proteus模擬和程序

剛剛下了一樓傳的附件,測試後發現精度和測量范圍都比較差。如果單從測頻的角度來說,51的頻率計是很簡單的。恰好幾年前我寫過類似的程序,是用來測頻率和占空比的。

理論上單用C52這單片機測頻率最高為:12M/12/2=500KHZ。我寫的這個程序可以同時測頻率和脈寬,模擬下大概可以測到350KHZ;測脈寬好像10KHZ左右,再高的話脈寬的精度就會下降。測頻精度在100KHZ以內,基本是2HZ;200K是5HZ;350KHZ以內是10HZ;最低測量頻率1HZ。

模擬比較慢,數據要3秒後才會穩定,有興趣的話自測吧。

50KHZ測量

F. 設計一個以單片機為核心的頻率測量裝置。求大神給寫一下程序。

單片機頻率計模擬。

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

sbit p0=P1^0;

bit tb0,tb1;

uchar tt0,tt1,tt2,tt3;

uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

void main()

{

TMOD=0x11;

TH0=(65535-50000)/256;

TL0=(65535-50000)%256;

EA=1;

ET0=1; //開定時器0中斷

ET1=1; //開定時器1中斷

TR0=1; //啟動定時器0

TR1=1; //啟動定時器1

while(1)

{

if(TR1==0)

{

// tt3=65536*tt2+266*TH1+TL1

TH1=0x00;TL1=0x00;

tt1=0x00;tt2=0x00;

tb1=1;

led[0]=tt3/1000000;

led[1]=tt3/100000%10;

led[2]=tt3/100000%10;

led[3]=tt3/10000%10;

led[4]=tt3/1000%10;

led[5]=tt3/100%10;

led[6]=tt3/10%10;

led[7]=tt3%10;

}

if(tt0==1 && tb0=1)

{

tb0=1;P0==0xff;

P2=led[0];P0=0xfe

}

if(tt0==2 && tb0=1)

{

tb0=1;P0==0xff;

P2=led[1];P0=0xfd

}

if(tt0==3 && tb0=1)

{

tb0=1;P0==0xff;

P2=led[2];P0=0xfb

}

if(tt0==4 && tb0=1)

{

tb0=1;P0==0xff;

P2=led[3];P0=0xf7

}

if(tt0==5 && tb0=1)

{

tb0=1;P0==0xff;

P2=led[4];P0=0xef

}

if(tt0==6 && tb0=1)

{

tb0=1;P0==0xff;

P2=led[5];P0=0xdf

}

if(tt0==7 && tb0=1)

{

tb0=1;P0==0xff;

P2=led[6];P0=0xbf

}

if(tt0==8 && tb0=1)

{

tb0=1;P0==0xff;

P2=led[7];P0=0x7f

tt0=0;

}

}

}

void timer0() interrupt 1

{

TH0=(65535-2000)/256;

TL0=(65535-2000)%256;

tt1++;

if(tt1==500)

{

TR1=0; //啟動定時器1

tb1=0

}

tt0++;tb0=1;

if(tb1==1 && TR1==0)TR1=1;

}

void timer1() interrupt 3

{

tt2++;

}

閱讀全文

與單片機頻率計匯編相關的資料

熱點內容
數據加密升級 瀏覽:164
移動設備網頁源碼 瀏覽:702
做程序員幾年了感覺都是在做業務 瀏覽:68
移動魔白盒伺服器地址 瀏覽:348
linuxapache狀態 瀏覽:298
華為伺服器准系統是什麼 瀏覽:236
word壓縮所有圖片大小 瀏覽:391
php求平均值 瀏覽:120
焊錫單片機 瀏覽:917
自由程序員如何賺錢 瀏覽:682
手機pdf閱讀器哪個好 瀏覽:25
命令行插件 瀏覽:111
安卓手機沒有呼吸燈怎麼看消息 瀏覽:751
雜訊檢測app哪個好 瀏覽:813
androidapp生命周期 瀏覽:344
小眾搭配app哪個好用 瀏覽:825
奧特佳電動空調壓縮機 瀏覽:596
用什麼編譯器看nginx源碼 瀏覽:333
java中局部變數 瀏覽:821
雲伺服器命令行復制文件 瀏覽:401