4.花样流水灯

AT89S51的定时/计数器T0产生2秒钟的定时,每当2秒定时到来时,更换闪烁的灯,每个指示闪烁的频率为0.2秒。(即L10.2秒的速率闪烁,2秒定时到来时,灯L1闪过10下之后,L2开始以0.2秒的速率闪烁,如此循环下去,共4个灯,L1~L4

(说明:定时2秒,采用16位定时50ms,共定时40次才可达到2秒,每50ms产生一中断,定时的40次数在中断服务程序中完成,同样0.2秒的定时,需要4次才可达到0.2秒。对于中断程序,在主程序中要对中断开中断。 由于每次2秒定时到时,L1L4要交替闪烁。采用ID来号来识别。当ID0时,L1在闪烁,当ID1时,L2在闪烁;当ID2时,L3在闪烁;当ID3时,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

 

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,@ADPTR的指令,根据累加器的值再加上DPTR的值,就可以使程序计数器PC指到表格内所要取出的数据。

因此,只要把控制码建成一个表,而利用MOVC A,@ADPTR做取码的操作,就可方便地处理一些复杂的控制动作

汇编:

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

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;

}

}

}

你可能感兴趣的:(单片机学习,delay,汇编,table,语言)