計數(shù)器是按機器周期算的
成都創(chuàng)新互聯(lián)專注骨干網(wǎng)絡服務器租用10年,服務更有保障!服務器租用,達州電信機房 成都服務器租用,成都服務器托管,骨干網(wǎng)絡帶寬,享受低延遲,高速訪問。靈活、實現(xiàn)低成本的共享或公網(wǎng)數(shù)據(jù)中心高速帶寬的專屬高性能服務器。
一個機器周期=12時鐘周期
不管時鐘多少,都按一個機器周期=12時鐘周期計算 //**** 關鍵 ****//
12MHZ時鐘換過來就是1M機器周期(1M/S)
1ms就是1000機器周期;
6MHZ時鐘換過來就是0.5M機器周期(0.5M/S)
1ms就是500機器周期
8位計數(shù)器最高范圍是65536,
如果我們要記時1s,可以以10ms為單位,循環(huán)記時100次
現(xiàn)在就是初始化,10ms為例
TL0=-10000; //對T0計數(shù)初始化賦值,用12M的JT,10ms也就是機器周期計數(shù)10000
TH0=-100008;
這就是初始化,一次溢出10ms
(若用6M的JT,10ms也就是機器周期計數(shù)5000)
當然這只是其中一部分,具體還有比如TR0(1)的設置
溢出中斷允許等!
上面兩句等價于
TL0=55536;//(65536-10000)
TH0=555368;
相當于從55536開始數(shù),
數(shù)10000次(10ms)后溢出,為一個記數(shù)周期
100次后就是1s
上述過程是在中斷服務程序中的
上面的內(nèi)容不知道對你有沒有用~~(網(wǎng)上找的)
用中斷,定時器工作方式1,計數(shù)最大數(shù)為65536,那么從15536開始計數(shù),達到65536要計50000次,6M的晶振機器周期為2微秒,那么溢出一次耗時為100000微秒,計數(shù)溢出10次即為1秒鐘
ORG 000BH
AJMP TIME0
ORG 30H
MAIN:
MOV 30H,#00H;先把30H地址的數(shù)據(jù)清零,用做給溢出計數(shù)用
MOV TMOD,#00000001B
MOV TH0,#3CH
MOV TL0,#0B0H
SETB EA
SETB ET0
SETB TR0
LOOP:AJMP LOOP
TIME0:PUSH ACC
PUSH PSW
INC 30H;進入中斷后就自增
MOV A,30H
CJNE A,#10,T_RET;看計數(shù)器的溢出到了10次沒,沒有就跳到T_RET再繼續(xù)從15536計數(shù)
T_L1:延時1秒到了,寫自己的程序吧。
MOV 30H,#00H;記得把溢出計數(shù)器再次清零
T_RET:MOV TH0,#3CH
MOV TL0,#0B0H
POP PSW
POP ACC
RETI
END
延時有很多種方法,有一種是讓單片機去做無聊的循環(huán),
還有一種是用定時器。
我本身也是菜鳥所以只能粗略的講一下。
第一種的算法是
晶振的周期T1=1/f; 這里f=6MHz 所以T1=1/6 us;(微秒)
單片機花12個T1去執(zhí)行一個指令,
所以一個機器周期等于12個晶振周期,
T2=12*T1=2us
10ms=1000 0us
所以你要得到10ms的延時就要想辦法讓機器去做5000條“無聊的指令”
所以
DEL: MOV R5,#05H
F1: MOV R6,#05H
F2: MOV R7,#32H
F3: DJNZ R7,F3
DJNZ R6,F2
DJNZ R5,F1
RET
這種方法是用于對時間要求不高的地方,我說的是其思想,程序中可能有錯的地方
用定時器的方法我不太會就不誤人了 (補充一下就是這個是用匯編寫的,你在主程序中用ACALL DEL調(diào)用就延時了。
通過調(diào)用這個子程序就可以實現(xiàn)
DEL1S: MOV R1,#10
DEL1: MOV R2,#100
DEL2: MOV R3,#250
DEL3: DJNZ R3,DEL3 ;2*2*250*100*10=1000000us
DJNZ R2,DEL2
DJNZ R1,DEL1
RET
沒有做具體計算,要準確的定時1s的話可以稍微改動一下R1R2R3的值。6M晶振則機器周期為2us,一條指令執(zhí)行為2個機器周期,由此得出其延時時間
最好的方式是使用定時器中斷來做延時,更精確
C語言軟件延時一般用for循環(huán)或while循環(huán):
void delay(unsigned int data)
{
unsigned int i, j;
for(i=data; i!=0; i--)
for(j=1000; j!=0; j--);
}
void delay(unsigned int data)
{
unsigned int i, j;
i=data;
while(i--)
for(j=1000; j!=0; j--);
}
不同的單片機指令周期不太一樣,
想精確延時200ms,最好用protue軟件仿真一下,或者自己也可以在開發(fā)環(huán)境中利用斷點調(diào)試。
PS:用定時器是最好的方法。
6M晶振,方式2定時1mS的時間太長,不能直接實現(xiàn),(最大定時應該是512uS)下面是500uS定時示例程序,可在中斷函數(shù)中計數(shù)每2次得1S。
void Timer1Init(void) //500微秒@6.000MHz
{
AUXR = 0xBF; //定時器時鐘12T模式
TMOD = 0x0F; //設置定時器模式
TMOD |= 0x20; //設置定時器模式
TL1 = 0x06; //設置定時初值
TH1 = 0x06; //設置定時重載值
TF1 = 0; //清除TF1標志
TR1 = 1; //定時器1開始計時
}