at89s51.c

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

C
3,134
字号
ANL A,#0FH 
MOV COUNT,A 
MOV P1,A 
SK2: JB P3.6,SK1 
LCALL DELY10MS 
JB P3.6,SK1 
INC COUNT 
MOV A,COUNT 
CJNE A,#16,NEXT 
MOV A,P3 
ANL A,#0FH 
MOV COUNT,A 
NEXT: MOV P1,A 
WAIT: JNB P3.6,WAIT 
LJMP SK2 
SK1: JB P3.7,SK2 
LCALL DELY10MS 
JB P3.7,SK2 
DEC COUNT 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 59 - 
MOV A,COUNT 
CJNE A,#0FFH,NEX 
MOV A,P3 
ANL A,#0FH 
MOV COUNT,A 
NEX: MOV P1,A 
WAIT2: JNB P3.7,WAIT2 
LJMP SK2 
DELY10MS: MOV R6,#20 
MOV R7,#248 
D1: DJNZ R7,$ 
DJNZ R6,D1 
RET 
END 
7. C语言源程序 
#include 
unsigned char curcount; 
void delay10ms(void) 
{ 
unsigned char i,j; 
for(i=20;i>0;i--) 
for(j=248;j>0;j--); 
} 
void main(void) 
{ 
curcount=P3 & 0x0f; 
P1=~curcount; 
while(1) 
{ 
if(P3_6==0) 
{ 
delay10ms(); 
if(P3_6==0) 
{ 
if(curcount>=15) 
{ 
curcount=15; 
} 
else 
{ 
curcount++; 
} 
P1=~curcount; 
while(P3_6==0); 
} 
} 
if(P3_7==0) 
{ 
delay10ms(); 
if(P3_7==0) 
{ 
if(curcount<=0) 
{ 
curcount=0; 
AT89S51I /'? ZZZVXSHUPFXFRP
- 60 - 
} 
else 
{ 
curcount--; 
} 
P1=~curcount; 
while(P3_7==0); 
} 
} 
} 
} 
13 | D- /T 
1U O *―
V /¨3 0^ y| D- 1u,X+6- 0 ! ¨3 0^ y| D- 1u,XD!E ‰0^¨3 y
G¨' GyP +G ¨/+×' Gy"+G ¨/+(//2+~
2U *dC )5-

3U 2*4fi9- %E3 
~1 ^)(2ˇ4 ,XP0.0/AD0 P0.7/AD7*ü88 f4 E y| D- / ,Xa
AT89S51单片机实验及实践教程 www.supermcu.com 
- 61 - 
-h端口上; 
(2. 把"单片机系统"区域中的P2.0/A8-P2.7/A15用8芯排线连接到"动态数码显示"区域中的S1
-S8端口上; 
(3. 把"单片机系统"区域中的P1.7端口用导线连接到"独立式键盘"区域中的SP1端口上; 
4. 程序设计内容 
(1. 动态扫描方法 
动态接口采用各数码管循环轮流显示的方法,当循环显示频率较高时,利用人眼的暂留特性,看不
出闪烁显示现象,这种显示需要一个接口完成字形码的输出(字形选择),另一接口完成各数码管
的轮流点亮(数位选择). 
(2. 在进行数码显示的时候,要对显示单元开辟8个显示缓冲区,每个显示缓冲区装有显示的不同数
据即可. 
(3. 对于显示的字形码数据我们采用查表方法来完成. 
5. 程序框图 

图4.13.2 
6. 汇编源程序 
ORG 00H 
START: JB P1.7,DIR1 
MOV DPTR,#TABLE1 
SJMP DIR 
DIR1: MOV DPTR,#TABLE2 
DIR: MOV R0,#00H 
MOV R1,#01H 
NEXT: MOV A,R0 
MOVC A,@A+DPTR 
MOV P0,A 
MOV A,R1 
开始 
K1按键识别成功否 
置显示"12345"字形码首地址 置显示"HELLO"字形码首地址 
置字形码偏移量和位选代码 
查表并送出显示 
延时2ms,并指向下一个偏移量
5个数码管显示完否 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 62 - 
MOV P2,A 
LCALL DAY 
INC R0 
RL A 
MOV R1,A 
CJNE R1,#0DFH,NEXT 
SJMP START 
DAY: MOV R6,#4 
D1: MOV R7,#248 
DJNZ R7,$ 
DJNZ R6,D1 
RET 
TABLE1: DB 06H,5BH,4FH,66H,6DH 
TABLE2: DB 78H,79H,38H,38H,3FH 
END 
7. C语言源程序 
#include 
unsigned char code table1[]={0x06,0x5b,0x4f,0x66,0x6d}; 
unsigned char code table2[]={0x78,0x79,0x38,0x38,0x3f}; 
unsigned char i; 
unsigned char a,b; 
unsigned char temp; 
void main(void) 
{ 
while(1) 
{ 
temp=0xfe; 
for(i=0;i<5;i++) 
{ 
if(P1_7==1) 
{ 
P0=table1[i]; 
} 
else 
{ 
P0=table2[i]; 
} 
P2=temp; 
a=temp<>(7-i); 
temp=a|b; 
for(a=4;a>0;a--) 
for(b=248;b>0;b--); 
} 
} 
} 
14. 4×4矩阵式键盘识别技术 
1. 实验任务 
如图4.14.2所示,用AT89S51的并行口P1接4×4矩阵键盘,以P1.0-P1.3作输入线,以P1.4-P1.7
作输出线;在数码管上显示每个按键的"0-F"序号.对应的按键的序号排列如图4.14.1所示 
AT89S51I /'? ZZZVXSHUPFXFRP
- 63 - 

U - %*dC )5-

U 2*4fi9- %E3 
~ ^)(2ˇ4 ,XP3.0 P3.70^ *ü88 f4 E y4X4> K, ,XC1 
C4R1 R40^ × 
~ ^)(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~
4 / cA'AuY 
~ h -‰LK, A ) 
~ ! K W,X> ' ¨> ' ,X4 A E K,X4 - ~-‰L,X> 4 '
4 E E J> y ' &38 E ~! K,X( àL D+G '¨ G
,X 0^~ 4 E E +Ly 9&&¨5àyE E / cEg D+r) ,X~K, ) / c,Xˇ
u .Bn ?K ¨ K ¨K,Xs6 ×E U#\L8 KüK` 
,Xj|~ J> ¨ Eg - ¨S KE > | y¨" J> Eg9 K
( ¨+> ' O\ Eà6 K4 - 5àA K¨E E EC ><¨ A K,Xs6 ~
0 
4
8 
C 
1 
5 
9 
D 
2 
6 
A 
E 
3 
7 
B 
F 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 64 - 
5. 程序框图 

图4.14.3 
6. 汇编源程序 
KEYBUF EQU 30H 
ORG 00H 
START: MOV KEYBUF,#2 
WA I T: 
MOV P3,#0FFH 
CLR P3.4 
MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JZ NOKEY1 
LCALL DELY10MS 
MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JZ NOKEY1 
MOV A,P3 
ANL A,#0FH 
CJNE A,#0EH,NK1 
MOV KEYBUF,#0 
LJMP DK1 
NK1: CJNE A,#0DH,NK2 
MOV KEYBUF,#1 
P3=FFH,P3.0=0 
有键按下吗 
延时10ms 
真得有键按下吗 
根据当前状态识别按键 
P3=FFH,P3.1=0 
有键按下吗 
延时10ms 
真得有键按下吗 
根据当前状态识别按键 
P3=FFH,P3.2=0 
有键按下吗 
延时10ms 
真得有键按下吗 
根据当前状态识别按键 
P3=FFH,P3.3=0 
有键按下吗 
延时10ms 
真得有键按下吗 
根据当前状态识别按键 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 65 - 
LJMP DK1 
NK2: CJNE A,#0BH,NK3 
MOV KEYBUF,#2 
LJMP DK1 
NK3: CJNE A,#07H,NK4 
MOV KEYBUF,#3 
LJMP DK1 
NK4: NOP 
DK1: 
MOV A,KEYBUF 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P0,A 
DK1A: MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JNZ DK1A 
NOKEY1: 
MOV P3,#0FFH 
CLR P3.5 
MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JZ NOKEY2 
LCALL DELY10MS 
MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JZ NOKEY2 
MOV A,P3 
ANL A,#0FH 
CJNE A,#0EH,NK5 
MOV KEYBUF,#4 
LJMP DK2 
NK5: CJNE A,#0DH,NK6 
MOV KEYBUF,#5 
LJMP DK2 
NK6: CJNE A,#0BH,NK7 
MOV KEYBUF,#6 
LJMP DK2 
NK7: CJNE A,#07H,NK8 
MOV KEYBUF,#7 
LJMP DK2 
NK8: NOP 
DK2: 
MOV A,KEYBUF 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P0,A 
DK2A: MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JNZ DK2A 
NOKEY2: 
MOV P3,#0FFH 
CLR P3.6 
MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JZ NOKEY3 
LCALL DELY10MS 
MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JZ NOKEY3 
MOV A,P3 
ANL A,#0FH 
CJNE A,#0EH,NK9 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 66 - 
MOV KEYBUF,#8 
LJMP DK3 
NK9: CJNE A,#0DH,NK10 
MOV KEYBUF,#9 
LJMP DK3 
NK10: CJNE A,#0BH,NK11 
MOV KEYBUF,#10 
LJMP DK3 
NK11: CJNE A,#07H,NK12 
MOV KEYBUF,#11 
LJMP DK3 
NK12: NOP 
DK3: 
MOV A,KEYBUF 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P0,A 
DK3A: MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JNZ DK3A 
NOKEY3: 
MOV P3,#0FFH 
CLR P3.7 
MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JZ NOKEY4 
LCALL DELY10MS 
MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JZ NOKEY4 
MOV A,P3 
ANL A,#0FH 
CJNE A,#0EH,NK13 
MOV KEYBUF,#12 
LJMP DK4 
NK13: CJNE A,#0DH,NK14 
MOV KEYBUF,#13 
LJMP DK4 
NK14: CJNE A,#0BH,NK15 
MOV KEYBUF,#14 
LJMP DK4 
NK15: CJNE A,#07H,NK16 
MOV KEYBUF,#15 
LJMP DK4 
NK16: NOP 
DK4: 
MOV A,KEYBUF 
MOV DPTR,#TABLE 
MOVC A,@A+DPTR 
MOV P0,A 
DK4A: MOV A,P3 
ANL A,#0FH 
XRL A,#0FH 
JNZ DK4A 
NOKEY4: 
LJMP WAIT 
DELY10MS: 
MOV R6,#10 
D1: MOV R7,#248 
DJNZ R7,$ 
DJNZ R6,D1 
RET 
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H 
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H 
END 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 67 - 
7. C语言源程序 
#include 
unsigned char code table[]={0x3f,0x06,0x5b,0x4f, 
0x66,0x6d,0x7d,0x07, 
0x7f,0x6f,0x77,0x7c, 
0x39,0x5e,0x79,0x71}; 
unsigned char temp; 
unsigned char key; 
unsigned char i,j; 
void main(void) 
{ 
while(1) 
{ 
P3=0xff; 
P3_4=0; 
temp=P3; 
temp=temp & 0x0f; 
if (temp!=0x0f) 
{ 
for(i=50;i>0;i--) 
for(j=200;j>0;j--); 
temp=P3; 
temp=temp & 0x0f; 
if (temp!=0x0f) 
{ 
temp=P3; 
temp=temp & 0x0f; 
switch(temp) 
{ 
case 0x0e: 
key=7; 
break; 
case 0x0d: 
key=8; 
break; 
case 0x0b: 
key=9; 
break; 
case 0x07: 
key=10; 
break; 
} 
temp=P3; 
P1_0=~P1_0; 
P0=table[key]; 
temp=temp & 0x0f; 
while(temp!=0x0f) 
{ 
temp=P3; 
temp=temp & 0x0f; 
} 
} 
} 
P3=0xff; 
P3_5=0; 
temp=P3; 
temp=temp & 0x0f; 
if (temp!=0x0f) 
{ 
for(i=50;i>0;i--) 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 68 - 
for(j=200;j>0;j--); 
temp=P3; 
temp=temp & 0x0f; 
if (temp!=0x0f) 
{ 
temp=P3; 
temp=temp & 0x0f; 
switch(temp) 
{ 
case 0x0e: 
key=4; 
break; 
case 0x0d: 
key=5; 
break; 
case 0x0b: 
key=6; 
break; 
case 0x07: 
key=11; 
break; 
} 
temp=P3; 
P1_0=~P1_0; 
P0=table[key]; 
temp=temp & 0x0f; 
while(temp!=0x0f) 
{ 
temp=P3; 
temp=temp & 0x0f; 
} 
} 
} 
P3=0xff; 
P3_6=0; 
temp=P3; 
temp=temp & 0x0f; 
if (temp!=0x0f) 
{ 
for(i=50;i>0;i--) 
for(j=200;j>0;j--); 
temp=P3; 
temp=temp & 0x0f; 
if (temp!=0x0f) 
{ 
temp=P3; 
temp=temp & 0x0f; 
switch(temp) 
{ 
case 0x0e: 
key=1; 
break; 
case 0x0d: 
key=2; 
break; 
case 0x0b: 
key=3; 
break; 
case 0x07: 
key=12; 
break; 
} 
temp=P3; 
AT89S51单片机实验及实践教程 www.supermcu.com 
- 69 - 
P1_0=~P1_0; 
P0=table[key]; 
temp=temp & 0x0f; 
while(temp!=0x0f) 
{ 
temp=P3; 
temp=temp & 0x0f; 
} 
} 
} 
P3=0xff; 
P3_7=0; 
temp=P3; 
temp=temp & 0x0f; 
if (temp!=0x0f) 
{ 
for(i=50;i>0;i--) 
for(j=200;j>0;j--); 
temp=P3; 
temp=temp & 0x0f; 
if (temp!=0x0f) 
{ 
temp=P3; 
temp=temp & 0x0f; 
switch(temp) 
{ 
case 0x0e: 
key=0; 
break; 
case 0x0d: 
key=13; 
break; 
case 0x0b: 
key=14; 
break; 
case 0x07: 
key=15; 
break; 
} 
temp=P3; 
P1_0=~P1_0; 
P0=table[key]; 
temp=temp & 0x0f; 
while(temp!=0x0f) 
{ 
temp=P3; 
temp=temp & 0x0f; 
} 
} 
} 
} 
} 
15. 定时计数器T0作定时应用技术(一) 
1. 实验任务 
用AT89S51单片机的定时/计数器T0产生一秒的定时时间,作为秒计数时间,当一秒产生时,秒计数
加1,秒计数到60时,自动从0开始.硬件电路如下图所示 
2. 电路原理图 
AT89S51I /'? ZZZVXSHUPFXFRP
- 70 - 
4.15.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~
U /: @í@―? 
AT89S51)(,XYF…16!n /AuD< ^4 / n /AuD<¨W ^ 0ü13!n 
¨3^ 0ü16!n '8!n ~ UE E A'5B(M!^s6 , ~n /AuD<) 03E E EC 9A'nTCON(M!^s6 ,<9' ,X~ 
) ü E ‰16!n 0 ¨ bT09A¨¨ n 3 65536us¨G65.536ms¨?"'
E' L U,X1/ ,Xn ¨?!8¨ NOE E EC 9 ) E K Nl¨A' "T0,X n
50ms¨G Un 1/ L U4 E 20 ,X50ms,Xn ~ bE 20 ^ G *üEC ,X "'9
4 AuZ~ 
?!8¨ A'nTMOD 00000001B¨GTMOD 01H 
M6 U4 T0n /AuD 9NX5Bae¨E E M6,X@ ^ Au1k 
TH0 ~216 50000 /256 
TL0 ~216 50000 MOD256 
'T0ü 0,X í¨ V)k- 50ms,Xn K¨ ¨E E E #TCON(M!^s6 
,U /: u-
AT89S51I /'? ZZZVXSHUPFXFRP
- 71 - 

U !v4E# /: U A"U 
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 

⌨️ 快捷键说明

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