㈠ 怎麼使用單片機的定時計數器,實現最簡單的對外部信號進行測頻,試畫出電路圖並
CPU時序的有關知識
振盪周期:為單片機提供定時信號的振盪源的周期(晶振周期或外加振盪周期)
狀態周期:2個振盪周期為1個狀態周期,用S表示。振盪周期又稱S周期或時鍾周期。
機器周期:1個機器周期含6個狀態周期,12個振盪周期。
指令周期:完成1條指令所佔用的全部時間,它以機器周期為單位。
例如:外接晶振為12MHz時,51單片機相關周期的具體值為:
振盪周期=1/12us;
狀態周期=1/6us;
機器周期=1us;
指令周期=1~4us;
在學習定時器之前需要明白的
51單片機有兩組定時器/計數器,因為既可以定時,又可以計數,故稱之為定時器/計數器。
定時器/計數器和單片機的CPU是相互獨立的。
定時器/計數器工作的過程是自動完成的,不需要CPU的參與。
51單片機中的定時器/計數器是根據機器內部的時鍾或者是外部的脈沖信號對寄存器中的數據加1。
有了定時器/計數器之後,可以增加單片機的效率,一些簡單的重復加1的工作可以交給定時器/計數器處理。CPU轉而處理一些復雜的事情。同時可以實現精確定時作用。
定時/計數器的工作原理
定時/計數器實質上是一個加1計數器。它隨著計數器的輸入脈沖進行自加1,也就是每來一個脈沖,計數器就自動加1,,當加到計數器為全1時,再輸入一個脈沖就使計數器回零,且計數器的溢出使相應的中斷標志位置1,向CPU發出中斷請求(定時/計數器中斷允許時)。如果定時/計數器工作於定時模式,則表示定時時間已到;如果工作於計數模式,則表示計數值已滿。
可見,由溢出時計數器的值減去計數初值才是加1計數器的計數值。
51單片機定時器結構
定時/計數器的實質是加1計數器(16位),由高8位和低8位兩個寄存器THx和TLx組成。TMOD是定時/計數器的工作方式寄存器,確定工作方式和功能;TCON是控制寄存器,控制T0、T1的啟動和停止及設置溢出標志。
定時/計數器的控制
51單片機定時/計數器的工作由兩個特殊功能寄存器控制。TMOD用於設置其工作方式;TCON用於控制其啟動和中斷申請。
1、工作方式寄存器TMOD
工作方式寄存器TMOD用於設置定時/計數器的工作方式,低四位用於T0,高四位用於T1。其格式如下:
GATE是門控位, GATE=0時,用於控制定時器的啟動是否受外部中斷源信號的影響。只要用軟體使TCON中的TR0或TR1為1,就可以啟動定時/計數器工作;
GATA=1時,要用軟體使TR0或TR1為1,同時外部中斷引腳INT0/1也為高電平時,才能啟動定時/計數器工作。即此時定時器的啟動條件,加上了INT0/1引腳為高電平這一條件。
C/T :定時/計數模式選擇位。C/T =0為定時模式;C/T =1為計數模式。
M1M0:工作方式設置位。定時/計數器有四種工作方式。
2、控制寄存器TCON
TCON的低4位用於控制外部中斷,已在前面介紹。TCON的高4位用於控
制定時/計數器的啟動和中斷申請。其格式如下:
TF1(TCON.7):T1溢出中斷請求標志位。T1計數溢出時由硬體自動置TF1為1。CPU響應中斷後TF1由硬體自動清0。T1工作時,CPU可隨時查詢TF1的狀態。所以,TF1可用作查詢測試的標志。TF1也可以用軟體置1或清0,同硬體置1或清0的效果一樣。
TR1(TCON.6):T1運行控制位。TR1置1時,T1開始工作;TR1置0時,T1停止工作。TR1由軟體置1或清0。所以,用軟體可控制定時/計數器的啟動與停止。
TF0(TCON.5):T0溢出中斷請求標志位,其功能與TF1類同。
TR0(TCON.4):T0運行控制位,其功能與TR1類同。
定時/計數器的工作方式
1、方式0
方式0為13位計數,由TL0的低5位(高3位未用)和TH0的8位組成。TL0的低5位溢出時向TH0進位,TH0溢出時,置位TCON中的TF0標志,向CPU發出中斷請求。
定時器模式時有:N=t/ Tcy
計數初值計算的公式為:X=2^13-N。
定時器的初值還可以採用計數個數直接取補法獲得。
計數模式時,計數脈沖是T0引腳上的外部脈沖。
門控位GATE具有特殊的作用。當GATE=0時,經反相後使或門輸出為1,此時僅由TR0控制與門的開啟,與門輸出1時,控制開關接通,計數開始;當GATE=1時,由外中斷引腳信號控制或門的輸出,此時控制與門的開啟由外中斷引腳信號和TR0共同控制。當TR0=1時,外中斷引腳信號引腳的高電平啟動計數,外中斷引腳信號引腳的低電平停止計數。這種方式常用來測量外中斷引腳上正脈沖的寬度。
2、方式1
方式1的計數位數是16位,由TL0作為低8位,TH0
作為高8位,組成了16位加1計數器 。
計數個數與計數初值的關系為:X=2^16-N
3、方式2
方式2為自動重裝初值的8位計數方式。
計數個數與計數初值的關系為:X=2^8-N
工作方式2特別適合於用作較精確的脈沖信號發生器。
4、方式3
方式3隻適用於定時/計數器T0,定時器T1處於方式3時相當於TR1=0,停止計數。
工作方式3將T0分成為兩個獨立的8位計數器TL0和TH0 。
使用定時器,該做哪些工作
初始化程序應完成如下工作:
1.對TMOD賦值,以確定T0和T1的工作方式。
2.計算初值,並將其寫入TH0、TL0或TH1、TL1。
3.中斷方式時,則對EA賦值,開放定時器中斷。
4.使TR0或TR1置位,啟動定時/計數器定時或計數。
計數器初值的計算:
機器周期也就是CPU完成一個基本操作所需要的時間。
機器周期=1/單片機的時鍾頻率。
51單片機內部時鍾頻率是外部時鍾的12分頻。也就是說當外部晶振的頻率輸入到單片機裡面的時候要進行12分頻。比如說你用的是12MHZ的晶振,那麼單片機內部的時鍾頻率就是12/12MHZ,當你使用12MHZ的外部晶振的時候。機器周期=1/1M=1us。
而我們定時1ms的初值是多少呢,1ms/1us=1000。也就是要計數1000個數,初值=65535-1000+1(因為實際上計數器計數到64536才溢出)=64536=FC18H
定時器中斷
使用定時器,該做哪些工作
初始化程序應完成如下工作:
對TMOD賦值,以確定T0和T1的工作方式。
計算初值,並將其寫入TH0、TL0或TH1、TL1。
中斷方式時,則對EA賦值,開放定時器中斷。
使TR0或TR1置位,啟動定時/計數器定時或計數。
㈡ 單片機課程設計數字頻率計
數碼管台古老了,你用這個吧,看著還稍微有點可以,代碼和電路都給你了,沒有做不出來的理由,有問題加我QQ11422376745
#include "d:c51 eg51.h"
#include "d:c51intrins.h"
sbit LCM_RS=P3^0;
sbit LCM_RW=P3^1;
sbit LCM_EN=P3^7;
#define BUSY 0x80 //常量定義
#define DATAPORT P1
#define uchar unsigned char
#define uint unsigned int
#define L 50
uchar str0[16],str1[16],count;
uint speed;
unsigned long time;
void ddelay(uint);
void lcd_wait(void);
void display();
void initLCM();
void WriteCommandLCM(uchar WCLCM,uchar BusyC);
void STR();
void account();
/*********延時K*1ms,12.000mhz**********/
void int0_isr(void) interrupt 0 /*遙控使用外部中斷0,接P3.2口*/
{
unsigned int temp;
time=count;
TR0=0;
temp=TH0;
temp=((temp << 8) | TL0);
TH0=0x3c;
TL0=0xaf;
count=0;
TR0=1;
time=time*50000+temp;
}
void time0_isr(void) interrupt 1 /*遙控使用定時計數器1 */
{
TH0 =0x3c;
TL0 =0xaf;
count++;
}
void main(void)
{
TMOD=0x01; /*TMOD T0選用方式1(16位定時) */
IP|=0x01; /*INT0 中斷優先*/
TCON|=0x11; /*TCON EX0下降沿觸發,啟動T0*/
IE|=0x83;
TH0=0x3c;
TL0=0xaf;
initLCM();
WriteCommandLCM(0x01,1); //清顯示屏
for(;;)
{
account();
display();
}
}
void account()
{
unsigned long a;
if (time!=0)
{
a=L*360000000/time;
}
speed=a;
}
void STR()
{
str0[0]='S';
str0[1]='p';
str0[2]='e';
str0[3]='e';
str0[4]='d';
str0[5]=' ';
str0[6]=(speed%100000)/10000+0x30;
str0[7]=(speed%10000)/1000+0x30;
str0[8]=(speed%1000)/100+0x30;
str0[9]='.';
str0[10]=(speed%100)/10+0x30;
str0[11]=speed%10+0x30;
str0[12]='k';
str0[13]='m';
str0[14]='/';
str0[15]='h';
}
void ddelay(uint k)
{
uint i,j;
for(i=0;i<k;i++)
{
for(j=0;j<60;j++)
{;}
}
}
/**********寫指令到LCD子函數************/
void WriteCommandLCM(uchar WCLCM,uchar BusyC)
{
if(BusyC)lcd_wait();
DATAPORT=WCLCM;
LCM_RS=0; /* 選中指令寄存器*/
LCM_RW=0; // 寫模式
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
/**********寫數據到LCD子函數************/
void WriteDataLCM(uchar WDLCM)
{
lcd_wait( ); //檢測忙信號
DATAPORT=WDLCM;
LCM_RS=1; /* 選中數據寄存器 */
LCM_RW=0; // 寫模式
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
/***********lcd內部等待函數*************/
void lcd_wait(void)
{
DATAPORT=0xff; //讀LCD前若單片機輸出低電平,而讀出LCD為高電平,則沖突,Proteus模擬會有顯示邏輯黃色
LCM_EN=1;
LCM_RS=0;
LCM_RW=1;
_nop_();
_nop_();
_nop_();
while(DATAPORT&BUSY)
{ LCM_EN=0;
_nop_();
_nop_();
LCM_EN=1;
_nop_();
_nop_();
}
LCM_EN=0;
}
/**********LCD初始化子函數***********/
void initLCM( )
{
DATAPORT=0;
ddelay(15);
WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號
ddelay(5);
WriteCommandLCM(0x38,0);
ddelay(5);
WriteCommandLCM(0x38,0);
ddelay(5);
WriteCommandLCM(0x38,1); //8bit數據傳送,2行顯示,5*7字型,檢測忙信號
WriteCommandLCM(0x08,1); //關閉顯示,檢測忙信號
WriteCommandLCM(0x01,1); //清屏,檢測忙信號
WriteCommandLCM(0x06,1); //顯示游標右移設置,檢測忙信號
WriteCommandLCM(0x0c,1); //顯示屏打開,游標不顯示,不閃爍,檢測忙信號
}
/****顯示指定坐標的一個字元子函數****/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=1;
X&=15;
if(Y)X|=0x40; //若y為1(顯示第二行),地址碼+0X40
X|=0x80; //指令碼為地址碼+0X80
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}
/*******顯示指定坐標的一串字元子函數*****/
void DisplayListChar(uchar X,uchar Y,uchar *DData)
{
uchar ListLength=0;
Y&=0x01;
X&=0x0f;
while(X<16)
{
DisplayOneChar(X,Y,DData[ListLength]);
ListLength++;
X++;
}
}
void display()
{
STR();
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
}
㈢ 51單片機的數字頻率計
本應用系統設計的目的是通過在「單片機原理及應用」課堂上學習的知識,以及查閱資料,培養一種自學的能力。並且引導一種創新的思維,把學到的知識應用到日常生活當中。在設計的過程中,不斷的學習,思考和同學間的相互討論,運用科學的分析問題的方法解決遇到的困難,掌握單片機系統一般的開發流程,學會對常見問題的處理方法,積累設計系統的經驗,充分發揮教學與實踐的結合。全能提高個人系統開發的綜合能力,開拓了思維,為今後能在相應工作崗位上的工作打下了堅實的基礎。
1.1數字頻率計概述
數字頻率計是計算機、通訊設備、音頻視頻等科研生產領域不可缺少的測量儀器。它是一種用十進制數字顯示被測信號頻率的數字測量儀器。它的基本功能是測量正弦信號,方波信號及其他各種單位時間內變化的物理量。在進行模擬、數字電路的設計、安裝、調試過程中,由於其使用十進制數顯示,測量迅速,精確度高,顯示直觀,經常要用到頻率計。
本數字頻率計將採用定時、計數的方法測量頻率,採用一個1602A LCD顯示器動態顯示6位數。測量范圍從1Hz—10kHz的正弦波、方波、三角波,時基寬度為1us,10us,100us,1ms。用單片機實現自動測量功能。
基本設計原理是直接用十進制數字顯示被測信號頻率的一種測量裝置。它以測量周期的方法對正弦波、方波、三角波的頻率進行自動的測量。
點擊重新載入
1.2頻率測量儀的設計思路與頻率的計算
圖1 頻率測量原理圖
頻率測量儀的設計思路主要是:對信號分頻,測量一個或幾個被測量信號周期中已知標准頻率信號的周期個數,進而測量出該信號頻率的大小,其原理如右圖1所示。
若被測量信號的周期為,分頻數m1,分頻後信號的周期為T,則:T=m1Tx 。由圖可知: T=NTo
(註:To為標准信號的周期,所以T為分頻後信號的周期,則可以算出被測量信號的頻率f。)
由於單片機系統的標准頻率比較穩定,而是系統標准信號頻率的誤差,通常情況下很小;而系統的量化誤差小於1,所以由式T=NTo可知,頻率測量的誤差主要取決於N值的大小,N值越大,誤差越小,測量的精度越高。
1.3 基本設計原理
基本設計原理是直接用十進制數字顯示被測信號頻率的一種測量裝置。它以測量周期的方法對正弦波、方波、三角波的頻率進行自動的測量。
所謂「頻率」,就是周期性信號在單位時間(1s)內
㈣ 單片機頻率計
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++;
}
別說你的設計要求用匯編啊!!!
不過既然是課程設計,我這個只是給你參考,你自己一定要弄懂,變成自己的。我實測過,程序沒問題,但用到你的硬體上可能需要改一下,因為你的硬體數碼管不一定和我的硬體接法一樣,但整體思路我都給你了。
㈤ 51單片機電子頻率計
建議你去"幸福校園"看看 裡面有些樣子 你可以參考
前言
傳統的數字頻率計都是採用純硬體方式組成(純數字電路)。它的集成電路(IC)用量較大,因而產品的體積、功耗都較大,生產成本較高。產品定型後不能升級(加入新功能)。而採用單片機和相關可編程智能集成器件製成的現代數字頻率計方式情況就不同了,單片機的內核CPU可完成多項工作如計數、讀入、解碼、驅動和時基的產生等。和純硬體方式比,它減少了很大一部分的集成電路的用量,還可加入許多的智能操作,這更是純硬體方式所望塵莫及的。
目前市場上的頻率計產品很多,但基本上都是採用專用計數晶元(如ICM7240 , ICM7216) 和數字邏輯電路組成,由於這些晶元本身的工作頻率不高(如ICM7240 僅有15MHz 左右) ,從而限制了產品的工作頻率的提高, 遠不能達到在一些特殊的場合需要測量很高的頻率的要求,而且測量精度也受到晶元本身極大的限制。
自從80年代單片機引入我國之後,單片機已廣泛地應用於各行各業的電子設計中,使頻率計智能化水平在廣度和深度上產生了質的飛躍,數字化也成為了電子設計的必由之路. 運用單片機和高速計數器的組合設計頻率計,並採用適當的演算法取代傳統電路,次方法不僅能解決傳統頻率計結構復雜、穩定性差、精度不高的弊端,而且性能也將大有提高,可實現精度較高、等精度和寬范圍頻率計的要求;隨著單片機技術的不斷發展,可以用單片機通過軟體設計直接用十進制數字顯示被測信號頻率。本設計正是基於此技術進行的傳統頻率計技術改進。
㈥ 單片機頻率計
測頻法,用T0計時,T1計數。
#include <reg52.H>
#include <intrins.h>
void Delay_nus(unsigned int n);
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char T1count;
unsigned char timecount;
unsigned int x;
void main(void)
{
TMOD=0x51; //定時器工作方式
TH0=0x4c; //裝入初值,延時50ms 11.059326MHz
TL0=0;
TH1=TL1=0;
IP=0x02;
IE|=0x8a;
TCON|=0x50;
while(1)
{
P0=dispcode[x/10000];
P1=0x00;
P0=dispcode[x/1000%10];
P1=0x20;
P0=dispcode[x/100%10];
P1=0x40;
P0=dispcode[x/10%10];
P1=0x60;
P0=dispcode[x%10];
P1=0x80;
Delay_nus(15);
P0=0x76;
P1=0xa0;
}
}
void t1(void) interrupt 3
{
T1count++;
}
void t0(void) interrupt 1
{
TH0=0x4c; //重新裝入初值
TL0=0;
if(++timecount==20) //當1秒時 註:中斷里應該盡量少做任務,但是這個是必須再這里的,否則關中斷不及時造成統計錯誤
{
TCON&=0xaf;
x=T1count*65536+TH1*256+TL1;
timecount=0; //全部初始化
T1count=0;
TH1=TL1=0;
TCON|=0x50;
} //計T0中斷次數,統計時間
}
void Delay_nus(unsigned int n)
{
while(n--)
_nop_();
}
㈦ 51單片機做頻率計電路輸出到單片機有錯誤,該怎麼辦
叫人修