📄 at89s51.c
字号:
MOVC A,@A+DPTR
CJNE A,#01H,LOOP1
JMP START
LOOP1: MOV P1,A
MOV R3,#20
LCALL DELAY
INC DPTR
JMP LOOP
DELAY: MOV R4,#20
D1: MOV R5,#248
DJNZ R5,$
DJNZ R4,D1
DJNZ R3,DELAY
RET
AT89S51单片机实验及实践教程 www.supermcu.com
- 39 -
TABLE: DB 0FEH,0FDH,0FBH,0F7H
DB 0EFH,0DFH,0BFH,07FH
DB 0FEH,0FDH,0FBH,0F7H
DB 0EFH,0DFH,0BFH,07FH
DB 07FH,0BFH,0DFH,0EFH
DB 0F7H,0FBH,0FDH,0FEH
DB 07FH,0BFH,0DFH,0EFH
DB 0F7H,0FBH,0FDH,0FEH
DB 00H, 0FFH,00H, 0FFH
DB 01H
END
7. C语言源程序
#include
unsigned char code table[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f,
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f,
0x7f,0xbf,0xdf,0xef,
0xf7,0xfb,0xfd,0xfe,
0x7f,0xbf,0xdf,0xef,
0xf7,0xfb,0xfd,0xfe,
0x00,0xff,0x00,0xff,
0x01};
unsigned char i;
void delay(void)
{
unsigned char m,n,s;
for(m=20;m>0;m--)
for(n=20;n>0;n--)
for(s=248;s>0;s--);
}
void main(void)
{
while(1)
{
if(table[i]!=0x01)
{
P1=table[i];
i++;
delay();
}
else
{
i=0;
}
}
}
6. 报警产生器
1. 实验任务
用P1.0输出1KHz和500Hz的音频信号驱动扬声器,作报警信号,要求1KHz信号响100ms,500Hz
信号响200ms,交替进行,P1.7接一开关进行控制,当开关合上响报警信号,当开关断开告警信号停止,
编出程序.
AT89S51I /'? ZZZVXSHUPFXFRP
- 40 -
U *dC )5-
4.6.1
U 2*4fi9- %E3
~1 ^)(2ˇ4 ,XP1.00^ *ü―4 E yM Ne + ,XSPK IN0^ ×
~2 üM Ne + ,XSPK OUT0^ y 8 ,X 5 16 ,X[`×
~3 ^)(2ˇ4 ,XP1.7/RD0^ *ü―4 E y C^…| G ,XK10^ ×
U /: @í@―?
~1 {*ó,X "'
500Hz <ó2ms¨ +G! 1ms 1 ¨1KHz,X <ó1ms¨ +G!
500us 1 ×
U /: u-
AT89S51单片机实验及实践教程 www.supermcu.com
- 41 -
图4.6.2
6. 汇编源程序
FLAG BIT 00H
ORG 00H
START: JB P1.7,START
JNB FLAG,NEXT
MOV R2,#200
DV: CPL P1.0
LCALL DELY500
LCALL DELY500
DJNZ R2,DV
CPL FLAG
NEXT: MOV R2,#200
DV1: CPL P1.0
LCALL DELY500
DJNZ R2,DV1
CPL FLAG
SJMP START
DELY500: MOV R7,#250
LOOP: NOP
DJNZ R7,LOOP
RET
END
7. C语言源程序
#include
#include
bit flag;
unsigned char count;
开始
K1按下了吗
FLAG=0吗
置200次计数
P1.0输出取反
延时500us
计数值计完了吗
FLAG取反
置200次计数
P1.0输出取反
延时1ms
计数值计完了吗
FLAG取反
AT89S51单片机实验及实践教程 www.supermcu.com
- 42 -
void dely500(void)
{
unsigned char i;
for(i=250;i>0;i--)
{
_nop_();
}
}
void main(void)
{
while(1)
{
if(P1_7==0)
{
for(count=200;count>0;count--)
{
P1_0=~P1_0;
dely500();
}
for(count=200;count>0;count--)
{
P1_0=~P1_0;
dely500();
dely500();
}
}
}
}
7. I/O并行口直接驱动LED显示
1. 实验任务
如图13所示,利用AT89S51单片机的P0端口的P0.0-P0.7连接到一个共阴数码管的a-h的笔段上,
数码管的公共端接地.在数码管上循环显示0-9数字,时间间隔0.2秒.
2. 电路原理图
AT89S51I /'? ZZZVXSHUPFXFRP
- 43 -
4.7.1
2*4fi9- %E3
^)(2ˇ4 ,XP0.0/AD0 P0.7/AD70^ *ü88 f4 E y C^M- D- / +
,Xˇ D- 1u,Xa h0^ × U" P0.0/AD0 a, E ¨P0.1/AD1 b, E ¨P0.2/AD2
c, E ¨¨P0.7/AD7 h, E ~
/: @í@―?
~1 LEDD- /s)
×! LED/<
V / TABLEDB3FH¨06H¨5BH¨4FH¨66H¨6DH¨7DH¨07H¨7FH¨6FH
AT89S51I /'? ZZZVXSHUPFXFRP
- 44 -
U /: u-
4.7.2
U !v4E# /:
ORG 0
START: MOV R1,#00H
NEXT: MOV A,R1
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
INC R1
CJNE R1,#10,NEXT
LJMP START
DELAY: MOV R5,#20
D2: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
U & A /# /:
#include
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char dispcount;
void delay02s(void)
{
unsigned char i,j,k;
for(i=20;i>0;i--)
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}
AT89S51I /'? ZZZVXSHUPFXFRP
- 45 -
void main(void)
{
while(1)
{
for(dispcount=0;dispcount
¨5àü K ,XE / ¨AE U FDE 9¨?¨ü ,XE / ¨ " FDE 9¨
^6 E A^ " E / ¨E JAE U,X~?!8ü K ,X í¨
4.8.2
U^ ,XFD K,X y "1FD 4 $ L8]¨ 8 ¨ ^
G *ü+ 9$ L8]E oFD ¨rL ¨ rt.@ .@ +C^,X'/^¨E
AEà ¨k r"' E K Nl¨?!8 ^ G *üEC $ " ,X "' L8E oFD ¨
8 ¨ K ,X í¨ü ,X ,ü- n,XFD ¨
E 9Z0n,X( ~K',X K G ,X A ¨ 5ms ¨ 5àFS Z
FD ¨ a9 # ¨, Koe,ók 4 ¨8 ,ók 4 ¨E 6 n
Eg "+G¨8 E #,XP +G¨A !+bFD CK,XA^ " ¨CPU
AxA^ " 5à7AE×E ,X KA E / ~ 5à P Z2ˇ4 ,X^M4 ~
+b U"! ¨Q > ;> ¨,¨ a ,X í¨a;> Q ¨?!8
K> A 9 ¨ ^ ;> E ,XQ ¨ U 1Y KG ,XE / ¨
'G ,XE / ¨SJ6AE P +G( ~
~2 b KA ,X ¨ q'E ‰V JB
BIT¨REL *ü9 #BIToeP +G¨8
BIT 1¨í/ cE@ REL ;> / c¨oeí4 4`
;> / c~ 5 JNBBIT¨REL *ü
9 #BIToe"+G¨8 BIT 0¨í/ cE@
REL ;> / c¨oeí4 4` ;> / c~
~3 / cA'AuE / KA E / ,X V
/ 4.8.3
U /: u-
AT89S51单片机实验及实践教程 www.supermcu.com
- 47 -
图4.8.4
6. 汇编源程序
ORG 0
START: MOV R1,#00H ;初始化R7为0,表示从0开始计数
MOV A,R1 ;
CPL A ;取反指令
MOV P1,A ;送出P1端口由发光二极管显示
REL: JNB P3.7,REL ;判断SP1是否按下
LCALL DELAY10MS ;若按下,则延时10ms左右
JNB P3.7,REL ;再判断SP1是否真得按下
INC R7 ;若真得按下,则进行按键处理,使
MOV A,R7 ;计数内容加1,并送出P1端口由
CPL A ;发光二极管显示
MOV P1,A ;
JNB P3.7,$ ;等待SP1释放
SJMP REL ;继续对K1按键扫描
DELAY10MS: MOV R6,#20 ;延时10ms子程序
L1: MOV R7,#248
DJNZ R7,$
DJNZ R6,L1
RET
END
7. C语言源程序
#include
unsigned char count;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
while(1)
{
if(P3_7==0)
{
delay10ms();
if(P3_7==0)
{
count++;
if(count==16)
{
count=0;
}
P1=~count;
while(P3_7==0);
}
}
AT89S51I /'? ZZZVXSHUPFXFRP
- 48 -
9 K s6 KA T
1U O *―
V 4.9.1/¨ GSP1yüP3.7/RD1u6 ¨üAT89S51)(,XP10^ y 'U1u¨
+,X í¨L1yüP1.01u6 ,X 'U1uüK & ¨'! GSP1,X í¨L2yüP1.1
1u6 ,X 'U1uüK & ¨a GSP1,X í¨L3yüP1.21u6 ,X 'U1uüK & ¨a
GSP1,X í¨L4yüP1.31u6 ,X 'U1uüK & ¨a GSP1,X í¨ EBL1
üK & Z¨V!8EB# ~
2U *dC )5-
4.9.1
3U 2*4fi9- %E3
~1 ^)(2ˇ4 ,XP3.7/RD0^ E y( 0 K, ,XSP10^ ×
~2 ^)(2ˇ4 ,XP1.0 P1.40^ *ü88 f4 E y C^ 'U1u / +
,XL1 L80^ × U"¨P1.0E yL1¨P1.1E yL2¨P1.2E yL3¨
P1.3E yL4 ~
4U /: @í@― "
~1 A'Auae +9
ü *ó#¨ \ E E E ¨Fw " ¨" )_h×Fw?! AE
à,XAE$¨ \ Ax ¨à¨ b UE E K9A ! / AEà,Xs6 ¨ 4 ! AEà
,Xs6 +*üAEà,XID A ¨E ¨! K¨ID,XAE, à,X¨ )(\
A AEàs6 ,XD Z~
~2 A'Au "'
M6,X U" ^ , ¨L1L4 'U1uü! ,XK & ,X K¨ GSP19{¨
4 L1L4K & ,X ! n AEà,XID ¨'L1üK & ¨ID 0×'L2üK & ¨ID 1×'
AT89S51I /'? ZZZVXSHUPFXFRP
- 49 -
L3üK & ¨ID 2×'L4üK & ¨ID 3×\'¨ U! GK1 ¨ 4 AEà,X
ID 6 ó' M6,XˇuZ~ M64 G/ cA'Au,X ~
5U /: u-
4.9.2
6U !v4E# /:
ID EQU 30H
SP1 BIT P3.7
L1 BIT P1.0
L2 BIT P1.1
L3 BIT P1.2
L4 BIT P1.3
ORG 0
MOV ID,#00H
START: JB K1,REL
LCALL DELAY10MS
JB K1,REL
INC ID
MOV A,ID
CJNE A,#04,REL
MOV ID,#00H
REL: JNB K1,$
MOV A,ID
CJNE A,#00H,IS0
CPL L1
LCALL DELAY
SJMP START
AT89S51单片机实验及实践教程 www.supermcu.com
- 50 -
IS0: CJNE A,#01H,IS1
CPL L2
LCALL DELAY
SJMP START
IS1: CJNE A,#02H,IS2
CPL L3
LCALL DELAY
SJMP START
IS2: CJNE A,#03H,IS3
CPL L4
LCALL DELAY
SJMP START
IS3: LJMP START
DELAY10MS: MOV R6,#20
LOOP1: MOV R7,#248
DJNZ R7,$
DJNZ R6,LOOP1
RET
DELAY: MOV R5,#20
LOOP2: LCALL DELAY10MS
DJNZ R5,LOOP2
RET
END
7. C语言源程序
#include
unsigned char ID;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void delay02s(void)
{
unsigned char i;
for(i=20;i>0;i--)
{delay10ms();
}
}
void main(void)
{ while(1)
{ if(P3_7==0)
{delay10ms();
if(P3_7==0)
{
ID++;
if(ID==4)
{
ID=0;
}
while(P3_7==0);
}
}
switch(ID)
{ case 0:
P1_0=~P1_0;
AT89S51I /'? ZZZVXSHUPFXFRP
- 51 -
delay02s();
break;
case 1:
P1_1=~P1_1;
delay02s();
break;
case 2:
P1_2=~P1_2;
delay02s();
break;
case 3:
P1_3=~P1_3;
delay02s();
break;
}
}
}
10 00 99AuD<
U O *―
*üAT89S51)(90 |AuD AuD¨AuD$ ¨ L AuD×
~3 )( Au,XD UE > D- /¨Auk,XDE D¨ !' !¨ U^!' !
E E ,X!' !D h,XD- 1u /~V) !' ! ^ ^
Auk,XD 10"-¨G^ !D+¨ 10HL8¨G^k!D+Z~
~4 E E >< ¨ / !'!D+~
U /: u-
4.10.2
U !v4E# /:
Count EQU 30H
SP1 BIT P3.7
ORG 0
START: MOV Count,#00H
NEXT: MOV A,Count
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
WT: JNB SP1,WT
WAIT: JB SP1,WAIT
LCALL DELY10MS
JB SP1,WAIT
INC Count
MOV A,Count
CJNE A,#100,NEXT
LJMP START
DELY10MS: MOV R6,#20
AT89S51单片机实验及实践教程 www.supermcu.com
- 53 -
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
7. C语言源程序
#include
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char Count;
void delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
Count=0;
P0=table[Count/10];
P2=table[Count%10];
while(1)
{
if(P3_7==0)
{
delay10ms();
if(P3_7==0)
{
Count++;
if(Count==100)
{
Count=0;
}
P0=table[Count/10];
P2=table[Count%10];
while(P3_7==0);
}
}
}
}
11. 00-59秒计时器(利用软件延时)
1. 实验任务
如下图所示,在AT89S51单片机的P0和P2端口分别接有两个共阴数码管,P0口驱动显示秒时间的
十位,而P2口驱动显示秒时间的个位.
2. 电路原理图
AT89S51I /'? ZZZVXSHUPFXFRP
- 54 -
4.11.1
3U 2*4fi9- %E3
~1 ^)(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 ^)(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~
4U /: @í@―?
~1 üA'AuE / *ü ,|)0/ AuD)¨' / Js9 ¨A}/ AuD)t1¨' /
AuDE'60 ¨ 7 |E¤ 0¨ / AuD~
~2 b/ AuD) ,XDB U^W!D'
D ¨ "' G *ü 10HL8' 10"-~
~3 üD- /¨ E E ><,X ' ~
~4 / K¨,X{*óü E G G *üEC 2'.B
,X "'9' ¨4 E 2'.BAu1kk1/ K¨
1.002/ ~
DELY1S: MOV R5,#100
D2: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
5U /: u-
AT89S51单片机实验及实践教程 www.supermcu.com
- 55 -
图4.11.2
6. 汇编源程序
Second EQU 30H
ORG 0
START: MOV Second,#00H
NEXT: 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
LCALL DELY1S
INC Second
MOV A,Second
CJNE A,#60,NEXT
LJMP START
DELY1S: MOV R5,#100
D2: MOV R6,#20
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
7. C语言源程序
#include
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char Second;
void delay1s(void)
{
unsigned char i,j,k;
AT89S51单片机实验及实践教程 www.supermcu.com
- 56 -
for(k=100;k>0;k--)
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
void main(void)
{
Second=0;
P0=table[Second/10];
P2=table[Second%10];
while(1)
{
delay1s();
Second++;
if(Second==60)
{
Second=0;
}
P0=table[Second/10];
P2=table[Second%10];
}
}
12. 可预置可逆4位计数器
1. 实验任务
利用AT89S51单片机的P1.0-P1.3接四个发光二极管L1-L4,用来指示当前计数的数据;用P1.4-
P1.7作为预置数据的输入端,接四个拨动开关K1-K4,用P3.6/WR和P3.7/RD端口接两个轻触开关,
用来作加计数和减计数开关.具体的电路原理图如下图所示
2. 电路原理图
AT89S51I /'? ZZZVXSHUPFXFRP
- 57 -
3U 2*4fi9- %E3
~1 ^)(2ˇ4 ,XP1.0 P1.30^ *ü88 f4 E y C^ 'U1u / +
,XL1 L4 × U" P1.0 h-L1¨P1.1 h-L2¨P1.2 h-L3¨P1.3 h-L4×
~2 ^)(2ˇ4 ,XP3.0/RXD¨P3.1/TXD¨P3.2/INT0¨P3.3/INT1*ü―4 E y C^…
| G ,XK1 K4 ×
~3 ^)(2ˇ4 ,XP3.6/WR¨P3.7/RD*ü―4 E y( 0 K, ,XSP1'SP2
×
4U /: @í@―?
~ ( 0 KA ,X ) E / ×
~ NX5BaeAˇ",XK Nl
AT89S51I /'? ZZZVXSHUPFXFRP
- 58 -
~ LEDEg /
5U /: u-
6U !v4E# /:
COUNT EQU 30H
ORG 00H
START: MOV A,P3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -