新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī)T0做精確時(shí)鐘

51單片機(jī)T0做精確時(shí)鐘

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
T0精確時(shí)鐘,為了做到盡量精確,必須減少中斷的次數(shù),所以選擇使用方式1,它最多可以計(jì)數(shù)65536次。但是,方式1中斷后需要重新給定時(shí)器賦初值,這樣就要耽誤幾個(gè)機(jī)器周期,很難保證時(shí)鐘的精確。

有兩個(gè)方法可以解決這個(gè)問(wèn)題。

本文引用地址:http://butianyuan.cn/article/201611/318363.htm

第一個(gè)方法:你可以計(jì)算出中斷處理時(shí)重新給定時(shí)器賦初值所用的機(jī)器周期數(shù),在你計(jì)算出的初值里除去這幾個(gè)機(jī)器周期,作為補(bǔ)償。這個(gè)方法,只是在每次定時(shí)器中斷后,都可以按時(shí)得到執(zhí)行時(shí)很精確,但事實(shí)上中斷什么時(shí)候執(zhí)行誰(shuí)都說(shuō)不準(zhǔn),所以這個(gè)方法,只能做到盡量精確。

第二個(gè)方法:計(jì)算出一個(gè)湊巧的初值,使TL0正好等于0x00,這樣每次中斷溢出后,TL0都從0x00開(kāi)始計(jì)數(shù),即使中斷沒(méi)有得到執(zhí)行,TL0也會(huì)繼續(xù)計(jì)數(shù)。利用這一點(diǎn),在中斷處理函數(shù)中,只需要對(duì)TH0重新賦值,不需要管TL0。以下是示例程序:

//定時(shí)器T0時(shí)鐘參數(shù)

unsigned char T0_S = 0;//秒

unsigned char T0_M = 0;//分

unsigned char T0_H = 0;//時(shí)

unsigned char T0_Cycle = 0;//循環(huán)次數(shù)

//本程序所用晶振22.1184MHz,每次定時(shí)25ms,循環(huán)40次正好1s。

void Timer0_Init(void)//T0初始化函數(shù)

{

TMOD = 0x01;//設(shè)置T0工作方式1

TH0= 0x4c;//(65536-46080)/256,設(shè)置初值46080,晶振22.1184MHz,

//每個(gè)機(jī)器周期0.5425微秒,定時(shí)25ms

TL0= 0x00;//(65536-46080)%256,TL0恰好=0x00

IE|= 0x82;//開(kāi)中斷

TR0= 1 ;//T0開(kāi)始定時(shí)

}

//

void Timer0(void) interrupt 1

{

TH0= 0x4c;//重新給TH0賦值

//TL0= 0x00;//不對(duì)TL0賦值,讓其繼續(xù)計(jì)數(shù)

TF0= 0 ;//定時(shí)溢出清0

T0_Cycle ++ ;

if(T0_Cycle == 40)//循環(huán)40次,每次25ms,定時(shí)1s

{

T0_Cycle = 0 ;

T0_S++ ;

if(T0_S == 60)

{

T0_S = 0;

T0_M++;

if(T0_M == 60)

{

T0_M = 0;

T0_H++;

if(T0_H == 24)

{

T0_H = 0;

}

}

}

}

}

以上程序即使T0中斷賦初值會(huì)耽誤幾個(gè)機(jī)器周期,中斷沒(méi)有得到及時(shí)執(zhí)行也沒(méi)有關(guān)系,因?yàn)門(mén)L0的計(jì)數(shù)不受影響。但有一種情況必須要注意,雖然這種情況發(fā)生的可能性不大。如果T0中斷長(zhǎng)時(shí)間沒(méi)有得到響應(yīng),TL0再一次溢出了,這時(shí)這種方法的誤差就大了。

經(jīng)過(guò)測(cè)試,第二種方法還是比較精確的,時(shí)鐘跑了一天快了10s,這個(gè)誤差應(yīng)該是晶振本身的問(wèn)題,如果是定時(shí)器的問(wèn)題,應(yīng)該是慢了,不會(huì)快了。



評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉