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 + -
显示快捷键?