一、實驗任務
用 AT89S51 單片機的定時/計數器 T0 産生一秒的定時時間,作為秒計數時間,當一秒産生時,秒計數加 1,秒計數到 60 時,自動從 0 開始。硬體電路如下圖所示
二、電路原理圖
圖 4.15.1
三、系統闆上硬體連線
(1. 把“單片機系統”區域中的 P0.0/AD0-P0.7/AD7 端口用 8 芯排線連接配接到“四路靜态數位顯示子產品”區域中的任一個 a-h 端 口 上 ;要求 :P0.0/AD0對應着 a,P0.1/AD1 對應着 b,……,P0.7/AD7 對應着 h。
(2. 把“單片機系統”區域中的 P2.0/A8-P2.7/A15 端口用 8 芯排線連接配接到“四路靜态數位顯示子產品”區域中的任一個 a-h 端口上;要求:P2.0/A8 對應着 a,P2.1/A9 對應着 b,……,P2.7/A15 對應着h。
四、程式設計内容
AT89S51 單片機的内部 16 位定時/計數器是一個可程式設計定時/計數器,它既可以工作在 13 位定時方式,也可以工作在 16 位定時方式和 8 位定時方式。隻要通過設定特殊功能寄存器 TMOD,即可完成。定時/計數器何時工作也是通過軟體來設定 TCON 特殊功能寄存器來完成的。現在我們選擇 16 位定時工作方式,對于 T0 來說,最大定時也隻有 65536us,即 65.536ms,無法達到我們所需要的 1 秒的定時,是以,我們必須通過軟體來處理這個問題,假設我們取 T0 的最大定時為 50ms,即要定時 1 秒需要經過 20次的 50ms 的定時。對于這 20 次我們就可以采用軟體的方法來統計了。是以,我們設定 TMOD=00000001B,即 TMOD=01H下面我們要給 T0 定時/計數器的 TH0,TL0 裝入預置初值,通過下面的公式可以計算出
TH0=(216-50000)
/
256
256
TL0=(216-50000) MOD
當 T0 在工作的時候,我們如何得知 50ms 的定時時間已到,這回我們通過檢
測 TCON 特殊功能寄存器中的 TF0 标志位,如果 TF0=1 表示定時時間已到。
五、程式框圖
圖 4.15.2
六、彙編源程式(查詢法)
SECOND EQU 30H
TCOUNT EQU 31H
ORG 00H
START: MOV SECOND,#00H
MOV TCOUNT,#00H
MOV TMOD,#01H
MOV TH0,#(65536-50000) / 256
MOV TL0,#(65536-50000) MOD 256
SETB TR0
DISP: MOV A,SECOND
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
WAIT: JNB TF0,WAIT
CLR TF0
MOV TH0,#(65536-50000) / 256
MOV TL0,#(65536-50000) MOD 256
INC TCOUNT
MOV A,TCOUNT
CJNE A,#20,NEXT
MOV TCOUNT,#00H
INC SECOND
MOV A,SECOND
CJNE A,#60,NEX
MOV SECOND,#00H
NEX: LJMP DISP
NEXT: LJMP WAIT
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
七、C 語言源程式(查詢法)
#include
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
unsigned char second;
unsigned char tcount;
void main(void)
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
tcount=0;
second=0;
P0=dispcode[second/10];
P2=dispcode[second%10];
while(1)
{
if(TF0==1)
{
tcount++;
if(tcount==20)
{
tcount=0;
second++;
if(second==60)
{
second=0;
}
P0=dispcode[second/10];
P2=dispcode[second%10];
}
TF0=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
}
}
1. 彙編源程式(中斷法)
SECOND EQU 30H
TCOUNT EQU 31H
ORG 00H
LJMP START
ORG 0BH
LJMP INT0X
START: MOV SECOND,#00H
MOV A,SECOND
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
MOV TCOUNT,#00H
MOV TMOD,#01H
MOV TH0,#(65536-50000)
MOV TL0,#(65536-50000)
SETB TR0
SETB ET0
SETB EA
SJMP $
INT0X:
MOV TH0,#(65536-50000)
MOV TL0,#(65536-50000)
INC TCOUNT
MOV A,TCOUNT
CJNE A,#20,NEXT
MOV TCOUNT,#00H
INC SECOND
MOV A,SECOND
CJNE A,#60,NEX
MOV SECOND,#00H
NEX: MOV A,SECOND
MOV B,#10
DIV AB
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
NEXT: RETI
/ 256
MOD 256
/ 256
MOD 256
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
2. C 語言源程式(中斷法)
#include
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
unsigned char second;
unsigned char tcount;
void main(void)
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
ET0=1;
EA=1;
tcount=0;
second=0;
P0=dispcode[second/10];
P2=dispcode[second%10];
while(1);
}
void t0(void) interrupt 1 using 0
{
tcount++;
if(tcount==20)
{
tcount=0;
second++;
if(second==60)
{
second=0;
}
P0=dispcode[second/10];
P2=dispcode[second%10];
}
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}閱讀本文用了:
分
秒,轉發隻需1秒
❀轉載是一種智慧❀分享是一種美德❀