;;;;;;;;;;;; (AT89C2051) ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;; 2006年11月26日 ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DIN BIT P3.0 ;定义变量
CLK BIT P3.1
LOAD BIT P3.7
fen0 EQU 30H ;分个位内存地址
fen1 EQU 31H ;分十位内存地址
SHI0 EQU 32H ;小时个位内存地址
SHI1 EQU 33H ;小时十位内存地址
XING EQU 34H ;星期内存地址
MIAO00 EQU 35H ;1/10秒个位内存地址
MIAO0 EQU 36H ;秒个位内存地址
MIAO1 EQU 37H ;秒十位内存地址
ORG 0000H
AJMP MAIN
ORG 0003H ;外中断0中断入口地址
RETI ;中断返回(不开中断)
ORG 000BH ;定时/计数器0中断入口
AJMP INTA ;转定时/计数器0服务程序
ORG 0013H ;外中断1中断入口地址
RETI ;中断返回(不开中断)
ORG 001BH ;定时/计数器1中断入口
AJMP INTB ;转定时/计数器1服务程序
ORG 0023H ;串行口中断入口地址
RETI ;中断返回(不开中断)
ORG 0035H
; 初始化程序
MAIN: MOV SP,#5FH
MOV A,#00H
MOV R0,#20H
CUNHUAN: MOV @R0,A ;从20H-5EH清零
INC R0
CJNE R0,#5EH,CUNHUAN
MOV TMOD,#11H ;设置T0.T1工作方式1。定时
MOV TL1,#0B0H ;置T1计数初值
MOV TH1,#3CH ;
MOV TL0,#0B0H ;置T0计数初值
MOV TH0,#3CH ;
ACALL PROCECC ;设置MAX7219初始值
MOV 43H,#0 ;设置显示初值10:30,星期1
MOV 44H,#3
MOV 4AH,#0
MOV 46H,#1
MOV 47H,#1
MOV 40H,#0
MOV 41H,#0
MOV 42H,#0
;闹钟设定时间为6:20
MOV 50H,#0
MOV 51H,#2
MOV 52H,#6
MOV 53H,#0
MOV IE,#8AH
MOV IP,#08H ;置T1为高级中断
MOV TCON,#50H ;启动T0,T1开始计数
;主程序
START: MOV A,4BH ;秒个位内存地址送A
MOV B,#2 ;2送B
DIV AB ;4BH的内容除以2
MOV A,B ;B送A
JZ M1 ;根据A中是1或0决定小数点是否闪烁
MOV 30H,43H
MOV 31H,44H
MOV A,#80H
ORL A,4AH ;加上小数点
MOV 32H,A
MOV 33H,46H
MOV 34H,47H
MOV 35H,#0fh
MOV 36H,4BH
MOV 37H,42H
AJMP M2
M1: MOV 30H,43H
MOV 31H,44H
MOV 32H,4AH
MOV 33H,46H
MOV 34H,47H
MOV 35H,#0fh
MOV A,#80H
ORL A,4BH ;加上小数点
MOV 36H,A
MOV 37H,42H
M2: ACALL C2 ;调用打开显示子程序C2
ACALL DISPLAY ;显示
MOV A,28H ;判断28H标志位是否等于0
CJNE A,#00H,A1 ;若等于零,则关T0
CLR TR0
;自动亮度调节
A1: MOV A,46H
CJNE A,#01H,B2
MOV A,4AH
CJNE A,#06H,B2
MOV A,44H
JNZ B2
MOV A,#0AH ;亮度寄存器
MOV B,#00H
ACALL W_7219 ;调节亮度
B2: MOV A,46H
JNZ A2
MOV A,4AH
CJNE A,#08H,A2
MOV A,44H
JNZ A2
MOV A,#0AH ;亮度寄存器
MOV B,#03H
ACALL W_7219 ;调节亮度
;判断调时调闹键是否被按下,若按下则置28H为1,并开T0,并调用相应的程序段
A2: JB P1.0,A3
ACALL DEL
JB P1.0,A2
MOV 28H,#01H ;调整标志位28H入1
SETB TR0
ACALL TIAOSHI
A3: JB P1.5,A4
ACALL DEL
JB P1.5,A3
MOV 28H,#01H ;调整标志位28H入1
SETB TR0
ACALL TIAONAO
;判断P1。1口是否被按下,若是则轮流显示闹钟时间和当前时间
A4: JB P1.1,G1
ACALL DEL
JB P1.1,A4
C3: ACALL C2 ;调用打开显示子程序C2
MOV 30H,50H
MOV 31H,51H
MOV A,#80H
ORL A,52H
MOV 32H,A
MOV 33H,53H
ACALL DISPLAY ;显示
CALL DELL1
MOV 30H,43H
MOV 31H,44H
MOV 32H,4AH
MOV 33H,46H
MOV 34H,47H
MOV 35H,40H
MOV 36H,4BH
MOV 37H,42H
ACALL DISPLAY ;显示
CALL DELL1
JNB P1.1,C3
ACALL C1 ;调用关灭显示子程序C1
-
-
xilinxue 发表于 2008/9/18 14:17:55
;报警
G1: JB P1.4,G2
ACALL DEL
JB P1.4,G1
JNB P1.4,$ ;等待按键松开
SETB P3.3 ;使P3.3口所接的喇叭不发声
ACALL DEL
CPL F0
MOV 5CH,#0
CPL P3.5 ;P3.5口发光二极管亮表示待报警,灭表示取消报警
G2: JNB F0,G3
JB P3.4,G3 ;P3.4口为报警检测点
ACALL DEL
JB P3.4,G2
MOV 5CH,#1
G3: MOV A,5CH
CJNE A,#1,G4
ACALL F2 ;调用报警子程序
;判断是否停市电,若是则关显示
G4: JB P3.2,A9
ACALL DEL
JB P3.2,G4
ACALL C1 ;调用关灭显示子程序C1
B3: JNB P3.2,A4
ACALL C2 ;调用打开显示子程序C2
;判断有无设定闹钟
A9: MOV A,50H
CJNE A,#00H,B4 ;如果50H,51H,52H,53H的内容不等于0,说明有
MOV A,51H ;闹钟转B4
CJNE A,#00H,B4
MOV A,52H
CJNE A,#00H,B4
MOV A,53H
CJNE A,#00H,B4
AJMP B1
;判断闹钟时间是否到
B4: MOV A,43H
CJNE A,50H,B1 ;如果43H,44H,4AH,46H的内容等于50H,51H,52H,
MOV A,44H ;53H的内容,说明闹钟时间到,程序继续往下执行
CJNE A,51H,B1
MOV A,4AH
CJNE A,52H,B1
MOV A,46H
CJNE A,53H,B1
MOV 28H,#02H ;28H标志位入2,说明闹钟时间到
CLR P1.7 ;P1.7口输出低电平,使LM386得电
SETB TR0 ;开T0
;音乐程序
NEXT: MOV DPTR,#FIRST
MOV A,5AH
MOVC A,@A+DPTR
MOV R2,A
CJNE A,#00,NEXT1
CLR TR0
SJMP NEXT
NEXT1: MOV A,R2
ANL A,#0FH
MOV R5,A
MOV A,R2
SWAP A
ANL A,#0FH
JNZ SING
CLR TR0
SJMP D1
SING: DEC A
CLR C
RL A
MOV 5BH,A
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV TH0,A
MOV 2BH,A
MOV A,5BH
ADD A,#1
MOVC A,@A+DPTR
MOV TL0,A
MOV 2AH,A
SETB TR0
D1: ACALL DELAY
CLR TR0
INC 5AH
MOV A,5AH
CJNE A,#32,F1
B1: MOV 28H,#00H ;28H入0,返回
SETB P1.7 ;P1.7口输出高电平,使LM386失电
MOV 5AH,#00H
F1: AJMP START
DELAY: MOV R7,#03
D2: MOV R4,#250
D3: MOV R3,#50H
D30: DJNZ R3,D30
DJNZ R4,D3
DJNZ R7,D2
DJNZ R5,DELAY
RET
DEL: MOV R3,#02H ;时间1ms
DELAY1: MOV R4,#0F8H
AGAIN: DJNZ R4,AGAIN
DJNZ R3,DELAY1
RETDELL1: MOV R2,#05H
DELL2: MOV R3,#0FAH
DELL3: MOV R4,#0FAH
DELL4: DJNZ R4,DELL4
DJNZ R3,DELL3
DJNZ R2,DELL2
RET
引用 xilinxue 2008/9/18 14:17:55 发表于2楼的内容
-
-
xilinxue 发表于 2008/9/18 14:18:35
定时计数器0中断程序3楼 回复本楼
INTA: PUSH ACC ;保护现场
PUSH PSW
PUSH B
CLR TR0
MOV A,28H
A7: CJNE A,#01H,NAO ;28H等于1时,转调闹,即28H等于2时,转闹钟程序
AJMP TIAO
NAO: MOV TL0,2AH
MOV TH0,2BH
CPL P1.6
AJMP A6
TIAO: ACALL DISPLAY2
INC 3AH
MOV A,3AH
CJNE A,#06H,A6
MOV 3AH,#00H
ACALL DISPLAY1
ACALL DEL
MOV TL0,#0B0H ;置T0计数初值
MOV TH0,#3CH ;
A6: SETB TR0
POP B
POP PSW
POP ACC
RETI
;定时计数器1中断程序(时间计数)
INTB: PUSH ACC
PUSH PSW
PUSH B
CLR EA ;中断同步修正
MOV A,#0B1H ;
ADD A,TL1 ;
MOV TL1,A ;
MOV A,#3CH ;
ADDC A,TH1 ;
MOV TH1,A ;
SETB EA ;中断同步修正
INC 38H
MOV A,38H
CJNE A,#02H,QUT
MOV 38H,#00H
INC 40H ;1/10秒个位内存地址+1
MOV A,40H
CJNE A,#0AH,QUT
MOV 40H,#00H
INC 4BH ;秒个位内存地址+1
MOV A,4BH
CJNE A,#0AH,QUT
MOV 4BH,#00H
INC 42H ;秒十位内存地址+1
MOV A,42H
CJNE A,#06H,QUT
MOV 42H,#00H
INC 43H ;分个位内存地址+1
MOV A,43H
CJNE A,#0AH,QUT
MOV 43H,#00H
INC 44H ;分十位内存地址+1
MOV A,44H
CJNE A,#06H,QUT
MOV 44H,#00H
INC 4AH ;时个位内存地址+1
MOV A,4AH
CJNE A,#0AH,QUT1
MOV 4AH,#00H
INC 46H ;时十位内存地址+1
MOV A,4AH
QUT1: CJNE A,#04H,QUT
MOV A,46H
CJNE A,#02H,QUT
MOV 4AH,#00H
MOV 46H,#00H
INC 47H ;星期内存地址加1
MOV A,47H ;
CJNE A,#08H,QUT ;不到星期7,退出
MOV 47H,#01H ;到星期7,星期内存地址入1
QUT: POP B
POP PSW
POP ACC
RETI
;当前时间调整
TIAOSHI: CLR TR1
MOV R0,#20H
MOV R7,#01H
MOV 29H,#00H
LP0: JB P1.2,NEXT0
ACALL DEL
JB P1.2,LP0
LP1: JNB P1.2,LP1
INC 29H
SJMP EE
NEXT0: JB P1.3,DD
ACALL DEL
JB P1.3,NEXT0
LD1: JNB P1.3,LD1
ACALL DEL
LCALL DISPLAY1
MOV 29H,#00H
INC R7
INC R0
MOV A,R7
CJNE A,#06H,EE
LJMP LL
DD: LJMP L1
EE: MOV A,29H
CJNE A,#0AH,LA1
MOV 29H,#00H
LA1: MOV @R0,29H
AJMP L1
QIAO: AJMP LP0
L1: MOV A,R7
CJNE A,#06H,QIAO
LL: MOV 43H,20H
MOV 44H,21H
MOV 4AH,22H
MOV 46H,23H
MOV 47H,24H
MOV 40H,#0
MOV 4BH,#0
MOV 42H,#0
MOV 28H,#00H ;调整结束后28H入0,返回
MOV TL1,#0B0H ;重置T1计数初值
MOV TH1,#3CH
SETB TR1
RET
引用 xilinxue 2008/9/18 14:18:35 发表于3楼的内容
-
-
xilinxue 发表于 2008/9/18 14:19:11
;闹钟时间调整4楼 回复本楼
TIAONAO: MOV R0,#50H
MOV R7,#01H
MOV 29H,#00H
LP0B: JB P1.2,NEXT0B
ACALL DEL
JB P1.2,LP0B
LP1B: JNB P1.2,LP1B
INC 29H
SJMP EEB
NEXT0B: JB P1.3,DDB
ACALL DEL
JB P1.3,NEXT0B
LD1B: JNB P1.3,LD1B
ACALL DEL
LCALL DISPLAY1
MOV 29H,#00H
INC R7
INC R0
MOV A,R7
CJNE A,#05H,EEB
LJMP LLB
DDB: LJMP L1B
EEB: MOV A,29H
CJNE A,#0AH,LA1B
MOV 29H,#00H
LA1B: MOV @R0,29H
AJMP L1B
QIAOB: AJMP LP0B
L1B: MOV A,R7
CJNE A,#05H,QIAOB
LLB: MOV TL0,#0B0H ;重置T0计数初值
MOV TH0,#3CH
MOV 28H,#00H ;调整结束后28H入0,返回
RET
;;;各子程序
C1: MOV A,#0CH ;关灭寄存器
MOV B,#00H ;取值为0或1.为1正常操作;为0关灭
LCALL W_7219
RET
C2: MOV A,#0CH ;关灭寄存器
MOV B,#01H ;取值为0或1.为1正常操作;为0关灭
LCALL W_7219
RET
F2: PUSH PSW
SETB RS0
SETB RS1
MOV R0,#200
F3: MOV R1,#240
DJNZ R1,$
DJNZ R0,F3
CPL P3.3 ;P3.3口接报警喇叭
POP PSW
RET
;MAX7219初始化子程序
PROCECC : MOV A,#0BH ;扫描寄存器 (显示位数)
MOV B,#07H ;取值由 00-07 ,分别表示显?1- 8
LCALL W_7219
MOV A,#09H ;译码模式寄存器
MOV B,#0FFH
LCALL W_7219
MOV A,#0AH ;亮度寄存器
MOV B,#03H
LCALL W_7219
MOV A,#0CH ;关灭寄存器
MOV B,#01H ;取值为0或1.为1正常操作;为0关灭
LCALL W_7219
RET
;MAX7219显示子程序
DISPLAY: MOV R0,#FEN0
MOV R4,#01H
MOV R3,#08H
C_DISP: MOV A,@R0
MOV B,A
MOV A,R4
LCALL W_7219
INC R0
INC R4
DJNZ R3,C_DISP
RET
W_7219: CLR LOAD
LCALL SD_7219
MOV A,B
LCALL SD_7219
SETB LOAD
RET
SD_7219: MOV R6,#08H
C_SD: NOP
CLR CLK
RLC A
MOV DIN,C
NOP
SETB CLK
DJNZ R6,C_SD
RET
DISPLAY1: MOV A,R7
MOV B,29H
ACALL W_7219
RET
DISPLAY2: MOV A,R7
MOV B,#0FH
ACALL W_7219
RET
FIRST: DB 82H,01H,81H,94H,84H,0B4H,0A4H,04H ;音乐编码
DB 82H,01H,81H,94H,84H,0C4H,0B4H,04H
DB 82H,01H,81H,0F4H,0D4H,0B4H,0A4H,94H ;
DB 0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H
TABLE: DB 0F6H,6FH,0F7H,24H,0F8H,1BH,0F8H,8FH
DB 0F9H,5EH,0FAH,17H,0FAH,6BH,0FBH,08H
DB 0FBH,92H,0FCH,0EH,0FCH,4BH,0FCH,0AFH
DB 0FDH,0CH,0FDH,36H,0FDH,84H,0FDH,0C9H
END
引用 xilinxue 2008/9/18 14:19:11 发表于4楼的内容