|
基于AT89C51單片機設(shè)計了一款測量范圍在10HZ-10KHZ的頻率計,主要由輸入放大電路,整形電路、單片機AT89C51和顯示電路等組成。被測信號(正弦波或方波)通過放大、整形電路轉(zhuǎn)換成同頻率的方波脈沖信號,采用單片機內(nèi)部的定時/計數(shù)器T0進行計數(shù)。放大整形后的信號輸入到AT89C51單片機T0中斷口使用其計數(shù)模式對輸入信號進行計數(shù),再利用內(nèi)部定時器T1進行定時。最后在軟件的主函數(shù)部分通過一系列計算得出頻率,輸送至LCD液晶顯示屏輸出測量輸入信號值。
方案:
系統(tǒng)以AT89C51為核心,設(shè)計了一款測試范圍在10Hz ~ 10KHz 的頻率計。該系統(tǒng)主要設(shè)計思想是信號予處理電路 、串行通信電路 、測量數(shù)據(jù)顯示電路和系統(tǒng)軟件所組成, 其中信號予處理電路包含待測信號放大、波形變換、波形整形和分頻電路。信號予處理電路中的放大器實現(xiàn)對待測信號的放大 ,降低對待測信號的幅度要求;波形變換和波形整形電路實現(xiàn)把正弦波樣的正負交替的信號波形變換成可被單片機接受的信號。
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei.png (28.67 KB, 下載次數(shù): 52)
下載附件
2020-6-10 03:11 上傳
51hei.png (54.06 KB, 下載次數(shù): 46)
下載附件
2020-6-10 03:11 上傳
51hei.png (3.9 KB, 下載次數(shù): 52)
下載附件
2020-6-10 03:12 上傳
單片機源程序如下:
- #include <reg52.h>
-
- #define LCD1602_DB P0 //數(shù)據(jù)信號
- #define u32 unsigned long int
- #define u16 unsigned int
- #define u8 unsigned char
- u32 fre;
- u8 add;
- u8 WeiShu;
- u16 count;
- u16 count1;
- sbit LCD1602_RS=P2^6; //片選信號
- sbit LCD1602_RW=P2^5; //讀寫信號
- sbit LCD1602_E=P2^7; //使能信號
- u8 character[15]; //在屏幕上顯示的字符串
- u8 character_1[]={"frequency lx"}; //顯示
- u8 hz[]={"Hz"};
- u8 khz[]={"KHz"};
- void InitLcd1602();
- void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
- void timer_init(); //中斷初始化函數(shù)
- void delay_1s() //延遲1s
- {
- unsigned int i,j;
- for(i = 0;i<100;i++)
- for(j = 0;j<1000;j++);
- }
- // 等待液晶準備好
- void LcdWaitReady()
- {
- u8 sta;
- LCD1602_DB = 0xFF;
- LCD1602_RS = 0;
- LCD1602_RW = 1;
- do
- {
- LCD1602_E = 1;
- sta = LCD1602_DB; //讀取狀態(tài)字
- LCD1602_E = 0;
- }while (sta & 0x80); //bit7 等于 1 表示液晶正忙,重復(fù)檢測直到其等于 0 為止
- }
- //向 LCD1602 液晶寫入一字節(jié)命令,cmd-待寫入命令值
- void LcdWriteCmd(unsigned char cmd)
- {
- LcdWaitReady();
- LCD1602_RS = 0;
- LCD1602_RW = 0;
- LCD1602_DB = cmd;
- LCD1602_E = 1;
- LCD1602_E = 0;
- }
- // 向 LCD1602 液晶寫入一字節(jié)數(shù)據(jù),dat-待寫入數(shù)據(jù)值
- void LcdWriteDat(unsigned char dat)
- {
- LcdWaitReady();
- LCD1602_RS = 1;
- LCD1602_RW = 0;
- LCD1602_DB = dat;
- LCD1602_E = 1;
- LCD1602_E = 0;
- }
- // 設(shè)置顯示 RAM 起始地址,亦即光標位置,(x,y)-對應(yīng)屏幕上的字符坐標
- void LcdSetCursor(unsigned char x, unsigned char y)
- {
- u8 addr;
- if (y == 0){ //由輸入的屏幕坐標計算顯示 RAM 的地址
- addr = 0x00 + x; //第一行字符地址從 0x00 起始
- }else{
- addr = 0x40 + x; //第二行字符地址從 0x40 起始
- }
- LcdWriteCmd(addr | 0x80); //設(shè)置 RAM 地址
- }
- //在液晶上顯示字符串,(x,y)-對應(yīng)屏幕上的起始坐標,str-字符串指針
- void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
- {
- LcdSetCursor(x, y); //設(shè)置起始地址
- while (*str != '\0')
- { //連續(xù)寫入字符串數(shù)據(jù),直到檢測到結(jié)束符
- LcdWriteDat(*str++); //先取 str 指向的數(shù)據(jù),然后 str 自加 1
- }
- }
- // 初始化 1602 液晶
- void InitLcd1602()
- {
- LcdWriteCmd(0x38); //16*2 顯示,5*7 點陣,8 位數(shù)據(jù)接口
- LcdWriteCmd(0x0C); //顯示器開,光標關(guān)閉
- LcdWriteCmd(0x06); //文字不動,地址自動+1
- LcdWriteCmd(0x01); //清屏
- }
- void number_dispose() //數(shù)據(jù)處理
- {
- //character[15]={'\0'};
- u8 i,j=1;
- u32 temp;
- u32 number_sign;
-
- if(fre<1000)
- {
- temp=fre*100;
- number_sign=fre*100;
- while(temp>0) //計算位數(shù)
- {
- temp/=10;
- j++;
- }
- WeiShu=j;
- for(i=0;i<j;i++) //依次取余
- {
- if(i==2)
- character[j-i-1]='.';
- else
- {
- character[j-i-1]=number_sign%10+0x30;
- number_sign/=10;
- }
- }
- }
- else
- {
- temp=fre;
- number_sign=fre;
- while(temp>0) //計算位數(shù)
- {
- temp/=10;
- j++;
- }
- WeiShu=j;
- for(i=0;i<j;i++) //依次取余
- {
- if(i==3)
- character[j-i-1]='.';
- else
- {
- character[j-i-1]=number_sign%10+0x30;
- number_sign/=10;
- }
- }
- }
- }
- void main()
- {
- timer_init(); //定時/計數(shù)器初始化
- while(1)
- {
- number_dispose(); //數(shù)據(jù)處理
- InitLcd1602();
- LcdShowStr(0, 0, character_1);
- LcdShowStr(0, 1, character);
- if(fre<1000)
- LcdShowStr(WeiShu+1, 1, hz);
- else
- LcdShowStr(WeiShu+1, 1, khz);
- delay_1s();
- }
- }
- //定時/計數(shù)器初始化
- void timer_init(void) //定時/計數(shù)器初始化
- {
- TMOD=0x66; //計數(shù)器0和計數(shù)器1工作工作方式2,自動重裝初值
- TH0=0; //計數(shù)器初值為0
- TL0=0;
- TR0=1; //計數(shù)器開始計數(shù)
- ET0=1; //打開計數(shù)器0中斷
- TH1=0; //計數(shù)器初值為0
- TL1=0;
- TR1=1; //計數(shù)器開始計數(shù)
- ET1=1; //打開計數(shù)器1中斷
- RCAP2H=(65536-62500)/256; //在程序初始化的時候給RCAP2L和RCAP2H賦值,
- RCAP2L=(65536-62500)%256; //TH2和TL2將會在中斷產(chǎn)生時自動使TH2=RCAP2H,TL2=RCAP2L。
- TH2=RCAP2H; //12M晶振下每次中斷62.5ms(1s=1000ms=62.5ms×16)
- TL2=RCAP2L;
- ET2=1; //打開定時器2中斷
- TR2=1; //定時器2開始計時
- EA=1; //開總中斷
- }
- //中斷函數(shù)
- void timer2(void) interrupt 5 //定時器2中斷(62.5ms)
- {
- add++;
- TF2=0; //定時器2的中斷標志位TF2不能夠由硬件清零,所以要在中斷服務(wù)程序中將其清零
- if (add==32) //定時1s時間到
- {
- add=0; //計時清0
- EA=0; //關(guān)中斷
- fre=(long)count1*256+TL1; //count*256強制轉(zhuǎn)換成long型,否則將不產(chǎn)生進位~先判斷分頻后(計數(shù)器1)
- // FLAG = 0;
- if(fre<2000)//如果不到200KHz則讀取分頻前(計數(shù)器0)頻率(200K÷100=2000)
- {
- fre = (long)count*256+TL0;
- // FLAG = 1;
- }
- // if(!FLAG)
- // {
- // fre = fre *100;//100分頻
- // }
- TL0=0; //清零計數(shù)器0計數(shù)
- TH0=0;
- TL1=0;
- TH1=0;
- count=0; //清零計數(shù)器0計數(shù)
- count1=0;
- EA=1; //開中斷
- }
- }
- void timer0(void) interrupt 1 //計數(shù)器0中斷
- {
- count++;
- }
復(fù)制代碼
所有資料51hei提供下載:
|
-
-
簡易頻率計-AD原理圖PCB.zip
2020-6-9 19:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
854.88 KB, 下載次數(shù): 36, 下載積分: 黑幣 -5
AD原理圖及PCB
-
-
簡易頻率計-程序.zip
2020-6-9 19:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
6.88 KB, 下載次數(shù): 27, 下載積分: 黑幣 -5
程序
-
-
簡易頻率計-文檔.zip
2020-6-9 19:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
162.12 KB, 下載次數(shù): 33, 下載積分: 黑幣 -5
文檔
評分
-
查看全部評分
|