A. 單片機頻率計
1.實驗任務
利用51單片機的T0、T1的定時計數器功能,來完成對輸入的信號進行頻率計數,計數的頻率結果通過8位動態數碼管顯示出來。要求能夠對0-250KHZ的信號頻率進行准確計數,計數誤差不超過±1HZ。
2.電路原理圖
見插圖
3.程序設計內容
(1).定時/計數器T0和T1的工作方式設置,由圖可知,T0是工作在計數狀態下,對輸入的頻率信號進行計數,但對工作在計數狀態下的T0,最大計數值為fOSC/24,由於fOSC=12MHz,因此:T0的最大計數頻率為250KHz。對於頻率的概念就是在一秒只數脈沖的個數,即為頻率值。所以T1工作在定時狀態下,每定時1秒中到,就停止T0的計數,而從T0的計數單元中讀取計數的數值,然後進行數據處理。送到數碼管顯示出來。
(2).T1工作在定時狀態下,最大定時時間為65ms,達不到1秒的定時,所以採用定時50ms,共定時20次,即可完成1秒的定時功能。
4.C語言源程序
/******************************************************************************
*定時器+計數器測頻
*
*file:frequency.c
*name:zhzhchang
*time:2010.3.17
*V1.0
*blog:http://blog.csdn.net/zhzht19861011
*Nots:本程序定義6個數碼管,經過實測,在200HZ~50KHZ時結果較准確,誤差小於0.4%,
*50KHZ以上頻率未進行測量.據資料表明,可以測量到120KHZ,本程序未證明.
*********************************************************************************/
#include<reg52.h>
bitint_flag;//定時器01S到標志位
unsignedcharvolatileint_count;//定時器0中斷次數
unsignedcharvolatileT1count;//定時器1中斷次數
unsignedcharcodedofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//顯示段碼值0123456789
unsignedlongsum;//1S內脈沖總個數
unsignedcharled[6];//LED顯示緩存
///////////////軟體延時/////////////
voiddelay(unsignedintcnt)
{
while(--cnt);
}
///定時器0初始化
voidinit_t0(void)
{
TMOD=(TMOD&0xF0)||0x01;//定時器0工作於方式1
TH0=(65536-50000)/256;//定時50ms
TL0=(65535-50000)%256;
}
//定時器1初始化
voidinit_t1(void)
{
TMOD=(TMOD&0x0F)|0x50;//timer1forcount
TH1=0x00;
TL1=0x00;
}
//顯示
voiddisp(void)
{
unsignedchari;
for(i=0;i<6;i++)
{
P0=dofly[(led[i])];//取顯示數據
P2=5-i;//取段碼
delay(100);//掃描間隙延時,根據單片機調整,延時1ms即可
}
}
///////////////////////////////////////////////////////
voidmain(void)
{
EA=1;//開總中斷
init_t0();//初始化定時器
init_t1();
TR0=1;//定時器開始工作
TR1=1;
ET0=1;//開T0中斷
while(1)
{
if(int_flag==1)
{
int_flag=0;
sum=TL1+TH1*256+T1count*65536;//計算1秒內的脈沖個數
//以下將數據格式化,轉成LED可顯示的BCD碼
led[0]=sum%10;//最低位
sum=sum/10;
led[1]=sum%10;//第二位
sum=sum/10;
led[2]=sum%10;
sum=sum/10;
led[3]=sum%10;
sum=sum/10;
led[4]=sum%10;
led[5]=sum/10;
int_count=0x00;
T1count=0;
TH1=0x00;
TL1=0x00;
TR1=1;
}
disp();
}
}
//定時器0中斷服務程序
voidint_t0(void)interrupt1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
int_count++;
if(int_count==20)
{
TR1=0;
int_flag=1;
int_count=0x00;
}
}
//定時器1中斷服務程序
voidint_t1(void)interrupt3
{
T1count++;
}
別說你的設計要求用匯編啊!!!
不過既然是課程設計,我這個只是給你參考,你自己一定要弄懂,變成自己的。我實測過,程序沒問題,但用到你的硬體上可能需要改一下,因為你的硬體數碼管不一定和我的硬體接法一樣,但整體思路我都給你了。
B. 51單片機的簡易頻率計設計
單片機直接用USB連電腦只能取電不能通訊,通訊的話 需要介面電路,例如USB轉TTL的晶元,CH340,PL2303,這樣的晶元才可以,如果直接測TTL電平的話 確實不需要其他外圍電路了,因為51的信號就是TLL電平的。
C. 基於89C51單片機的數字頻率計怎麼模擬啊
你使用PROTEUS軟體調用AT89C51,等你的程序編輯好了後,使用這個軟體調用軟體示波器產看對應頻率大小即可,其實,你需要做的就是程序,您這個程序可以使用定時器0來輸出,定時器1來計算數字頻率的脈沖計數,這樣就可以知道具體數字頻率的大小了。
D. 關於51單片機簡易頻率計的問題
該課程設計偏離了實際應用。
一般來說,單片機通過計數器實現頻率測量。測量方波外圍電路簡單,測量正弦波需要外部調理電路,但是,既然能夠做到測量正弦波了,方波更沒問題了。人為分為兩種模式,從使用上講,不方便,從技術上講,更是多此一舉。
E. 急需基於單片機AT89C51製作的頻率計原理圖!
原理圖很簡單 就接一塊液晶 然後用T0和TI分別用於計數和定時 就可以了
原理圖差不多就是一塊單片機加一個液晶
F. 基於MCS51單片機的頻率計設計
沒有現成的,但以前有一個調試程序是用C,送你看到它,電路很簡單,只要速度信號轉換為方波輸入IO口...您的郵箱是504370059 @ QQ。 COM,檢查一下
G. 51單片機頻率計數。
這個是需要修改的 51接12M晶振就是為了精確程序運行時間 內部是經過 12分頻的這樣運行一條一般的指令就是1us 至於單片機開發板一般可能是11.0592的 因為一般的開發板有串口 而用串口就必須用11.0592不然波特率不準
H. C51單片機的頻率計,但是輸入頻率在4位數以下有效,高了之後就顯示不對了,求高手幫忙看看代碼哪裡有問題
你好!
把程序和模擬發一下,幫你調試一下看看
I. 求51單片機頻率計程序!!!!!!!!!!!!!!
;******************************************************************
;* *
;* ME300B單片機開發系統演示程序-1602LCD顯示數字頻率計 *
;* *
;* 郵箱: [email protected] *
;* 網站: http://www.willar.com *
;* 作者: gguoqing *
;* 時間: 2006/06/03 *
;* *
;*【版權】COPYRIGHT(C)偉納電子 www.willar.com ALL RIGHTS RESERVED *
;*【聲明】此程序僅用於學習與參考,引用請註明版權和作者信息! *
;* *
;******************************************************************
;------------------------------------------------------------
;頻率計的程序
;包含:外部中斷設置,中斷服務程序,定時程序,定時服務程序
;以及數據處理,顯示,包括 三位十進制數轉化為四位BCD碼,
;
;------------------------------------------------------------
BEEP BIT P3.7
LCD_RS BIT P2.0
LCD_RW BIT P2.1
LCD_EN BIT P2.2
LCD_X EQU 3FH ;LCD 地址變數
TIMER_H EQU 30H ;定時器高位位元組單元
TIMER_L EQU 31H ;定時器低位位元組單元
TIMCOUNT EQU 32H ;時間中斷數
INT_G EQU 35H ;中斷計數緩沖單元高地址
INT_H EQU 34H ;中斷計數緩沖單元中地址
INT_L EQU 33H ;中斷計數緩沖單元低地址
T_S EQU 36H ;數據顯示低位
T_M EQU 37H ;數據顯示中位
T_H EQU 38H ;數據顯示高位
T_G EQU 39H ;數據顯示最高位
;----------------------------------------------------------
ORG 0000H
JMP MAIN ;主程序開始
ORG 000BH
JMP TIMER_INT ;定時器T0中斷服務程序
ORG 001BH ;定時器T1中斷服務程序
JMP TIMER1
ORG 0030H
;----------------------------------------------------------
MAIN:
MOV SP,#60H ;設置SP指針
LCALL PRO_SET ;初始化
CALL SET_LCD
LCALL TIM_T0
;-----------------------------------------------------------
;LCD1602是慢速顯示器件,故100MS顯示一次。
;-----------------------------------------------------------
MAIN1:
MOV R5,40
MAIN2:
ACALL DELAY1 ;3ms
DJNZ R5,MAIN2
ACALL SBIN_SBCD
CALL CONV
JMP MAIN1
;------------------------------------------------------------
;T1計數器中斷服務子程序
;計T1計數器溢出次數
;------------------------------------------------------------
TIMER1:
INC 2AH
RETI
;------------------------------------------------------------
;初始化程序
;------------------------------------------------------------
PRO_SET: MOV A,#00H
MOV B,#00H
MOV 2AH,A
MOV P0,#0FFH
MOV P1,#0FFH
MOV P2,#0FFH
MOV INT_H,#00H
MOV INT_L,#00H
MOV INT_G,#00H
MOV T_S,#00H
MOV T_H,#00H
MOV T_M,#00H
MOV T_G,#00H
MOV TIMCOUNT,#00H
MOV TIMER_H,#04CH ;定時 50 MS
MOV TIMER_L,#10H ;
CLR BEEP
SETB P3.5 ;P3.5埠置輸入狀態
RET ;T1(TIMER1的外部輸入腳)
;-----------------------------------------------------
;LCD 初始化設置
;-----------------------------------------------------
SET_LCD:
CLR LCD_EN
CALL INIT_LCD ;初始化 LCD
CALL DELAY1
MOV DPTR,#INFO1 ;指針指到顯示信息1
MOV A,#1 ;顯示在第一行
CALL LCD_SHOW
MOV DPTR,#INFO2 ;指針指到顯示信息2
MOV A,#2 ;顯示在第二行
CALL LCD_SHOW
RET
;-----------------------------------------------------
INFO1: DB " CYMOMETER ",0 ;LCD 第一行顯示信息
INFO2: DB "FREQ: HZ ",0 ;LCD 第二行顯示信息
;-----------------------------------------------------
;LCD 介面初始化
;8位I/O控制
;-----------------------------------------------------
INIT_LCD:
MOV A,#38H ;雙列顯示,字形5*7點陣
CALL WCOM
CALL DELAY1
MOV A,#38H ;雙列顯示,字形5*7點陣
CALL WCOM
CALL DELAY1
MOV A,#38H ;雙列顯示,字形5*7點陣
CALL WCOM
CALL DELAY1
MOV A,#0CH ;開顯示,關游標,
CALL WCOM
CALL DELAY1
MOV A,#01H ;清除 LCD 顯示屏
CALL WCOM
CALL DELAY1
RET
;----------------------------------------------------
LCD_SHOW: ;在LCD的第一行或第二行顯示信息字元
CJNE A,#1,LINE2 ;判斷是否為第一行
LINE1: MOV A,#80H ;設置 LCD 的第一行地址
CALL WCOM ;寫入命令
CALL CLR_LINE ;清除該行字元數據
MOV A,#80H ;設置 LCD 的第一行地址
CALL WCOM ;寫入命令
JMP FILL
LINE2: MOV A,#0C0H ;設置 LCD 的第二行地址
CALL WCOM ;寫入命令
CALL CLR_LINE ;清除該行字元數據
MOV A,#0C0H ;設置 LCD 的第二行地址
CALL WCOM
FILL: CLR A ;填入字元
MOVC A,@A+DPTR ;由消息區取出字元
CJNE A,#0,LC1 ;判斷是否為結束碼
RET
LC1: CALL WDATA ;寫入數據
INC DPTR ;指針加1
JMP FILL ;繼續填入字元
RET
;---------------------------------------------------
CLR_LINE: ;清除該行 LCD 的字元
MOV R0,#24
CL1: MOV A,#' '
CALL WDATA
DJNZ R0,CL1
RET
;-----------------------------------------------------
; 寫指令、數據使能子程序
;-----------------------------------------------------
ENABLE: ;寫指令使能
CLR LCD_RS ;RS=L,LCD_RW=L,D0-D7=指令碼,E=高脈沖
CLR LCD_RW
SETB LCD_EN
CALL DELAY0
CLR LCD_EN
RET
ENABLE1: ;寫數據使能
SETB LCD_RS ;RS=H,RW=L,D0-D7=數據,E=高脈沖
CLR LCD_RW
SETB LCD_EN
CALL DELAY0
CLR LCD_EN
RET
DELAY0: MOV R7,#250 ;延時500微秒
DJNZ R7,$
RET
;----------------------------------------------------
;寫入命令子程序
;----------------------------------------------------
WCOM: ;以8位控制方式將命令寫至LCD
MOV P0,A ;寫入命令
CALL ENABLE
RET
;----------------------------------------------------
;寫入數據子程序
;----------------------------------------------------
WDATA: ;以8位控制方式將數據寫至LCD
MOV P0,A ;寫入數據
CALL ENABLE1
RET
;---------------------------------------------------
;在 LCD 第二行顯示字元
;A=ASC DATA, B=LINE X POS
;---------------------------------------------------
LCDP2: ;在LCD的第二行顯示字元
PUSH ACC ;
MOV A,B ;設置顯示地址
ADD A,#0C0H ;設置LCD的第二行地址
CALL WCOM ;寫入命令
POP ACC ;由堆棧取出A
CALL WDATA ;寫入數據
RET
;-------------------------------------------------------
;ASCII 轉換並在第二行顯示數字子程序
;-------------------------------------------------------
CONV: ; MOV A,T_G
MOV LCD_X,#6 ;設置位置
; CALL SHOW_DIG2
MOV A,T_H
;INC LCD_X ;載入小時數據
CALL SHOW_DIG2 ;顯示數據
MOV A,T_M ;載入分鍾數據
INC LCD_X ;設置位置
CALL SHOW_DIG2 ;顯示數據
MOV A,T_S ;載入秒數數據
INC LCD_X ;設置位置
CALL SHOW_DIG2 ;顯示數據
RET
;----------------------------------------------------
SHOW_DIG2:
MOV B,#16
DIV AB
ADD A,#30H
PUSH B
MOV B,LCD_X
CALL LCDP2
POP B
MOV A,B
ADD A,#30H
INC LCD_X
MOV B,LCD_X
CALL LCDP2
RET
;-----------------------------------------------------
DELAY1: ;延時3MS
MOV R6,#15
D2: MOV R7,#100
DJNZ R7,$
DJNZ R6,D2
RET
; ----------------- 定時器設置 ------------------------
;設置定時器0工作在定時方式1,定時器1工作在計數方式1
;---------------------------------------------------------
TIM_T0: MOV TMOD,#0D1H
MOV TH0,TIMER_H ;設置定時初值高位
MOV TL0,TIMER_L ;設置定時初值低位
MOV TH1,#00H ;清T1計數器
MOV TL1,#00H
MOV IE,#8AH ;開中斷總允許,允許T0溢出中斷
SETB PT1
SETB TR1
SETB TR0 ;定時器開始工作
RET
;--------------------------------------------------------
;定時器0中斷服務程序
;--------------------------------------------------------
TIMER_INT:
CLR TR0 ;關閉定時器
MOV TL0,TIMER_L ;重新賦初值
MOV TH0,TIMER_H ;
INC TIMCOUNT ;定時1S,時間單位
MOV A,TIMCOUNT ;查看數量值
CPL P1.4 ;產生自測信號
CJNE A,#20,T_END ;如果沒有到1S返回
CLR TR1 ;關閉計數器T1
MOV TIMCOUNT,#00H ;到1S則清零
MOV INT_L,TL1 ;取出計數值低位
MOV INT_H,TH1 ;取出計數值高位
MOV INT_G,2AH ;取出溢出計數值位
MOV TH1,#00H
MOV TL1,#00H
MOV 2AH,#00H
SETB TR1
T_END: SETB TR0 ;重新開始定時操作
RETI
;---------------------------------------------------------------
;三位元組二進制整數轉換成四位元組BCD碼子程序
;二進制數從低位到高位分別存放在INT_L、INT_H、INT_G單元中
;BCD碼從低位到高位分別存放在T_S、T_M、T_H、T_G 單元中
;---------------------------------------------------------------
SBIN_SBCD:
PUSH PSW
SETB PSW.3 ;設置當前寄存器
CLR PSW.4
CLR A ;清累加器
MOV T_G,A
MOV T_H,A ;清除出口單元,准備轉換
MOV T_M,A
MOV T_S,A
MOV R5,INT_G
MOV R7,INT_L ;設置二進制數起始地址
MOV R6,INT_H
MOV R2,#24
CLR C
HH1:
MOV A,R7
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R5
RLC A
MOV R5,A
MOV A,T_S ;得到低位數據
ADDC A,T_S ;累加
DA A ;十進制調整
MOV T_S,A ;保存數據
MOV A,T_M ;得到第二位數據
ADDC A,T_M ;累加
DA A ;十進制調整
MOV T_M,A ;保存結果
MOV A,T_H ;得到第三位
ADDC A,T_H ;累加
DA A
MOV T_H,A ;保存
MOV A,T_G ;得到第四位
ADDC A,T_G ;累加
;DA A
MOV T_G,A
DJNZ R2,HH1 ;
POP PSW
RET
;----------------------------------------------------------------
END ;告訴編譯器本程序到此結束。
;-----------------------------------------------------------------
J. 51單片機製作簡易數字頻率計程序
這里有一個四位數碼管的頻率計,供參考
#include<reg52.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //所需的段的位碼
//ucharwei[4]={0XEf,0XDf,0XBf,0X7f};//位的控制端 (開發板)
ucharwei[4]={0X80,0X40,0X20,0X10};//位的控制端 (模擬)
uintz,x,c,v,date; //定義數據類型
uintdispcount=0;
uintlck=0;
uintdisp=0;
/******************************************************************
延時函數
******************************************************************/
voiddelay(uchart)
{
uchari,j;
for(i=0;i<t;i++)
{
for(j=13;j>0;j--);
{;
}
}
}
/**********************************************************************
數碼管動態掃描
*********************************************************************/
voidxianshi()
{
/*****************數據轉換*****************************/
z=date/1000; //求千位
x=date%1000/100; //求百位
c=date%100/10; //求十位
v=date%10; //求個位
P2=wei[0];
P0=an[z];
delay(50);
P2=wei[1];
P0=an[x];
delay(50);
P2=wei[2];
P0=an[c];
delay(50);
P2=wei[3];
P0=an[v];
delay(50);
}
/*************************************************************************
定時器初值1ms
**************************************************************************/
voidinitTimer(void)
{
TMOD=0x0;
TH0=0xe3;
TL0=0xc;
}
/*************************************************************************
定時器函數
**************************************************************************/
voidtimer0(void)interrupt1
{
TH0=0xe3;
TL0=0xc;
lck++;
if(lck==1000)
{
disp=dispcount;
lck=0;
dispcount=0;
}
}
/*************************************************************************
中斷函數
**************************************************************************/
voidint0(void)interrupt0
{
dispcount++;//每一次中斷,計數加一
}
/*************************************************************************
主函數
**************************************************************************/
voidmain(void)
{
IT0=1;//INT0下降沿中斷
EX0=1;//允許INT1中斷
initTimer();//裝入初值
TR0=1;
ET0=1;
EA=1;
while(1)
{
date=disp;
xianshi();
}
}