1. 單片機常用的三種定時方法
1 方法1
在定時器溢出中斷得到響應時,停止定時器計數,讀出計數值(反映了中斷響應的延遲時間),根據此計數值算出到下一次中斷時,需多長時間,由此來重裝載和啟動定時器。例如定時周期為1ms,則通常定時器重裝載值為-1000(0FC18H)。下面的程序在計算每個定時周期的精確重裝載值時,考慮了由停止計數(CLR TR1)到重新啟動計數(SETB TR1)之間的7個機器周期時間。程序中#LOW(-1000+7)和#HIGH(-1000+7)是匯編符號,分別表示-1000+7=0FC1FH這個立即數的低位位元組(1FH)和高位位元組(0FCH)。
……
CLR EA ;禁止所有中斷
CLR TR1 ;停止定時器T1
MOV A,#LOW(-1000+7) ;期望數的低位位元組
ADD A,TL1 ;進行修正
MOV TL1,A ;重裝載低位位元組
MOV A,#HIGH(-1000+7) ;對高位位元組處理
ADDC A,TH1
MOV TH1,A
SETB TR1 ;重啟動定時器
SETB EA ;重開中斷
……
此方法適用於各種原因造成的定時誤差的情況,為通用方法。
2 方法2
假如定時周期為10ms,通常定時器重裝載值為0D8F0H,中斷子程序如下[2]:
ORL TL1,#0F0H
MOV TH1,#0D8H
……
這里用ORL TL1,#0F0H代替MOV TL1,#0F0H 可提高定時精度。此方法只適用於重裝載值低位位元組的低4位為零,且中斷響應的延遲時間小於16個機器周期的情況。類似的定時器重裝載值有0FFF0H,0FFE0H等。
3 方法3
假如定時周期為1ms,通常定時器重裝載值為0FC18H,中斷子程序如下:
MOV A,#LOW(-1000+4) ;期望數的低位位元組
ADD A,TL1
MOV TL1,A
MOV A,#HIGH(-1000+4) ;對高位位元組處理
ADDC A,TH1
MOV TH1,A
DEC TL1 ;恢復提前了的2個機器周期
……
這種方法中不停止定時器計數過程,若在執行指令ADDC A,TH1 或MOV TH1,A時,恰好產生TL1溢出向TH1進位的情況,則TH1的值就不對了,會產生更大的誤差。為此,程序段開頭為重裝載值加4,若有溢出進位,則可提前發生,其中2個機器周期是考慮到為TL1重裝載佔用的時間。
此方法適用於系統中無其它更高優先順序中斷源的情況。若類似方法1,在程序段開頭和結尾分別加上禁止所有中斷(CLR EA)和開中斷(SETB EA)指令,則將適用於所有情況。
4 方法4
假如定時周期不確定,只知道定時器重裝載值存放在寄存器R3、R2中,中斷子程序如下:
MOV A,#05H ;3個機器周期裝載TL1,2個周期提前
ADD A,TL1
ADD A,R2
MOV TL1,A
MOV A,R3 ;處理高位位元組
ADDC A,TH1
MOV TH1,A
DEC TL1 ;恢復提前了的2個機器周期
……
此法適用於定時周期不確定的情況,其它同方法3。
5 方法5
當定時中斷發生的位置可預知時,通常出現在主程序的AJMP $ (或SJMP $)等待指令處,中斷延遲時間為3個或4個機器周期。取固定值4可簡化補償程序。以定時周期1ms為例,中斷子程序如下:
ORG 001BH
MOV TL1,#LOW(-1000+4)
MOV TH1,#HIGH(-1000+4)
……
此方法適用於定時中斷總發生在同一條指令位置,且無其它中斷源的情況。
結 語
上述5種方法誤差均不超過1個機器周期,其中方法1、3、4較為通用,適用於任何情況,但程序較長;方法2、5簡單,但必須注意滿足對應條件,才能使用。當然,也還有其它方法[3],但比較煩瑣,並不理想,這里不一一介紹。
2. C51單片機定時器1以方式1定時1秒如何設置
1、先打開我們熟悉的單片機c51編程軟體——keil,先把主方法寫好。
3. 51單片機指令
TF1是定時器1溢出標志位,$是取地址。JNB TF1,$ 實現的功能是查詢定時器1溢出標志位,如果為0,跳轉到本條指令繼續執行(即繼續查詢)直到定時時間到,TF1置位,才執行下一條指令。
給你注釋一下:
MOV TMOD,#10H //設置定時器工作方式(定時器1,工作方式2)
SETB TR1 //開啟定時器1
LOOP: MOV TH1,#0D8H //裝初值D8F0H 即55536,定時10mS(晶振12M)時間隨晶振改變
MOV TL1,#0F0H
JNB TF1,$ //查詢等待定時器1中斷
CLR TF1 //定時器溢出標志位清0(定時時間到後硬體自動給TF1置位,需軟體清0)
CPL P1.1 //P1.1取反
SJMP LOOP //跳到LOOP處循環(是個死循環)
該段程序實現的功能是:每隔10mS對P1.1取反一次。(10mS當然是晶振為12M的情況下)
4. 單片機怎麼實現5秒的定時
定時之前、定時完畢,都干什麼呀?
下面就是定時 5 秒(fosc = 6MHz)的鬧巧完整程尺腔序。
DL5S()
{
unsigned char t = 0;
TMOD = 0X01;
TR0 = 1;
while(t < 200) {
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
while(TF0 == 0);
TF0 = 0;
t++;
}
}
-----
用匯編語言,就很簡單了。
下面就是定時 5 秒(fosc = 6MHz)的完整陵彎衫程序。
DL5S:
MOV TMOD, #01H
SETB TR0
MOV R2, #200
D_LOOP:
MOV TH0, #HIGH(65536 - 50000)
MOV TL0, #LOW(65536 - 50000)
JNB TF0, $
CLR TF0
DJNZ R2, D_LOOP
RET
END