單片機(jī)頻率計(jì) 系統(tǒng)采用單片機(jī)+分頻模塊+整形模塊+lcd1602液晶顯示+按鍵設(shè)計(jì)而成。
頻率的測(cè)量范圍為1Hz—20MHz能測(cè)量各種周期信號(hào),能測(cè)出正弦波、三角波或方波等波形的頻率。通過(guò)LCD1602液晶顯示屏顯示檢測(cè)到的即時(shí)頻率數(shù)值(最多8位數(shù),單位為Hz)。
頻率計(jì)電路原理圖如下:
74HC14電路設(shè)計(jì) 由于三極管放大電路輸出的信號(hào)不是標(biāo)準(zhǔn)的方波信號(hào),存在著上升沿不夠陡峭,波形類(lèi)似于正弦波等問(wèn)題,為了使單片機(jī)對(duì)信號(hào)更好的采集,這里使用了施密特觸發(fā)器74HC14對(duì)三極管放大電路輸出的信號(hào)進(jìn)行整形。電路圖如圖3-10所示。 圖3-10施密特觸發(fā)器電路原理圖 其中輸入信號(hào)從芯片的1號(hào)腳輸入,74HC14本身是一個(gè)芯片內(nèi)部帶有6個(gè)施密特觸發(fā)器,我這里為了充分利用芯片使用了其中三個(gè),實(shí)際上可以只使用一個(gè)。整形后的信號(hào)從芯片的6號(hào)腳輸出。 3.5分頻模塊設(shè)計(jì) 3.5.1 74HC390芯片介紹 分頻電路一般采用十進(jìn)制計(jì)數(shù)器如74HC290、74HC390等來(lái)實(shí)現(xiàn)時(shí)間計(jì)數(shù)單元的計(jì)數(shù)功能。本次設(shè)計(jì)中選擇74HC390。由其內(nèi)部邏輯框圖(如圖3)可知,其為雙2-5-10異步計(jì)數(shù)器,并每一計(jì)數(shù)器均有一個(gè)異步清零端(高電平有效)。由于我們要設(shè)計(jì)的是100分頻電路,因此74HC390內(nèi)部?jī)蓚(gè)計(jì)數(shù)器都用上,分別都設(shè)置成10計(jì)數(shù)器。 圖3-11 74HC390內(nèi)部邏輯框圖 3.5.2 74HC390分頻電路設(shè)計(jì) 由于單片機(jī)運(yùn)行速度有限,單片機(jī)運(yùn)行一條基礎(chǔ)指令需要1個(gè)機(jī)器周期即12個(gè)是時(shí)鐘周期,換算成時(shí)間為1us。因此當(dāng)頻率過(guò)高的時(shí)候單片機(jī)就不能很精確的換算出頻率。為了解決這個(gè)問(wèn)題,這設(shè)計(jì)加入了一個(gè)100分頻的計(jì)數(shù)器。當(dāng)頻率高于200KHZ的時(shí)候單片機(jī)計(jì)算分頻后的信號(hào),當(dāng)頻率低于200KHZ的時(shí)候計(jì)算分頻前的信號(hào)。這樣高低搭配可以擴(kuò)大單片機(jī)的測(cè)量頻率。最終換算出其真實(shí)對(duì)應(yīng)的頻率并在液晶上顯示。其中電路圖如圖3-12所示。 圖3-12 74HC390分頻電路原理圖
4.系統(tǒng)軟件設(shè)計(jì) 4.1系統(tǒng)軟件總體設(shè)計(jì) 4-1系統(tǒng)主流程圖
頻率計(jì)元件清單:
單片機(jī)仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
頻率計(jì)仿真操作說(shuō)明:
鼠標(biāo)右擊這個(gè)元件, 選擇最后一項(xiàng)就可以了
單片機(jī)頻率計(jì)源程序如下: - //******************************************************************************************
- //連接框圖: ___________________
- // | P1.0 |->RS
- // | P1.1 |->RW
- // | P1.2 |->E
- // | P0 |->DB
- // | P3.4 |->1~9999hz的輸入
- // | P3.5 |->1~9999KHZ輸入 (分頻后)
- //******************************************************************************************
- #include <reg52.h>
- unsigned long int fre;
- unsigned char time;
- unsigned int count;
- unsigned int count1;
- //端口及函數(shù)說(shuō)明----------------------------------------------------------------------------
- sbit LCD_RS=P1^0; //片選信號(hào)
- sbit LCD_RW=P1^1; //讀寫(xiě)信號(hào)
- sbit LCD_E=P1^2; //使能信號(hào)
- #define LCD_DB P0 //數(shù)據(jù)信號(hào)
- unsigned char character[10]={0};//在屏幕上顯示的字符串
- unsigned char character_1[]={"fre= Hz"};
- unsigned char FLAG = 0;
- void LCD_init(void);//初始化函數(shù)
- void LCD_write_command(unsigned char command);//寫(xiě)指令函數(shù)
- void LCD_write_data(unsigned char dat);//寫(xiě)數(shù)據(jù)函數(shù)
- void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat);//在某個(gè)屏幕位置上顯示一個(gè)字符,X(0-15),y(1-2)
- void delay_n40us(unsigned int n);//延時(shí)函數(shù)
-
- void timer_init(); //中斷初始化函數(shù)
- //-------------------------------------------------------------------------------
- void delay_n40us(unsigned int n) //延時(shí)函數(shù)
- {
- unsigned int i;
- unsigned char j;
- for(i=n;i>0;i--)
- for(j=0;j<2;j++);
- }
- void delay_1s()
- {
- unsigned int i,j;
- for(i = 0;i<100;i++)
- for(j = 0;j<1000;j++);
- }
- void LCD_init(void) //液晶初始化函數(shù)
- {
- LCD_write_command(0x38);//設(shè)置8位格式,2行,5x7
- LCD_write_command(0x38);//設(shè)置8位格式,2行,5x7
- LCD_write_command(0x38);//設(shè)置8位格式,2行,5x7 切記要寫(xiě)三遍!!!!
- LCD_write_command(0x0c);//整體顯示,關(guān)光標(biāo),不閃爍
- LCD_write_command(0x06);//設(shè)定輸入方式,增量不移位
- LCD_write_command(0x01);//清除屏幕顯示
- delay_n40us(100);//清屏延時(shí)
- }
- void LCD_write_command(unsigned char dat) //寫(xiě)命令函數(shù)
- {
- LCD_DB=dat;
- LCD_RS=0;//指令
- LCD_RW=0;//寫(xiě)入
- LCD_E=1; //使能
- LCD_E=0;
- delay_n40us(1);//寫(xiě)命令延時(shí)
- }
- void LCD_write_data(unsigned char dat) //寫(xiě)數(shù)據(jù)函數(shù)
- {
- LCD_DB=dat;
- LCD_RS=1;//數(shù)據(jù)
- LCD_RW=0;//寫(xiě)入
- LCD_E=1;//使能
- LCD_E=0;
- delay_n40us(1); //寫(xiě)數(shù)據(jù)延時(shí)
- }
- void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat)//顯示一個(gè)字符
- {
- unsigned char address;
- if(y==1)
- address=0x80+x; //顯示在第一排的時(shí)候的x的地址
- else
- address=0xc0+x; //顯示在第二排的時(shí)候的x的地址
- LCD_write_command(address); //輸入地址
- LCD_write_data(dat); //輸入數(shù)據(jù)
- }
- void LCD_disp_num(unsigned char x,unsigned char y,unsigned char dat)//顯示一個(gè)數(shù)字
- {
- unsigned char address;
- if(y==1)
- address=0x80+x; //顯示在第一排的時(shí)候的x的地址
- else
- address=0xc0+x; //顯示在第二排的時(shí)候的x的地址
- LCD_write_command(address); //輸入地址
- LCD_write_data(dat+48); //輸入數(shù)據(jù)
- }
- void dis_num(void)
- {
- unsigned char i=0,j=0,k=0;
- LCD_write_command(0x01);//清除屏幕顯示
-
- character[0] = fre/1000000;
- character[1] = fre/100000%10;
- character[2] = fre/10000%10;
- character[3] = fre/1000%10;
- character[4] = fre/100%10;
- character[5] = fre/10%10;
- character[6] = fre%10;
- character[7] = 'H';
- character[8] = 'z';
-
- for(i = 0;i<4;i++) //顯示fre
- {
- LCD_disp_char(i+0,1,character_1[i]);
- }
- for(i = 0;i<10;i++) //判斷第一個(gè)不為0的數(shù)
- {
- if(character[i]!=0)
- break;
- }
- k = 10-i-2;
- for(j = 0;j<k;j++) //顯示所有的數(shù)字
- {
- LCD_disp_num(4+j,1,character[i++]);
- }
-
- for(i = 5;i<7;i++) //顯示Hz
- {
- LCD_disp_char(j+4,1,character_1[i]);
- j++;
- }
- }
- void main()
- {
- unsigned char i;
- LCD_init();
- timer_init(); //定時(shí)/計(jì)數(shù)器初始化
-
- for(i = 0;i<4;i++)
- {
- LCD_disp_char(i+0,1,character_1[i]);
- }
- while(1)
- {
- dis_num(); //顯示
- delay_1s();
-
- }
- }
- void timer_init(void) //定時(shí)/計(jì)數(shù)器初始化
- {
- TMOD=0x66; //計(jì)數(shù)器0工作工作方式2,自動(dòng)重裝初值
- TH0=0; //計(jì)數(shù)器初值為0
- TL0=0;
- TR0=1; //計(jì)數(shù)器開(kāi)始計(jì)數(shù)
- ET0=1; //打開(kāi)計(jì)數(shù)器0中斷
- TH1=0; //計(jì)數(shù)器初值為0
- TL1=0;
- TR1=1; //計(jì)數(shù)器開(kāi)始計(jì)數(shù)
- ET1=1; //打開(kāi)計(jì)數(shù)器0中斷
- RCAP2H=(65536-62500)/256; //在程序初始化的時(shí)候給RCAP2L和RCAP2H賦值,
- RCAP2L=(65536-62500)%256; //TH2和TL2將會(huì)在中斷產(chǎn)生時(shí)自動(dòng)使TH2=RCAP2H,TL2=RCAP2L。
- TH2=RCAP2H; //12M晶振下每次中斷62.5ms
- TL2=RCAP2L;
- ET2=1; //打開(kāi)定時(shí)器2中斷
- TR2=1; //定時(shí)器2開(kāi)始計(jì)時(shí)
- EA=1; //開(kāi)總中斷
- }
- //----------------------------------------------------------------
- void timer2(void) interrupt 5 //定時(shí)器2中斷(62.5ms)
- {
- double temp;
- time++;
- TF2=0; //定時(shí)器2的中斷標(biāo)志位TF2不能夠由硬件清零,所以要在中斷服務(wù)程序中將其清零
- if (time==16) //定時(shí)1s時(shí)間到
- {
- time=0; //計(jì)時(shí)清0
- fre=(long)count*256+TL1; //count*256強(qiáng)制轉(zhuǎn)換成long型,否則將不產(chǎn)生進(jìn)位 先判斷分頻后的
- FLAG = 0;
-
- if(fre<2000)//200K之后讀取分頻后的頻率
- {
- fre = (long)count1*256+TL0;
- FLAG = 1;
- }
-
- count=0; //清零計(jì)數(shù)器0計(jì)數(shù)
- count1=0;
- EA=1; //開(kāi)中斷
- }
- }
- //----------------------------------------------------------------
- void timer0(void) interrupt 1 //計(jì)數(shù)器0中斷
- {
- count++;
- }
- //----------------------------------------------------------------
- void timer1(void) interrupt 3 //計(jì)數(shù)器1中斷
- {
- count1++;
- }
-
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
|