


PS—串行口中斷優(yōu)先級控制位
PT1—TC1中斷優(yōu)先級控制位
PX1—外部中斷1優(yōu)先級控制位
PT0—TC0中斷優(yōu)先級控制位
PX0—外部中斷0優(yōu)先級控制位
同優(yōu)先級的中斷請求,按默認(rèn)順序響應(yīng)。
【說明】
1. 本文里類似的x均可取值為0或1。
2. TC指Timer/Counter,即定時器/計(jì)數(shù)器。
3. 機(jī)器周期是單片機(jī)的基本操作周期,一個機(jī)器周期內(nèi)單片機(jī)完成一項(xiàng)基本操作,如取指等。一個機(jī)器周期包含12個時鐘周期。時鐘周期是時鐘頻率的倒數(shù)。
4. T0對應(yīng)引腳P3.4,T1對應(yīng)P3.5。
5. INT0對應(yīng)P3.2引腳,INT1對應(yīng)P3.3引腳。
二、定時器的使用
由于定時器都是由初值計(jì)數(shù)直至溢出,因此最重要的就是設(shè)置計(jì)數(shù)器的初值。 假設(shè)需要定時器產(chǎn)生一次中斷的事件為t,計(jì)算初值的步驟如下:


四、例程
可將以下代碼直接復(fù)制到.c文件中。





STC89C52單片機(jī)定時器1實(shí)現(xiàn)計(jì)數(shù)器
///////////////////////////////////////////////////////////////////////////
實(shí)現(xiàn)功能: 配置定時器1的相關(guān)寄存器,使其實(shí)現(xiàn)定時器中斷功能,然后通過在數(shù)碼管顯示
實(shí)驗(yàn)板型號:BS-XYD-C52
實(shí)驗(yàn)名稱: 定時器1實(shí)現(xiàn)計(jì)數(shù)器
///////////////////////////////////////////////////////////////////////////
#include《reg52.h》
#define uchar unsigned char //定義unsigned char 為 uchar
#define uint unsigned int //定義unsigned int 為 uint
uchar cTime_10ms_counter; //中斷次數(shù)計(jì)數(shù)單元
uchar cTime_1s_ok; //判斷是否為1s的變量
uchar uDis_buff[2]; //顯示緩沖區(qū),存放要顯示的2個字符的段碼值
uchar cTime; //秒計(jì)數(shù)單元
#define Time_1s_Sign 100 //根據(jù)中斷周期,判斷是否到一秒的標(biāo)志
sbit Duan=P2^6; //定義數(shù)碼管的段選使能端
sbit Wei =P2^7; //定義數(shù)碼管的位選使能端
#define Digital_tube_Wei_Enable Wei=1; //開啟控制數(shù)碼管的位選使能端
#define Digital_tube_Wei_Disable Wei=0; //關(guān)閉控制數(shù)碼管的位選使能端
#define Digital_tube_Duan_Enable Duan=1; //開啟控制數(shù)碼管的段選使能端
#define Digital_tube_Duan_Disable Duan=0; //關(guān)閉控制數(shù)碼管的段選使能端
#define Digital_tube_Duan P0 //定義數(shù)碼管數(shù)據(jù)端口
uchar code Dis_table[]= //將BCD碼轉(zhuǎn)換成數(shù)碼管掃描碼的數(shù)組
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};
uchar code Dis_Position[]= //定義數(shù)碼管位選的數(shù)組
{0x3e,0x3d,0x3b,0x37,0x1f,0x2f};
///////////////////////////////////////////////////////////////////////////
函數(shù)名稱:毫秒延時函數(shù)
函數(shù)功能:實(shí)現(xiàn)毫秒級的延時
參數(shù)介紹:Delay_MS: 定義需要延時的毫秒的數(shù)值
iNumber: 記錄Delay_MS的數(shù)值,以for語句實(shí)現(xiàn)所要求的延時
iValue: 要延時毫秒所要進(jìn)行的循環(huán)數(shù)值,本數(shù)值為實(shí)際測得
返回值: 無
注意事項(xiàng):本實(shí)驗(yàn)是在所用晶振為12M的前提下實(shí)現(xiàn)的毫秒延時,本函數(shù)是通過循環(huán)的形
式完成,所以如果改變了晶振的頻率,請做相應(yīng)的改變
///////////////////////////////////////////////////////////////////////////
void DelayMs(uint Delay_MS)
{
uint iNumber,iValue;
for(iNumber=0;iNumber《Delay_MS;iNumber++) //用for語句實(shí)現(xiàn)單片機(jī)的延時
{
iValue=107; //107這個數(shù)值是通過測定而得
while(iValue--);
}
}
///////////////////////////////////////////////////////////////////////////
函數(shù)名稱:One_DigitalTube_display
函數(shù)功能:完成在實(shí)驗(yàn)板上數(shù)碼管指定顯示,即在特定的數(shù)碼管上顯示特定的數(shù)字,比
在第一個數(shù)碼管上顯示0
參數(shù)介紹:uData:要顯示的數(shù)字的BCD碼數(shù)組
uNumber:選擇哪個數(shù)碼管顯示,即讓某個特定數(shù)碼管顯示
返回值: 無
注意事項(xiàng):實(shí)驗(yàn)板上的數(shù)碼管是共陰極的數(shù)碼管,如果使用共陽極的數(shù)碼管,請注意不
要弄反了
///////////////////////////////////////////////////////////////////////////
void One_DigitalTube_display(uchar uData,uchar uNumber)
{
Digital_tube_Duan_Enable; //使能數(shù)碼管的段選
Digital_tube_Duan=Dis_table[uData];//輸入所要顯示的數(shù)值
Digital_tube_Duan_Disable; //關(guān)閉數(shù)碼管的段選
Digital_tube_Duan=Dis_Position[uNumber]; //點(diǎn)亮特定的數(shù)碼管
Digital_tube_Wei_Enable; //使能數(shù)碼管的位選
Digital_tube_Wei_Disable; //關(guān)閉數(shù)碼管的位選
DelayMs(5); //調(diào)整時序,以實(shí)現(xiàn)穩(wěn)定顯示
}
///////////////////////////////////////////////////////////////////////////
函數(shù)名稱:Time_to_disbuffer
函數(shù)功能:把要在數(shù)碼管上顯示的數(shù)值,進(jìn)行取余、取整,即對數(shù)值進(jìn)行分割,這樣以
便顯示在分離的數(shù)碼管
參數(shù)介紹:無
返回值: 無
注意事項(xiàng):無
///////////////////////////////////////////////////////////////////////////
void Time_to_disbuffer()
{
uDis_buff[1]=cTime; //對cTime的數(shù)值取余,即就是取cTime的個位
uDis_buff[0]=cTime/10; //對cTime的數(shù)值取整,即就是取cTime的十位
}
///////////////////////////////////////////////////////////////////////////
函數(shù)名稱:Init_time1
函數(shù)功能:配置定時器1,配置的模式是定時器1采用16位定時器模式,在定時器1的輸入
數(shù)值寄存器輸入特定的數(shù)值,使其每次中斷的周期為10ms,同時允許定時器1
中斷,并打開總中斷
參數(shù)介紹:無
返回值: 無
注意事項(xiàng):無
///////////////////////////////////////////////////////////////////////////
void Init_time1(void)
{
TMOD |= 0x10;
TH1=(65535-10000)/256;
TL1=(65535-10000)%6; //定時器0的,寫入數(shù)值寄存器的低8位
EA=1; //總中斷打開
ET1=1; //定時器T0允許中斷
TR1=1; //定時器T0開始工作
}
///////////////////////////////////////////////////////////////////////////
函數(shù)名稱:Timer_Display
函數(shù)功能:把顯示緩沖區(qū)的數(shù)值顯示在數(shù)碼管上
參數(shù)介紹:cNumber:記錄for語句的循環(huán)次數(shù)
返回值: 無
注意事項(xiàng):無
///////////////////////////////////////////////////////////////////////////
void Timer_Display()
{
uchar cNumber;
for(cNumber=0;cNumber《2;cNumber++)
{
One_DigitalTube_display(uDis_buff[cNumber],cNumber);
DelayMs(2);
}
}
///////////////////////////////////////////////////////////////////////////
函數(shù)名稱:main
函數(shù)功能:利用定時器1中斷,在數(shù)碼管上實(shí)現(xiàn)以一分鐘為周期的計(jì)數(shù)器
參數(shù)介紹:無
返回值: 無
注意事項(xiàng):無
///////////////////////////////////////////////////////////////////////////
void main()
{
Init_time1(); //初始化定時器1
cTime=0;
while(1)
{
if(cTime_1s_ok)
{
cTime_1s_ok=0;
if(++cTime》=60) //每次自加一,同時判斷是否到1分鐘
{
cTime=0;
}
Time_to_disbuffer(); //新調(diào)整好的時間送入顯示緩沖區(qū)
}
Timer_Display(); //更新顯示內(nèi)容
}
}
///////////////////////////////////////////////////////////////////////////
函數(shù)名稱:Interrupt_handler_time1
函數(shù)功能:重新給寄存器TH1和TL1賦值,判斷是否到達(dá)一秒,如果到一秒了,把相應(yīng)的
變量賦予正值,以方便其他的程序編寫
參數(shù)介紹:無
返回值: 無
注意事項(xiàng):無
///////////////////////////////////////////////////////////////////////////
void Interrupt_handler_time1(void) interrupt 3
{
uchar i;
TH1=(65535-10000)/256;//定時10毫秒
TL1=(65535-10000)%6;
cTime_10ms_counter++;
if(cTime_10ms_counter==Time_1s_Sign) //判斷是否到達(dá)一秒
{
cTime_10ms_counter=0;
cTime_1s_ok=1;
}
}
STC89C52單片機(jī)定時器2詳解
自認(rèn)為單片機(jī)所有的資源中最不好搞清楚的就是定時器2,尤其是對于那些以前從來沒有玩過單片機(jī)的新手。定時器2是新增資源,也是51單片機(jī)定時器里面功能最強(qiáng)大的一個定時器。所以掌握好定時器2還是非常有必要的。以下是在我完全搞明白它的原理和用法的基礎(chǔ)上整理的一篇小文章。讀起來,好像Datasheet一樣!請?jiān)?,希望沒有辜負(fù)你的點(diǎn)擊!
定時器2是一個16位定時器/計(jì)數(shù)器,通過設(shè)置特殊功能寄存器T2CON中的C/T2位可將其設(shè)置為定時器或是計(jì)數(shù)器;通過設(shè)置T2CON中的工作模式選擇位可將定時器2設(shè)置為三種工作模式,分別為捕獲、自動重新裝載(遞增或是遞減計(jì)數(shù))和波特率發(fā)生器。
知識點(diǎn)一、定時器2的控制寄存器T2CON(可按位尋址)*
D7位--TF2:定時器2溢出標(biāo)志位。用于請求中斷(必須由軟件清0)
D6位--EXF2:定時器外部標(biāo)志位。當(dāng)外部信號使能時,發(fā)生外部負(fù)跳變時置位請求中斷(必須由軟件清0)
D5位--RCLK:接受時鐘標(biāo)志位。默認(rèn)情況下串行口中模式1和模式3的時鐘是由定時器1的溢出率提供,若該位置位,則由定時器2提供。
D4位--TCLK:發(fā)送時鐘標(biāo)志位。原理同上
D3位--EXEN2:定時器2的外部使能標(biāo)志位。定時器2沒有作為串行口時鐘時,若將該位置位時,將允許T2EX的負(fù)跳變產(chǎn)生捕獲或重裝
D2位--TR2:定時器2啟動/停止控制位。
D1位--C/T2:定時器2的定時器/計(jì)數(shù)器選擇位(在reg52頭文件中定義為了C_T2,請注意,下面相同)
D0位--CP/RL2:捕獲/重裝標(biāo)志位。
知識點(diǎn)二 ?、 ?定時器2的模式控制寄存器T2MOD(不可按位尋址)
該寄存器在單片機(jī)的頭文件reg2.h中可能沒有被定義,自己定義吧!
D1位—T2OE:定時器2輸出使能位
D0位—DCEN:向下計(jì)數(shù)使能位
知識點(diǎn)三:定時器2的三種模式*
*1、捕獲模式*
在“CP/RL2=1”&&“TR2=1”時進(jìn)入捕獲模式。通過對控制寄存器T2CON的外部使能標(biāo)志位EXEN2的置位和清0,又可以有分為如下兩種工作模式:
《1》EXEN2=0:
此時定時器2作為一個16位的定時器/計(jì)數(shù)器(由定時器/計(jì)數(shù)器選擇位C/T2位選擇)使用,實(shí)驗(yàn)已通過。
《2》EXEN2=1:
此時定時器在前者的基礎(chǔ)上,增加一個特性,即允許接受外部輸入T2CON的負(fù)跳變,此負(fù)跳變使定時器2中的TH2和TL2中的值存入陷阱寄存器RCAP2H和RCAP2L中,并將外部標(biāo)志位EXF2置位,引起中斷。該中斷與前者中的中斷同時存在并共用同一中斷程序(在中斷中可檢測TF2和T2EX位確定是哪一個引起的中斷)。除此之外該模式下,當(dāng)中斷是T2EX位引發(fā)的時,雖然引發(fā)了中斷,但是由于不是溢出,并且計(jì)數(shù)器沒有停止計(jì)數(shù),因此,此時TH2和TL2不用重新裝載值。
實(shí)驗(yàn)證明在此模式下可以實(shí)現(xiàn):用溢出中斷輸出方波,用線接入T2EX(P1^1),在T2EX的中斷中使蜂鳴器響起來,理論和實(shí)踐一樣,蜂鳴器響的頻率是方波的兩倍(因?yàn)樗徊蹲截?fù)跳變)
2、自動重裝模式(遞增/遞減計(jì)數(shù)器)*
16位自動重裝模式中,定時器2可通過C/T2位配置為定時器/計(jì)數(shù)器,根據(jù)外部使能標(biāo)志位EXEN2的置位和清0,可分為兩種情況:
《1》EXEN2=0時
定時器2為16位自動重裝的普通定時器,由陷阱寄存器提供重裝的值,只需要預(yù)設(shè)一下即可,可用于定時精度要求高,定時時間長(16位)的情況。
《2》EXEN2=1時,根據(jù)遞減計(jì)數(shù)使能位DCEN的置位和清0可分為兩種情況:
A1、T2MOD=0x00(DCEN=0;默認(rèn)情況);
與上一種情況相比,此時16位自動重新裝載可由外部T2EX的負(fù)跳變,和溢出任意一種觸發(fā),并都能產(chǎn)生中斷。
A2、T2MOD=0x01(DCEN=1);
此時允許T2EX控制計(jì)數(shù)的方向;T2EX=0時,重裝的值為0FF和0FF,遞減計(jì)數(shù)與陷阱寄存器預(yù)存值相等時,置位TF2產(chǎn)生中斷。T2EX=1時;自動重裝值為陷阱寄存器中的值,溢出時置位TF2產(chǎn)生中斷。
3、波特率發(fā)生器模式
T2CON的TCLK和RCLK位為0(默認(rèn))時,串行口發(fā)送和接受的波特率由定時器1提供;置位為1時,由定時器2提供??梢砸粋€通過定時器1,一個通過定時器2,這樣可以獲得發(fā)送和接受時不同的波特率。
注意的地方: 定時器2作為定時器時,遞增頻率為晶振頻率的12分頻,而定時器2作為波特率發(fā)生器時,它的遞增頻率為晶振頻率的2分頻。
模式1和模式3的波特率=(振蕩器頻率/32) * (65535-N)
定時器2為計(jì)數(shù)模式時,外部時鐘信號由T2(P1^0)引腳進(jìn)入。
定時器2作為波特率發(fā)生器的時候,TH2溢出并不會置位TF2,所以此時可以不用禁止定時器2中斷,若是EXEN2位被置位時,可以將T2EX作為附加的外部中斷。
定時器2作為波特率發(fā)生器的時候,不要對TH2和TL2讀寫,可以讀陷阱寄存器,但是也不要寫。當(dāng)對定時器2的陷阱寄存器進(jìn)行訪問時,應(yīng)關(guān)閉定時器(TR2清0)。
4、可編程時鐘輸出
52系列單片機(jī),可設(shè)定定時器/計(jì)數(shù)器2通過T2(p1^0)引腳輸出時鐘。
P1^0除了可以作為普通I/O口外,還可以作為定時器2的外部計(jì)數(shù)輸入和時鐘信號輸出。
C/T2=0并且T2MOD的T2OE位為1時,可將定時器2選為時鐘信號發(fā)生器,自動裝初值。設(shè)置公式:
時鐘信號輸出頻率=(振蕩器頻率/4)* (65535-N)
在時鐘輸出模式下,計(jì)數(shù)器溢出不會產(chǎn)生中斷請求。這種功能相當(dāng)于定時器2可同時作為波特率發(fā)生器和時鐘發(fā)生器。
**因?yàn)榇藭r外部中斷并沒有被暫用,若是在設(shè)置上不沖突的話可能同時還可以響應(yīng)T2EX引入的外部信號,這個只是猜想,還沒有用實(shí)驗(yàn)證明過,哈哈***
? ? ?單片機(jī)對于外來脈沖信號具有計(jì)數(shù)功能,但是有要求:
計(jì)數(shù)脈沖的最高頻率=振蕩器的頻率/24
并且為了確保給定電平在電平變化之前能被采樣一次,則這個電平至少要維持一個機(jī)器周期。
STC89C52單片機(jī)的定時器2的實(shí)現(xiàn)時鐘的程序
////////////////////////////////////////////////////////////////////////
實(shí)現(xiàn)功能: 配置定時器2的相關(guān)寄存器,使其實(shí)現(xiàn)定時器中斷功能,然后根據(jù)中斷
的周期頻率實(shí)現(xiàn)準(zhǔn)確的時鐘系統(tǒng),在數(shù)碼管上顯示實(shí)現(xiàn)
實(shí)驗(yàn)板型號:BS-XYD-C52
實(shí)驗(yàn)名稱: 定時器2實(shí)現(xiàn)時鐘系統(tǒng)
/////////////////////////////////////////////////////////////////////////
#include《reg52.h》
#define uchar unsigned char //定義unsigned char 為 uchar
#define uint unsigned int //定義unsigned int 為 uint
uchar cTime_10ms_counter; //中斷次數(shù)計(jì)數(shù)單元
uchar cTime_1s_ok; //判斷是否為1s的變量
uchar uDis_buff[6]; //顯示緩沖區(qū),存放要顯示的6個字符的段碼值
uchar cTime[3]; //時、分、秒計(jì)數(shù)單元
#define Time_1s_Sign 100 //根據(jù)中斷周期,判斷是否到一秒的標(biāo)志
sbit led=P1^0;
sbit Duan=P2^6; //定義數(shù)碼管的段選使能端
sbit Wei =P2^7; //定義數(shù)碼管的位選使能端
#define Digital_tube_Wei_Enable Wei=1; //開啟控制數(shù)碼管的位選使能端
#define Digital_tube_Wei_Disable Wei=0; //關(guān)閉控制數(shù)碼管的位選使能端
#define Digital_tube_Duan_Enable Duan=1; //開啟控制數(shù)碼管的段選使能端
#define Digital_tube_Duan_Disable Duan=0; //關(guān)閉控制數(shù)碼管的段選使能端
#define Digital_tube_Duan P0 //定義數(shù)碼管數(shù)據(jù)端口
uchar code Dis_table[]= //將BCD碼轉(zhuǎn)換成數(shù)碼管掃描碼的數(shù)組
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};
uchar code Dis_Position[]= //定義數(shù)碼管位選的數(shù)組
{0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
/////////////////////////////////////////////////////////////////////////
函數(shù)名稱:毫秒延時函數(shù)
函數(shù)功能:實(shí)現(xiàn)毫秒級的延時
參數(shù)介紹:Delay_MS: 定義需要延時的毫秒的數(shù)值
iNumber: 記錄Delay_MS的數(shù)值,以for語句實(shí)現(xiàn)所要求的延時
iValue: 要延時毫秒所要進(jìn)行的循環(huán)數(shù)值,本數(shù)值為實(shí)際測得
返回值: 無
注意事項(xiàng):本實(shí)驗(yàn)是在所用晶振為12M的前提下實(shí)現(xiàn)的毫秒延時,本函數(shù)是通過循環(huán)的形
式完成,所以如果改變了晶振的頻率,請做相應(yīng)的改變
/////////////////////////////////////////////////////////////////////////
void DelayMs(uint Delay_MS)
{
uint iNumber,iValue;
for(iNumber=0;iNumber《Delay_MS;iNumber++) //用for語句實(shí)現(xiàn)單片機(jī)的延時
{
iValue=107; //107這個數(shù)值是通過測定而得
while(iValue--);
}
}
/////////////////////////////////////////////////////////////////////////
函數(shù)名稱:One_DigitalTube_display
函數(shù)功能:完成在實(shí)驗(yàn)板上數(shù)碼管指定顯示,即在特定的數(shù)碼管上顯示特定的數(shù)字,比
在第一個數(shù)碼管上顯示0
參數(shù)介紹:cData:要顯示的數(shù)字的BCD碼數(shù)組
cNumber:選擇哪個數(shù)碼管顯示,即讓某個特定數(shù)碼管顯示
返回值: 無
注意事項(xiàng):實(shí)驗(yàn)板上的數(shù)碼管是共陰極的數(shù)碼管,如果使用共陽極的數(shù)碼管,請注意不
要弄反了
/////////////////////////////////////////////////////////////////////////
void One_DigitalTube_display(uchar cData,uchar cNumber)
{
Digital_tube_Duan_Enable; //使能數(shù)碼管的段選
Digital_tube_Duan=Dis_table[cData];//輸入所要顯示的數(shù)值
Digital_tube_Duan_Disable; //關(guān)閉數(shù)碼管的段選
Digital_tube_Wei_Enable; //使能數(shù)碼管的位選
Digital_tube_Duan=Dis_Position[cNumber]; //點(diǎn)亮特定的數(shù)碼管的公共端
Digital_tube_Wei_Disable; //關(guān)閉數(shù)碼管的位選
DelayMs(1); //調(diào)整時序,以實(shí)現(xiàn)穩(wěn)定顯示
}
/////////////////////////////////////////////////////////////////////////
函數(shù)名稱:Time_to_disbuffer
函數(shù)功能:把要在數(shù)碼管上顯示的數(shù)值,進(jìn)行取余、取整,即對數(shù)值進(jìn)行分割,這樣以
便顯示在分離的數(shù)碼管
參數(shù)介紹:cNumber1: 記錄時、分、秒計(jì)數(shù)單元數(shù)組的變量
cNumber2:記錄顯示緩沖區(qū)數(shù)組的變量
返回值: 無
注意事項(xiàng):無
/////////////////////////////////////////////////////////////////////////
void Time_to_disbuffer()
{
uchar cNumber1,cNumber2=0;
for(cNumber1=0;cNumber1《=2;cNumber1++)
{
uDis_buff[cNumber2++]=cTime[cNumber1]/10; //對cTime的數(shù)值取整,即
//就是取cTime的十位
uDis_buff[cNumber2++]=cTime[cNumber1]; //對cTime的數(shù)值取余,即
//就是取cTime的個位
}
}
/////////////////////////////////////////////////////////////////////////
函數(shù)名稱:Init_time2
函數(shù)功能:配置定時器2,配置的模式是定時器1采用16位定時器模式,在定時器1的輸入
數(shù)值寄存器輸入特定的數(shù)值,使其每次中斷的周期為10ms,同時允許定時器1
中斷,并打開總中斷
參數(shù)介紹:無
返回值: 無
注意事項(xiàng):無
/////////////////////////////////////////////////////////////////////////
void Init_time1(void)
{
TH2=(65535-10000)/256;
TL2=(65535-10000)%6; //定時器0的,寫入數(shù)值寄存器的低8位
EA=1; //總中斷打開
ET2=1; //定時器T0允許中斷
TR2=1; //定時器T0開始工作
}
/////////////////////////////////////////////////////////////////////////
函數(shù)名稱:Timer_Display
函數(shù)功能:把顯示緩沖區(qū)的數(shù)值顯示在數(shù)碼管上
參數(shù)介紹:cNumber:記錄for語句的循環(huán)次數(shù)
返回值: 無
注意事項(xiàng):無
/////////////////////////////////////////////////////////////////////////
void Timer_Display()
{
uchar cNumber;
for(cNumber=0;cNumber《6;cNumber++)
{
One_DigitalTube_display(uDis_buff[cNumber],cNumber);
if(cNumber==1|cNumber==3)
{
Digital_tube_Duan_Enable; //使能數(shù)碼管的段選
Digital_tube_Duan=0x80; //輸入所要顯示的數(shù)值
Digital_tube_Duan_Disable; //關(guān)閉數(shù)碼管的段選
Digital_tube_Wei_Enable; //使能數(shù)碼管的位選
Digital_tube_Duan=Dis_Position[cNumber]; //點(diǎn)亮特定的數(shù)碼管的公共端
Digital_tube_Wei_Disable; //關(guān)閉數(shù)碼管的位選
DelayMs(1);
}
}
}
/////////////////////////////////////////////////////////////////////////
函數(shù)名稱:main
函數(shù)功能:利用定時器2中斷,實(shí)現(xiàn)準(zhǔn)確的時鐘系統(tǒng),然后在數(shù)碼管上顯示實(shí)現(xiàn)
參數(shù)介紹:無
返回值: 無
注意事項(xiàng):無
/////////////////////////////////////////////////////////////////////////
void main()
{
Init_time1(); //初始化定時器1
cTime[0]=23,cTime[1]=58,cTime[2]=58;
Time_to_disbuffer(); //把預(yù)設(shè)時間送入顯示緩沖區(qū)
while(1)
{
if(cTime_1s_ok) //判斷是否到1秒了
{
cTime_1s_ok=0;
if(++cTime[2]》=60) //每次自加一,同時判斷是否到1分鐘
{
cTime[2]=0;
if(++cTime[1]》=60) //每次自加一,同時判斷是否到1小時了
{
cTime[1]=0;
if(++cTime[0]》=24) //每次自加一,同時判斷是否到24點(diǎn)了
{
cTime[0]=0;
}
}
}
Time_to_disbuffer(); //新調(diào)整好的時間送入顯示緩沖區(qū)
}
Timer_Display(); //更新顯示內(nèi)容
}
}
/////////////////////////////////////////////////////////////////////////
函數(shù)名稱:Interrupt_handler_time2
函數(shù)功能:重新給寄存器TH2和TL2賦值,判斷是否到達(dá)一秒,如果到一秒了,把相應(yīng)的
變量賦予正值,以方便其他的程序編寫
參數(shù)介紹:無
返回值: 無
注意事項(xiàng):無
/////////////////////////////////////////////////////////////////////////
void Interrupt_handler_time2(void) interrupt 5
{
TF2=0;
TH2=(65535-10000)/256;//定時10毫秒
TL2=(65535-10000)%6;
cTime_10ms_counter++;
if(cTime_10ms_counter==Time_1s_Sign) //判斷是否到達(dá)一秒
{
cTime_10ms_counter=0;
cTime_1s_ok=1;
}
}
STC單片機(jī)STC89C52RC定時器延時時間的計(jì)算
延時時間要根據(jù)晶振頻率計(jì)算,不同板子可能有所不同。
時鐘周期:
1/時鐘源,在我現(xiàn)在這塊板子上,晶振頻率是11.0592M,也就是時鐘周期是 1/11059200秒
機(jī)器周期:
一般51單片機(jī)是12個時鐘周期,我的板子也就是 12/11059200秒
單次定時最長時間:
如果是16位的計(jì)數(shù)器,16位最大值是65535,共可計(jì)數(shù)65536次?;镜某?shù)一定要記住,還要記住8位最大值是255,共可計(jì)數(shù)256次,還要記住8位上每位代表的數(shù)值。
12 * 65536/11059200 = 0.0711 s,也就是,71 ms內(nèi)的定時可以單次定時就完成。如果定時時間超過71 ms,就要循環(huán)了。
一次定時需要幾次機(jī)器周期:
計(jì)算公式:定時秒數(shù)/機(jī)器周期
比 如我要定時1秒, 1/(12/11059200)= 921600次,16位計(jì)數(shù)器最大可計(jì)數(shù)65536次,921600次早就益出了。我們可以每次定時10 ms,循環(huán)100次就可以定時1秒了,1 s縮小100百倍就是10 ms, 也就是每次需要計(jì)數(shù)9216次。
確實(shí)計(jì)數(shù)器初始值:
定時10 ms時,如果計(jì)數(shù)器從0開始計(jì)數(shù),我們就不知道什么時候到了9216次。所以應(yīng)該計(jì)數(shù)了9216次,16位計(jì)數(shù)器最多計(jì)數(shù)95536次,然后就溢出,一溢出TCON的TF位就會置1,我們只要經(jīng)常檢測TF位就可以知道什么時候完成10ms的定時了。
計(jì)算公式:計(jì)數(shù)器初始值=最大計(jì)數(shù)次數(shù) - 需要計(jì)數(shù)次數(shù)
如果定時10 ms,計(jì)數(shù)器的初始值就是 65536 - 9216
計(jì)算計(jì)數(shù)器的高位和低位:
16位的計(jì)數(shù)器,也就是兩個8位組成,8位的最大計(jì)數(shù)次數(shù)是256。所以:
計(jì)數(shù)器高位 = 初始值/256
計(jì)數(shù)器低位 = 初始值%256
STC89C52RC單片機(jī)定時器示例代碼:
#include 《reg52.h》
//如果你的單片機(jī)沒用74hc138擴(kuò)展IO口,下面代碼可略
sbit enableG1 = P1^3;
sbit enableG2 = P1^4;
sbit selectC = P1^2;
sbit selectB = P1^1;
sbit selectA = P1^0;
void hc138()
{
enableG1 = 1;
enableG2 = 0;
selectC = 1;
selectB = 1;
selectA = 0;
}
typedef unsigned char uint8;
typedef unsigned int uint16;
/**
1ms需要的機(jī)器周期 = 0.001/(12/11059200) = 921.6
要讓led燈以7.83hz閃動, 周期是 1000 / 7.83 = 127.713 ms, 也就是每64 ms改變亮滅狀態(tài)
**/
void main(void)
{
uint16 counter;
hc138();
TMOD = 0X01;
TH0 = (65536 - 922) / 256;
TL0 = (65536 - 922) % 256;
TR0 =1;
while(1)
{
if(TF0 == 1)
{
TF0 = 0;
TH0 = (65536 - 922) / 256;
TL0 = (65536 - 922) % 256;
counter++;
}
if(counter == 64)
{
counter = 0;
P0 = ~P0;
}
}
}
電子發(fā)燒友App



















評論