AT89S51的定时/计数器T0产生2秒钟的定时,每当2秒定时到来时,更换闪烁的灯,每个指示闪烁的频率为0.2秒。(即L1以0.2秒的速率闪烁,2秒定时到来时,灯L1闪过10下之后,L2开始以0.2秒的速率闪烁,如此循环下去,共4个灯,L1~L4)
(说明:定时2秒,采用16位定时50ms,共定时40次才可达到2秒,每50ms产生一中断,定时的40次数在中断服务程序中完成,同样0.2秒的定时,需要4次才可达到0.2秒。对于中断程序,在主程序中要对中断开中断。 由于每次2秒定时到时,L1-L4要交替闪烁。采用ID来号来识别。当ID=0时,L1在闪烁,当ID=1时,L2在闪烁;当ID=2时,L3在闪烁;当ID=3时,L4在闪烁 )
汇编:
TCOUNT2S EQU 30H
TCNT02S EQU 31H
ID EQU 32H
ORG 00H
LJMP START
ORG 0BH;定时/计数器T0中断入口地址为000BH,
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
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
C语言:
#include <AT89X51.H>
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;
}
}
}
流水灯(取表方式)
利用取表的方法,使P1口的灯做不同变化:左移2次,右移2次,闪烁2次(延时的时间0.2秒)。
说明:
在用表格进行程序设计的时候,要用以下的指令来完成
(1). 利用MOV DPTR,#DATA16的指令来使数据指针寄存器指到表的开头。
(2). 利用MOVC A,@A+DPTR的指令,根据累加器的值再加上DPTR的值,就可以使程序计数器PC指到表格内所要取出的数据。
因此,只要把控制码建成一个表,而利用MOVC A,@A+DPTR做取码的操作,就可方便地处理一些复杂的控制动作
汇编:
ORG 0
START: MOV DPTR,#TABLE
LOOP: CLR A
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
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
C 语言:
#include <AT89X51.H>
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;
}
}
}