|
電路原理圖.gif (166.42 KB, 下載次數(shù): 57)
下載附件
2023-5-25 15:24 上傳
- /********************************************************
- 項(xiàng) 目:51單片機(jī)頻率計(jì)
- 單片機(jī):STC89c52RC
- 元 件:24MHZ晶振、1602液晶、MB506超高頻分頻器、
- 74HC393二進(jìn)制脈沖計(jì)數(shù)器、BF998雙刪極場(chǎng)效應(yīng)管、
- 74HC14施密特觸發(fā)器。
- 設(shè)計(jì)思路:參考網(wǎng)上“diy頻率計(jì)”帖子重新整理編程。利
- 用T0做定時(shí)器、T2做計(jì)數(shù)器,在一秒內(nèi)T2計(jì)數(shù)脈沖
- 數(shù)計(jì)算頻率
- 測(cè)試信號(hào)頻率32MHZ到2.4GHZ時(shí),開(kāi)關(guān)撥到高頻位置,
- 信號(hào)經(jīng)MB506放大分頻再輸入到BF998放大——74HC14整
- 形——74HC393計(jì)數(shù)后由Q1Q2Q3Q4送到單片機(jī)的P14 P15
- P16 P17腳,其中Q4也送到單片機(jī)的P1.0腳,從
- 而記錄Q4的脈沖個(gè)數(shù),計(jì)算出信號(hào)頻率。
- 測(cè)試信號(hào)頻率低于32MHZ時(shí),開(kāi)關(guān)撥到低頻位置,
- 被測(cè)試信號(hào)不經(jīng)過(guò)MB506直接到BF998放大,后面同上
- 編 程:
- ********************************************************/
- #include<at89x52.h>
- #define uchar unsigned char
- #define uint unsigned int
- unsigned char code table[]="f= M K Hz"; //兆hz 千hz
- unsigned char code table1[]="T= m u ns";//微妙 納秒 皮秒
- unsigned char code table2[]="0123456789";
- sbit lcdrs=P2^7;
- sbit lcdrw=P2^6;
- sbit lcden=P2^5;
- sbit LS393_MR=P1^3;
- sbit k200Hz=P2^0;
- sbit GP=P2^1;
- sbit k=P1^2;
- unsigned int jishu,i;
- unsigned long f=0,T,irtime;
- bit a=0; //標(biāo)志位,為1表示本次測(cè)試結(jié)束,可進(jìn)行下次測(cè)試
- /****************以下延時(shí)函數(shù)******************/
- void yanshi500us(uint x)
- {
- uint y;
-
- for(x;x>0;x--)
- for(y=122;y>0;y--);
- }
- void delay1s(void) //誤差 0us
- {
- unsigned char a,b,c,n;
- for(c=167;c>0;c--)
- for(b=39;b>0;b--)
- for(a=152;a>0;a--);
- for(n=1;n>0;n--);
- }
- //================以下是LCD操作=========================
- void read_busy() /*LCD1602 忙等待*/
- {
- lcdrs = 0;
- lcdrw = 1;
- lcden = 1;
- P0 = 0xff;
- while (P0&0x80);
- lcden = 0;
- }
-
- void lcdrw_com(unsigned char com) //寫(xiě)命令
- {
- read_busy();
- lcdrw=0;
- lcdrs=0;
- P0=com;
- yanshi500us(1);
- lcden=1;
- yanshi500us(1);
- lcden=0;
- // lcdrs=1;
- yanshi500us(10);
- }
-
- void lcdrw_dat(unsigned char dat) //寫(xiě)數(shù)據(jù)
- {
- read_busy();
- lcdrw=0;
- lcdrs=1;
- P0=dat;
- yanshi500us(1);
- lcden=1;
- yanshi500us(2);
- lcden=0;
- // lcdrs=1;
- yanshi500us(10);
- }
- void write_lcd(uchar COM,uchar dat)//向LCD寫(xiě)一個(gè)字
- {
- lcdrw_com(COM);
- lcdrw_dat(dat);
-
- }
-
- void lcdinit()
- {
- yanshi500us(30);
- lcdrw_com(0x38); //設(shè)置16*2屏顯,5*7點(diǎn)陣,8位數(shù)據(jù)接口
- yanshi500us(10);
- lcdrw_com(0x38);
- yanshi500us(10);
- lcdrw_com(0x38);
- yanshi500us(10);
- lcdrw_com(0x08); //關(guān)閉顯示
- lcdrw_com(0x01); //清屏
- lcdrw_com(0x06); //讀寫(xiě)一個(gè)字符后指針加一光標(biāo)加一
- lcdrw_com(0x0c); //開(kāi)顯示,顯示光標(biāo),光標(biāo)閃爍
-
- for(i=0;i<17;i++)
- {
- lcdrw_dat(table[i]); //寫(xiě)第一行數(shù)據(jù)f= M K HZ
- }
-
- lcdrw_com(0x80+0x40); //第二行起始位
- for(i=0;i<16;i++)
- {
- lcdrw_dat(table1[i]); //寫(xiě)第二行數(shù)據(jù)T= u n ps
- }
-
- }
- /*******************定時(shí)器0中斷服務(wù)函數(shù)**********************/
- void tim0_isr (void) interrupt 1 using 1//定時(shí)器0中斷服務(wù)函數(shù)
- {
- unsigned int fl;
- float ff; //用于計(jì)算帶小數(shù)點(diǎn)的頻率
- irtime++; //用于計(jì)數(shù)2個(gè)下降沿之間的時(shí)間
- if(k200Hz==0)
- {
- if(jishu==2)
- {
- TR0=0;
- TR2=0;
- ff=4000000.00/((irtime)*25); //精確到小數(shù)點(diǎn)后兩位
- f=ff*100; //使000.00類(lèi)型的小數(shù)變?yōu)?0000整數(shù),
- //從而容易分解個(gè)十百整數(shù)及小數(shù)點(diǎn)后兩位小數(shù)
- // f=4*f;
-
- if(irtime==0)
- {
- f=0;T=0;
- }
- else
- T=(1000000000/ff); //周期ns
- a=1;
- delay1s();
- }
- }
- else
- {
- if(irtime==20000) //計(jì)時(shí)夠2秒
- {
- fl=P1>>4; //少于16個(gè)脈沖的脈沖數(shù)
- TR2=0; //關(guān)計(jì)數(shù)器2
- TR0=0; //關(guān)定時(shí)器0
- irtime=0;
-
- fl=P1>>4; //少于16個(gè)脈沖的脈沖數(shù)
- f=((jishu*65536+(TH2*256+TL2))*16+fl)/2;//2秒內(nèi)總脈沖數(shù)即頻率
- if(GP==0)
- {
- f=2*f*64;
- }
- else
- f=2*f;
- if(f==0)
- T=0;
- else //下載時(shí)使用6T模式
- T=1000000000/f; //周期ns
- a=1;
- }
- }
- }
- void TIM0init(void)//定時(shí)器0初始化
- {
- TMOD=0x02;//定時(shí)器0工作方式2,8位初值自動(dòng)重裝,TH0是重裝值,TL0是初值
- ET0=1; //開(kāi)中斷
-
- if(k200Hz==0)
- {
- TH0=0xce;//初始值
- TL0=0xce;//自動(dòng)重裝值,定時(shí)25um
- TR2=1; //開(kāi)計(jì)數(shù)器2
- TR0=0; //關(guān)定時(shí)器0
- }
- else
- {
- TH0=0x38;//初始值
- TL0=0x38;//自動(dòng)重裝值,定時(shí)100um
- TR2=1; //開(kāi)計(jì)數(shù)器2
- TR0=1; //開(kāi)定時(shí)器0
- }
- }
-
- /*******************T2計(jì)數(shù)器初始化***********************/
- void t2Init(void) //t2初始化
- {
- TR2=0; //停止計(jì)數(shù)器2
- T2CON=0x2; //計(jì)數(shù)器
- T2MOD=0x00;
-
- if(k200Hz==0)
- {
- RCAP2H=0xff;
- RCAP2L=0xfe; // 自動(dòng)重裝,接收1個(gè)脈沖中斷
- }
- else
- {
- RCAP2H=0x0;
- RCAP2L=0x0; // 自動(dòng)重裝,接收65536個(gè)脈沖中斷
- }
- TH2=RCAP2H;
- TL2=RCAP2L; //定時(shí)器2賦初值
- EA=1; //開(kāi)總中斷
- ET2=1; // 開(kāi)外定時(shí)器2中斷
- }
- /*********************T2計(jì)數(shù)器***************************/
- void timer2() interrupt 5
- {
- TF2=0; //!!!注意!!! 定時(shí)器2必須由軟件對(duì)溢出標(biāo)志位清零,硬件不能清零,這里與定時(shí)器0和定時(shí)器1不同!!!
- jishu++;//T2中斷次數(shù),如果k200Hz=0,來(lái)一個(gè)脈沖中斷一次,否則65536個(gè)脈沖中斷一次
- if(k200Hz==0)
- {
- if(jishu==1) //收到第一個(gè)脈沖時(shí)開(kāi)啟計(jì)時(shí)器
- {
- TR0=1;
- }
- }
- }
- /*****************74LS393 復(fù)位*******************/
- void LS393_rest()
- {
- LS393_MR=0;
- LS393_MR=1;
- LS393_MR=0;
- }
- void main()
- {
- yanshi500us(100);
- lcdinit();
- t2Init();
- TIM0init();
-
- yanshi500us(100);
- LS393_rest();
- while(1)
- {
- if(k200Hz==0)
- {
- write_lcd(0x80+9,'z');
- write_lcd(0x80+8,'H');
- write_lcd(0x80+5,'.');
- write_lcd(0x80+10,' ');
- write_lcd(0x80+14,' ');
- write_lcd(0x80+15,' ');
-
- write_lcd(0x80+2,table2[f%100000/10000]);
- write_lcd(0x80+3,table2[f%10000/1000]);
- write_lcd(0x80+4,table2[f%1000/100]);
- write_lcd(0x80+6,table2[f%100/10]);
- write_lcd(0x80+7,table2[f%10]);
- delay1s();
-
- }
- /********************以下顯示頻率*********************/
- else
- {
- write_lcd(0x80+2,table2[f/1000000000]);
- write_lcd(0x80+3,table2[f%1000000000/100000000]);
- write_lcd(0x80+4,table2[f%100000000/10000000]);
- write_lcd(0x80+5,table2[f%10000000/1000000]);
- write_lcd(0x80+7,table2[f%1000000/100000]);
- write_lcd(0x80+8,table2[f%100000/10000]);
- write_lcd(0x80+9,table2[f%10000/1000]);
- write_lcd(0x80+11,table2[f%1000/100]);
- write_lcd(0x80+12,table2[f%100/10]);
- write_lcd(0x80+13,table2[f%10]);
- }
- /**********************以下顯示周期***************************/
- write_lcd(0x80+0x40+2,table2[T/1000000000]);
- write_lcd(0x80+0x40+3,table2[T%1000000000/100000000]);
- write_lcd(0x80+0x40+4,table2[T%100000000/10000000]);
- write_lcd(0x80+0x40+5,table2[T%10000000/1000000]);
- write_lcd(0x80+0x40+7,table2[T%1000000/100000]);
- write_lcd(0x80+0x40+8,table2[T%100000/10000]);
- write_lcd(0x80+0x40+9,table2[T%10000/1000]);
- write_lcd(0x80+0x40+11,table2[T%1000/100]);
- write_lcd(0x80+0x40+12,table2[T%100/10]);
- write_lcd(0x80+0x40+13,table2[T%10]);
- if(a==1)
- {
- a=0;
- jishu=0;
- irtime=0;
- t2Init();
- LS393_rest();
- TIM0init();
- }
- }
- }
復(fù)制代碼
|
評(píng)分
-
查看全部評(píng)分
|