at89s51.c

来自「35个51单片机使用的c51程序」· C语言 代码 · 共 3,134 行 · 第 1/5 页

C
3,134
字号
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 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 72 - 
NEXT: LJMP WAIT 
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH 
END 
7. 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; 
} 
} 
} 
8. 汇编源程序(中断法) 
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) / 256 
MOV TL0,#(65536-50000) MOD 256 
SETB TR0 
SETB ET0 
SETB EA 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 73 - 
SJMP $ 
INT0X: 
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: 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 
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH 
END 
9. 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; 
} 

AT89S51I /'? ZZZVXSHUPFXFRP
- 74 - 
16 n AuD< 7 0n h*üT~' 
U O *―
*üAT89S51,Xn /AuD 0.2/ ,XEó)[K & ¨V!8~) ~0.2/ ,XK & Eó)[3+n /AuDU *dC )5-

U 2*4fi- %E3 
~ ^)(2ˇ4 ,XP1.0 P1.3*ü―4 E y C^ 'U1u / + ,XL1 
L4 
U /: @í@―? 
~1 +bG *ü 9' ¨?!8¨ b $d NOW,X 9 ¨ bn /AuD AEu/ c~
:m"4 $d/ c V / 
ORG00H 
LJMPSTART 
ORG0BH ;n /AuDLJMP INT_T0 
START: NOP ;/ c 
. 
. 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 75 - 
INT_T0: PUSH ACC ;定时/计数器T0中断服务程序 
PUSH PSW 
. 
. 
POP PSW 
POP ACC 
RETI ;中断服务程序返回 
END 
(2. 定时2秒,采用16位定时50ms,共定时40次才可达到2秒,每50ms产生一中断,定时的
40次数在中断服务程序中完成,同样0.2秒的定时,需要4次才可达到0.2秒.对于中断程序,
在主程序中要对中断开中断. 
(3. 由于每次2秒定时到时,L1-L4要交替闪烁.采用ID来号来识别.当ID=0时,L1在闪烁,
当ID=1时,L2在闪烁;当ID=2时,L3在闪烁;当ID=3时,L4在闪烁 
5. 程序框图 
T0中断服务程序框图 
主程序框图 
开 始 
Count2S=0,Cnt02S=0,ID=0
TMOD=01H,TH0,TL0装入定时初值
TR0=1,ET0=1,EA=1
等待中断 
T0中断入口
Count2S加1 
Count2S=40吗 
Count2S=0
ID加1 
ID=4吗 
ID=0 
Cnt02S加1 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 76 - 
图4.16.2 

6. 汇编源程序 
TCOUNT2S EQU 30H 
TCNT02S EQU 31H 
ID EQU 32H 
ORG 00H 
LJMP START 
ORG 0BH 
LJMP INT_T0 
START: MOV TCOUNT2S,#00H 
MOV TCNT02S,#00H 
MOV ID,#00H 
MOV TMOD,#01H 
MOV TH0,#(65536-50000) / 256 
MOV TL0,#(65536-50000) MOD 256 
SETB TR0 
SETB ET0 
SETB EA 
SJMP $ 
INT_T0: MOV TH0,#(65536-50000) / 256 
MOV TL0,#(65536-50000) MOD 256 
INC TCOUNT2S 
MOV A,TCOUNT2S 
CJNE A,#40,NEXT 
MOV TCOUNT2S,#00H 
INC ID 
MOV A,ID 
CJNE A,#04H,NEXT 
MOV ID,#00H 
NEXT: INC TCNT02S 
MOV A,TCNT02S 
CJNE A,#4,DONE 
MOV TCNT02S,#00H 
MOV A,ID 
CJNE A,#00H,SID1 
CPL P1.0 
SJMP DONE 
SID1: CJNE A,#01H,SID2 
CPL P1.1 
Cnt02S=4吗 
Cnt02S=0 
ID=0 ID=1 ID=2 ID=3 
L1闪烁 L2闪烁 L3闪烁 L4闪烁 
中断返回 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 77 - 
SJMP DONE 
SID2: CJNE A,#02H,SID3 
CPL P1.2 
SJMP DONE 
SID3: CJNE A,#03H,SID4 
CPL P1.3 
SID4: SJMP DONE 
DONE: RETI 
END 
7. C语言源程序 
#include 
unsigned char tcount2s; 
unsigned char tcount02s; 
unsigned char ID; 
void main(void) 
{ 
TMOD=0x01; 
TH0=(65536-50000)/256; 
TL0=(65536-50000)%256; 
TR0=1; 
ET0=1; 
EA=1; 
while(1); 
} 
void t0(void) interrupt 1 using 0 
{ 
tcount2s++; 
if(tcount2s==40) 
{ 
tcount2s=0; 
ID++; 
if(ID==4) 
{ 
ID=0; 
} 
} 
tcount02s++; 
if(tcount02s==4) 
{ 
tcount02s=0; 
switch(ID) 
{ 
case 0: 
P1_0=~P1_0; 
break; 
case 1: 
P1_1=~P1_1; 
break; 
case 2: 
P1_2=~P1_2; 
break; 
case 3: 
P1_3=~P1_3; 
break; 
} 
} 
} 




AT89S51I /'? ZZZVXSHUPFXFRP
- 78 - 
17 / P@>U O *―
~ ¨/00¨11 SP1 Au ~ 
~ 12 SP1 ¨Au 0!6~
~ 13 SP1 ¨Au &L ~
U *dC )5-
4.17.1 
U 2*4fi9- %E3 
~ ^)(2ˇ4 ,XP0.0/AD0 P0.7/AD70^ *ü88 f4 E y C^M- D- / +
,Xˇ a h0^ × U" P0.0/AD0 h-a¨P0.1/AD1 h-b¨¨P0.7/AD7 
h-h~ 
~ ^)(2ˇ4 ,XP2.0/A8 P2.7/A150^ *ü88 f4 E y C^M- D- / +
,Xˇ a h0^ × U" P2.0/A8 h-a¨P2.1/A9 h-b¨¨P2.7/A15 h
-h~
~ ^)(2ˇ4 ,XP3.5/T1*ü―4 E y( 0 K, ,XSP10^ ×
U /: u-
/ c 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 79 - 







T0中断服务程序框图 
开 始 
SEC=0,并显示"00" 
开中断,并允许T0中断 
SP1识别成功否 
KEYCNT加1 
KEYCNT=1 KEYCNT=2 KEYCNT=3 
TH0,TL0初始化 停止T0 SEC=0,显示00 
计数清0 KEYCNT=0 
启动T0工作 
T0中断入口 
TCNT加1 
TCNT=400吗 
TCNT=0 
SEC加1 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 80 - 
图4.17.2 
5. 汇编源程序 
TCNTA EQU 30H 
TCNTB EQU 31H 
SEC EQU 32H 
KEYCNT EQU 33H 
SP1 BIT P3.5 
ORG 00H 
LJMP START 
ORG 0BH 
LJMP INT_T0 
START: MOV KEYCNT,#00H 
MOV SEC,#00H 
MOV A,SEC 
MOV B,#10 
DIV AB 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P0,A 
MOV A,B 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P2,A 
MOV TMOD,#02H 
SETB ET0 
SETB EA 
WT: JB SP1,WT 
LCALL DELY10MS 
JB SP1,WT 
INC KEYCNT 
MOV A,KEYCNT 
CJNE A,#01H,KN1 
SETB TR0 
MOV TH0,#06H 
MOV TL0,#06H 
MOV TCNTA,#00H 
MOV TCNTB,#00H 
LJMP DKN 
KN1: CJNE A,#02H,KN2 
CLR TR0 
LJMP DKN 
KN2: CJNE A,#03H,DKN 
MOV SEC,#00H 
MOV A,SEC 
MOV B,#10 
DIV AB 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P0,A 
MOV A,B 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
SEC=100吗 
SEC=0 
处理SEC并显示 
中断返回 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 81 - 
MOV P2,A 
MOV KEYCNT,#00H 
DKN: JNB SP1,$ 
LJMP WT 
DELY10MS: 
MOV R6,#20 
D1: MOV R7,#248 
DJNZ R7,$ 
DJNZ R6,D1 
RET 
INT_T0: 
INC TCNTA 
MOV A,TCNTA 
CJNE A,#100,NEXT 
MOV TCNTA,#00H 
INC TCNTB 
MOV A,TCNTB 
CJNE A,#4,NEXT 
MOV TCNTB,#00H 
INC SEC 
MOV A,SEC 
CJNE A,#100,DONE 
MOV SEC,#00H 
DONE: MOV A,SEC 
MOV B,#10 
DIV AB 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P0,A 
MOV A,B 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P2,A 
NEXT: RETI 
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH 
END 
6. 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 keycnt; 
unsigned int tcnt; 
void main(void) 
{ 
unsigned char i,j; 
TMOD=0x02; 
ET0=1; 
EA=1; 
second=0; 
P0=dispcode[second/10]; 
P2=dispcode[second%10]; 
while(1) 
{ 
if(P3_5==0) 
{ 
for(i=20;i>0;i--) 
for(j=248;j>0;j--); 
if(P3_5==0) 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 82 - 
{ 
keycnt++; 
switch(keycnt) 
{ 
case 1: 
TH0=0x06; 
TL0=0x06; 
TR0=1; 
break; 
case 2: 
TR0=0; 
break; 
case 3: 
keycnt=0; 
second=0; 
P0=dispcode[second/10]; 
P2=dispcode[second%10]; 
break; 
} 
while(P3_5==0); 
} 
} 
} 
} 
void t0(void) interrupt 1 using 0 
{ 
tcnt++; 
if(tcnt==400) 
{ 
tcnt=0; 
second++; 
if(second==100) 
{ 
second=0; 
} 
P0=dispcode[second/10]; 
P2=dispcode[second%10]; 
} 
} 
18. "嘀,嘀,……"报警声 
1. 实验任务 
用AT89S51单片机产生"嘀,嘀,…"报警声从P1.0端口输出,产生频率为1KHz,根据上面图可知:
1KHZ方波从P1.0输出0.2秒,接着0.2秒从P1.0输出电平信号,如此循环下去,就形成我们所需的
报警声了. 
2. 电路原理图 
AT89S51I /'? ZZZVXSHUPFXFRP
- 83 - 
4.18.1 
U 2*4fi- %E3 
~ ^)(2ˇ4 ,XP1.00^ *ü―4 E yM Ne + ,XSPK IN0^ ¨ 
~ üM Ne + ,XSPK OUT0^ y 8 5 16 ,X[`×
U /: @í@― "
~1 *ó# / ,XyA:~¨_V ^ ^ ,X / ~M yA:~¨ 
bE / yA:~¨ 0.2/ Js¨' 0.2/ Js¨V!8~) ¨A' ~,XNe)[1KHz¨íyA:~ c 
V / 
E~" 6 V)*ü)(9{*ó6 
~ +b U{*ó M6,X ¨ ^ M6,X F… ¨ F… 1KHZ " ¨4*ü K¨0.2/ ×
" F… +G¨34*ü0.2/ ×?!8¨ *ü)(,Xn /AuD0.2/ ×à ¨3 U*ü)({*ó1KHZ,X " ¨ b1KHZ,X " <ó1ms¨P +G4*ü
0.5ms¨"+G4*ü0.5ms¨?!83G *ün E'0.2/ ,Xn K¨Z~
U /: u-
AT89S51单片机实验及实践教程 www.supermcu.com 
- 84 - 
主程序框图 






中断服务程序框图 


图4.18.2 
开 始 
T02S=0,T05MS=0,FLAG=0
T0初始化 
T0启动定时并开中断 
等待中断 
T0中断入口 
T02S加1 
T02S=400吗 
FLAG取反 
FLAG=0 FLAG=1 
P1.0取反 
中断返回 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 85 - 
6. 汇编源程序 
T02SA EQU 30H 
T02SB EQU 31H 
FLAG BIT 00H 
ORG 00H 
LJMP START 
ORG 0BH 
LJMP INT_T0 
START: MOV T02SA,#00H 
MOV T02SB,#00H 
CLR FLAG 
MOV TMOD,#01H 
MOV TH0,#(65536-500) / 256 
MOV TL0,#(65536-500) MOD 256 
SETB TR0 
SETB ET0 
SETB EA 
SJMP $ 
INT_T0: 
MOV TH0,#(65536-500) / 256 
MOV TL0,#(65536-500) MOD 256 
INC T02SA 
MOV A,T02SA 
CJNE A,#100,NEXT 
INC T02SB 
MOV A,T02SB 
CJNE A,#04H,NEXT 
MOV T02SA,#00H 
MOV T02SB,#00H 
CPL FLAG 
NEXT: JB FLAG,DONE 
CPL P1.0 
DONE: RETI 
END 
7. C语言源程序 
#include 
unsigned int t02s; 
unsigned char t05ms; 
bit flag; 
void main(void) 
{ 
TMOD=0x01; 
TH0=(65536-500)/256; 
TL0=(65536-500)%256; 
TR0=1; 
ET0=1; 
EA=1; 
while(1); 
} 
void t0(void) interrupt 1 using 0 
{ 
TH0=(65536-500)/256; 
TL0=(65536-500)%256; 
t02s++; 
if(t02s==400) 
{ 
AT89S51I /'? ZZZVXSHUPFXFRP
- 86 - 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?