AT89C2051单片机做节日彩灯控制电路程序

;***************************************************

;*     用单片机89C2051制作的延时控制器      *

;*      T0、TT0配合构成为秒脉冲发生器              *

;*      TSBIN 为秒计数器(二进制,0~60) ;21H单元  *

;*      TMBIN 为分计数器(二进制,0~60) ;22H单元  *

;*      THBIN 为时计数器(二进制,0~24) ;23H单元  *

;*      KEYCODE 为键盘值;29H单元                  *

;*      KEYPRE 为按键标志字;PSW.5                 *

;*      当倒计时至00H00M00S 时,P3.0, P3.1端输出   *

;*      反相信号。                                 *

;*      S1----对时按钮;S2--对分按钮;           *

;*      S3--对秒按钮;S4--退出对时             *  

;***************************************************

 TMSBIN EQU 20H

 TSBIN EQU 21H

 TMBIN EQU 22H

 THBIN EQU 23H

 KEYCODE EQU 29H

 TT0 EQU 2BH

 OUT EQU 2DH

 KEYPRE BIT PSW.5

 

 DPS1 DATA 11001111B ;S4

 DPM0 DATA 11010111B ;S3

 DPM1 DATA 11011111B ;S2

 DPH0 DATA 11100111B ;S1

 DPH1 DATA 11101111B

 HIDE DATA 11111111B ;消隐字

 ORG 0000H

 AJMP MAIN

 ORG 000BH

 SJMP I_T0

 ORG 001BH

I_T1: AJMP MAIN1

 RETI

;***********   T0中断服务    ***********

 ORG 0030H

I_T0: PUSH ACC

 PUSH PSW

 MOV TH0,#0DCH  ;0.01s时间,常数因子为DC00H

 ;MOV TL0,#00H 

 CLR C

 MOV A,TMSBIN

 SUBB A,#01H

 MOV TMSBIN,A

 MOV R3,TT0  

 DJNZ R3,I_T01  ;中断次数<100(每次中断0.01S),转出

 CPL KEYPRE

 MOV R3,#100  ;中断次数=100次,重新下一个计数

 MOV TMSBIN,#100

 CLR C

 MOV A,TSBIN  ;秒计数器加1

 SUBB A,#01H

 MOV TSBIN,A

 ;SUBB A,#60   ;秒计数器>59?  Y,秒计数器=00

 JNC I_T01

 MOV A,TMBIN

 ADD A,THBIN

 JNZ M1

 MOV OUT,#11111101B

 CLR TR0

 MOV TSBIN,#00H

 SJMP I_T01

M1: MOV TSBIN,#59

 CLR C

 MOV A,TMBIN  ;分计数器加1

 SUBB A,#01H

 MOV TMBIN,A

 JNC I_T01

 MOV A,THBIN

 JZ I_T01

 MOV TMBIN,#59

 CLR C

 MOV A,THBIN  ;时计数器加1

 SUBB A,#01H

 MOV THBIN,A

 ;SUBB A,#24  ;时计数器>23? Y,时计数器=00

 JNC I_T01

 MOV THBIN,#00H

I_T01: MOV TT0,R3

 POP PSW

 POP ACC

 RETI

 ORG 00F0H

MAIN: MOV P1,#0FFH

 MOV OUT,#11111110B    ;P3.0输出低电平

 MOV P3,OUT

 MOV SP,#40H  ;初始化堆栈指针  

 MOV TMOD,#11H  ;T0、T1工作于16为定时器

 MOV TT0,#100

 MOV TH0,#0DCH  ;T0初值

 MOV TL0,#00H

 MOV TH1,#00H  ;T1初值

 MOV TL1,#00H

 MOV TSBIN,#59

 MOV TMBIN,#59

 MOV THBIN,#23

 CLR EX0

 CLR EX1

 CLR ES

 SETB ET0  ;开T0、T1中断

 SETB ET1

 SETB TR0

 SETB TR1

 SETB EA

MAIN1: MOV R6,#80H  ;主处理过程

DISP: MOV KEYCODE,#00H

 MOV TH1,#00H

 MOV TL1,#00H

 ACALL DISPLY  ;调用显示子程序

 DJNZ R6,DISP

 MOV DPTR,#KEY

 MOV A,KEYCODE  ;读键盘值

 JMP @A+DPTR  ;按键值跳相应处理程序

KEY: SJMP MAIN1

 SJMP KEY1         ;依次为:KEY值+2,4,6,8,因为SJMP占2个字节

 SJMP KEY2         ;S1的KEYCODE=02H,S2: KEYCODE=04H

 SJMP KEY3         ;S3: KEYCODE=06H, S4: KEYCODE=08H

 SJMP KEY4

KEY1: CLR TR0   ;时计数器加1

 MOV A,THBIN

 CLR C

 ADDC A,#01H

 MOV THBIN,A

 SUBB A,#24  ;24D

 JC KEY11

 MOV THBIN,#00H

KEY11:  SJMP MAIN1

 NOP

KEY2: CLR TR0   ;分计数器加1

 MOV A,TMBIN

 CLR C

 ADDC A,#01H

 MOV TMBIN,A

 SUBB A,#60  ;60D

 JC KEY21

 MOV TMBIN,#00H

KEY21:  SJMP MAIN1

 NOP

KEY3: CLR TR0   ;秒计数器加1

 MOV A,TSBIN

 CLR C

 ADDC A,#01H

 MOV TSBIN,A

 SUBB A,#60  ;60D

 JC KEY31

 MOV TSBIN,#00H

KEY31:  SJMP MAIN1 

 NOP

KEY4: MOV TH0,#0DCH  ;退出校时状态

 MOV TL0,#00H

 SETB TR0

 SJMP MAIN1

; **********    显示子程序    **************

     ORG 0200H  

DISPLY: MOV A,TSBIN  ;秒计数器调入A

 MOV B,#0AH

 DIV AB    ;秒计数值÷10 (结果十位存于A,个位存于B) 

 SWAP A

 ORL A,#07H  ;显示秒的十位

 MOV P1,A

 MOV A,#DPS1

 ANL A,OUT

 MOV P3,A

 ACALL DSPDEL  ;延时(显示时)0.5ms

 MOV C,P3.7  ;读S4按键状态

 MOV A,#HIDE

 ANL A,OUT

 MOV P3,A

 JC NP1

 MOV KEYCODE,#08H ;S4按下,键盘值=8 

NP1: MOV P1,#0F7H  ;消隐

 NOP

 NOP

 NOP

 MOV A,B   ;显示秒的个位

 SWAP A

 ORL A,#07H

 MOV P1,A

 MOV A,#DPS0

 ANL A,OUT

 MOV P3,A

 ACALL DSPDEL

 MOV A,#HIDE

 ANL A,OUT

 MOV P3,A

 NOP

 NOP

 NOP

 MOV A,TMBIN  ;

 MOV B,#0AH

 DIV AB   ;

 SWAP A   ;显示分的十位

 ORL A,#07H

 MOV P1,A

 MOV A,#DPM1

 ANL A,OUT

 MOV P3,A

 ACALL DSPDEL

 MOV C,P3.7  ;检测S2是否按下

 MOV A,#HIDE

 ANL A,OUT

 MOV P3,A

 JC NP2

 MOV KEYCODE,#04H ;S2按下,键盘值=4

 NOP

NP2: MOV P1,#0F7H  ;消隐

 NOP

 NOP

 MOV A,B

 SWAP A   ;显示分的个位

 ORL A,#07H

 MOV P1,A

 ;MOV C,KEYPRE

 ;MOV P1.3,C

 SETB P1.3

 MOV A,#DPM0

 ANL A,OUT

 MOV P3,A

 ACALL DSPDEL

 MOV C,P3.7  ;判断S3是否按下

 MOV A,#HIDE

 ANL A,OUT

 MOV P3,A

 JC NP3

 MOV KEYCODE,#06H ;若S3按下,键盘值=6

 NOP  

NP3: MOV P1,#0F7H  ;消隐

 NOP

 NOP

 MOV A,THBIN  ;

 MOV B,#0AH 

 DIV AB   ;

 SWAP A   ;显示时的十位

 JNZ DISPLY1

 MOV A,#0F7H

DISPLY1:ORL A,#07H

 MOV P1,A

 MOV A,#DPH1

 ANL A,OUT

 MOV P3,A

 ACALL DSPDEL

 MOV A,#HIDE

 ANL A,OUT

 MOV P3,A

 NOP

 MOV A,B

 SWAP A   ;显示时的个位

 ORL A,#07H

 ANL A,OUT

 MOV P1,A

 SETB P1.3

 MOV A,#DPH0

 ANL A,OUT

 MOV P3,A

 ACALL DSPDEL

 MOV C,P3.7  ;判断S1是否按下

 MOV A,#HIDE

 ANL A,OUT

 MOV P3,A

 JC NP4

 MOV KEYCODE,#02H ;S1按下,键盘值=2

 NOP

NP4: MOV P1,#0F7H  ;消隐

 NOP

 NOP

 NOP

 RET

;**********    延时子程序    **************8

DSPDEL: MOV R7,#0FFH  ;延时程序0.5ms

 DJNZ R7,$

 RET

 END