📄 汇编语言电子钟.asm
字号:
;模式: MODE0,代表正常
; MODE1,代表闹钟小时校正
; MODE2,代表闹钟分钟校正
; MODE3,代表时钟小时设置
; MODE4,代表时钟分钟设置
; MODE5,代表秒表计时
;指示灯: D0亮表示目前是闹钟调整状态,
; D1亮表明目前是时间校正状态,
; D3亮表示目前是秒表计时状态。
; 正常模式下灯都不亮
;秒表计时:K2控制毫妙表计时,K3控制秒表计时 ,
; 秒表状态下,按下K2/K3开始计时,再按下暂停计时
; 按模式选择键K1推出秒表模式,回到普通模式
;闹钟: 闹铃后按K2键停止响铃
;****************************************************************
;对不同的名称字符赋值
;****************************************************************
;LED数码管存储单元
LED1 EQU 60H
LED2 EQU 61H
LED3 EQU 62H
LED4 EQU 63H
;时钟存储单元
H_RG EQU 64H ;小时寄存器
M_RG EQU 65H ;分钟寄存器
SCAN EQU 66H ;扫描计数器
MODE_RG EQU 67H ;模式寄存器
CLK_H_RG EQU 68H ;闹钟时
CLK_M_RG EQU 69H ;闹钟分
COUNT0 EQU 6AH
COUNT1 EQU 6BH
LED_FLASH EQU 6CH ;闪烁效果
DELAY_BUF0 EQU 6DH
DELAY_BUF1 EQU 6EH
DELAY_BUF2 EQU 6FH
POINT_FLASH_BUF0 EQU 70H ;中间两点闪烁
POINT_FLASH_BUF1 EQU 71H
DELAY_BUF3 EQU 72H
DELAY_BUF4 EQU 73H
TIMER_S_RG EQU 74H ;秒表的秒
TIMER_MS_RG EQU 75H ;秒表的毫秒
FLAG EQU 20H
FLAG1 EQU 21H
MILISECOND_TIMER_FLAG EQU 22H ;毫秒
SECOND_TIMER_FLAG EQU 23H ;标志位
;****************************************************************
;主程序及其初值化程序
;****************************************************************
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP INT_T0 ;定时器0用来时钟计数
ORG 001BH
LJMP INT_T1 ;定时器1用来轮流显示4个LED
ORG 0030H
MAIN: MOV SP,#2FH
MOV IE,#10001010B
MOV IP,#0
MOV TMOD,#00010001B ;两个定时器都工作于方式1
SETB TR0
SETB TR1
MOV TH0,#0D8H ;每次中断10毫秒,6000次中断等于一分钟
MOV TL0,#0F0H
MOV TH1,#0F6H
MOV TL1,#3CH
MOV COUNT0,#100
MOV COUNT1,#60
MOV H_RG,#00
MOV M_RG,#00
MOV CLK_H_RG,#00
MOV CLK_M_RG,#00
MOV TIMER_S_RG,#0
MOV TIMER_MS_RG,#0
MOV MODE_RG,#0
MOV SCAN,#0
MOV LED_FLASH,#24
MOV FLAG,#0
MOV FLAG1,#0
CLR MILISECOND_TIMER_FLAG
CLR SECOND_TIMER_FLAG
MOV POINT_FLASH_BUF0,#120
MOV POINT_FLASH_BUF1,#40
WAIT: LCALL TURNBCTD_H
LCALL TURNBCTD_M
LCALL KEY_SCAN
SJMP WAIT
;****************************************************************
;显示程序,BCD码转为显示码(R6 R7-->LED1 LED2 LED3 LED4)
;****************************************************************
TURNBCTD_H: MOV A,MODE_RG
CJNE A,#1,IF_EQU_2_H
SETB TR0
JNB FLAG,SET_CLK_HOUR ;FLAG为1时LED不亮
MOV LED1,0FFH
MOV LED2,0FFH
RET
IF_EQU_2_H: CJNE A,#2,IF_EQU_3_H
SETB TR0
LJMP SET_CLK_HOUR
IF_EQU_3_H: CJNE A,#3,IF_EQU_4_H ;此时为普通时间设置模式,应该调用SET_HOUR
CLR TR0 ;关定时器
JNB FLAG,SET_HOUR
MOV LED1,0FFH
MOV LED2,0FFH
RET
IF_EQU_4_H: CJNE A,#4,IF_EQU_5_H ;看是不是模式5
CLR TR0
LJMP SET_HOUR ;正常时间模式,调用SET_HOUR
IF_EQU_5_H: CJNE A,#5,SET_HOUR ;正常模式时当然也是显示时间设置的内容
SETB TR0
LJMP SET_TIMER_S
TURNBCTD_M: MOV A,MODE_RG
CJNE A,#1,IF_EQU_2_M
SETB TR0
LJMP SET_CLK_MINUTE
IF_EQU_2_M: CJNE A,#2,IF_EQU_3_M
SETB TR0
JNB FLAG,SET_CLK_MINUTE
MOV LED3,0FFH
MOV LED4,0FFH
RET
IF_EQU_3_M: CJNE A,#3,IF_EQU_4_M
CLR TR0
LJMP SET_MINUTE
IF_EQU_4_M: CJNE A,#4,IF_EQU_5_M
CLR TR0
JNB FLAG,SET_MINUTE
MOV LED3,0FFH
MOV LED4,0FFH
RET
IF_EQU_5_M: CJNE A,#5,SET_MINUTE
SETB TR0
LJMP SET_TIMER_MS
SET_HOUR: MOV R7,H_RG
LCALL BCTD
MOV DPTR,#LED_CODE
MOV A,R4
ANL A,#0FH
MOVC A,@A+DPTR
MOV LED2,A
MOV A,R4
ANL A,#0F0H
SWAP A
MOVC A,@A+DPTR
MOV LED1,A
RET
SET_CLK_HOUR: MOV R7,CLK_H_RG
LCALL BCTD
MOV DPTR,#LED_CODE
MOV A,R4
ANL A,#0FH
MOVC A,@A+DPTR
MOV LED2,A
MOV A,R4
ANL A,#0F0H
SWAP A
MOVC A,@A+DPTR
MOV LED1,A
RET
SET_MINUTE: MOV R7,M_RG
LCALL BCTD
MOV DPTR,#LED_CODE
MOV A,R4
ANL A,#0FH
MOVC A,@A+DPTR
MOV LED4,A
MOV A,R4
ANL A,#0F0H
SWAP A
MOVC A,@A+DPTR
MOV LED3,A
RET
SET_CLK_MINUTE: MOV R7,CLK_M_RG
LCALL BCTD
MOV DPTR,#LED_CODE
MOV A,R4
ANL A,#0FH
MOVC A,@A+DPTR
MOV LED4,A
MOV A,R4
ANL A,#0F0H
SWAP A
MOVC A,@A+DPTR
MOV LED3,A
RET
SET_TIMER_MS: MOV R7,TIMER_MS_RG
LCALL BCTD
MOV DPTR,#LED_CODE
MOV A,R4
ANL A,#0FH
MOVC A,@A+DPTR
MOV LED4,A
MOV A,R4
ANL A,#0F0H
SWAP A
MOVC A,@A+DPTR
MOV LED3,A
RET
SET_TIMER_S: MOV R7,TIMER_S_RG
LCALL BCTD
MOV DPTR,#LED_CODE
MOV A,R4
ANL A,#0FH
MOVC A,@A+DPTR
MOV LED2,A
MOV A,R4
ANL A,#0F0H
SWAP A
MOVC A,@A+DPTR
MOV LED1,A
RET
;****************************************************************
;键盘扫描程序
;****************************************************************
KEY_SCAN: JNB P3.2,GO_MODE
JNB P3.3,GO_UP
JNB P3.4,GO_DOWN
RET
GO_MODE: CLR P1.2
LCALL BUTTON_SOUND_DELAY0
SETB P1.2
INC MODE_RG
MOV A,MODE_RG
CJNE A,#6,GO_MODE1
MOV MODE_RG,#0
GO_MODE1: JNB P3.2,GO_MODE1
MOV A,MODE_RG
SJMP CHK_MODE
CHK_MODE: MOV A,MODE_RG ;检查模式
CJNE A,#1,IF_EQU2
CLR P1.0 ;发光二极管D1亮时表示目前是闹钟设置模式
SETB P1.1
SETB P1.3
JNB P3.3,GO_UP
JNB P3.4,GO_DOWN
SJMP EXIT
GO_UP: CLR P1.2
LCALL BUTTON_SOUND_DELAY0
SETB P1.2
MOV A,MODE_RG ;判断是什么模式
CJNE A,#1,CHK_IF_UPMODE2
LJMP UP_CLK_H
GO_DOWN: CLR P1.2
LCALL BUTTON_SOUND_DELAY0
SETB P1.2
MOV A,MODE_RG
CJNE A,#1,CHK_IF_DNMODE2
LJMP DOWN_CLK_H
IF_EQU2: CJNE A,#2,IF_EQU3
CLR P1.0
SETB P1.1
JNB P3.3,GO_UP
JNB P3.4,GO_DOWN
SJMP EXIT
IF_EQU3: CJNE A,#3,IF_EQU4 ;发光二极管D2亮时表示目前是时间设置模式
CLR TR0
SETB P1.0
SETB P1.3
CLR P1.1
JNB P3.3,GO_UP
JNB P3.4,GO_DOWN
SJMP EXIT
IF_EQU4: CJNE A,#4,IF_EQU5 ;此时为模式0????
CLR TR0
SETB P1.0
SETB P1.3
CLR P1.1
JNB P3.3,GO_UP
JNB P3.4,GO_DOWN
SJMP EXIT
IF_EQU5: CJNE A,#5,NOMAL_MODE
CLR P1.3
SETB P1.0
SETB P1.1
SETB P1.2
MOV TIMER_MS_RG,#0 ;每次计时完都要把计时存储单元清零
MOV TIMER_S_RG,#0
CLR MILISECOND_TIMER_FLAG
CLR SECOND_TIMER_FLAG
JNB P3.3,GO_MILISECOND_TIMER_MODE ;这句只是要来防抖的.
JNB P3.4,GO_SECOND_TIMER_MODE
SJMP EXIT
NOMAL_MODE: SETB P1.3
RET
EXIT: SETB TR0
RET
CHK_IF_UPMODE2: CJNE A,#2,CHK_IF_UPMODE3 ;查看模式1
LJMP UP_CLK_M
CHK_IF_UPMODE3: CJNE A,#3,CHK_IF_UPMODE4
LJMP UP_SET_H
CHK_IF_UPMODE4: CJNE A,#4,CHK_IF_UPMODE5 ;MODE 4,EXIT
LJMP UP_SET_M
CHK_IF_UPMODE5: CJNE A,#5,EXIT
LJMP GO_MILISECOND_TIMER_MODE
GO_MILISECOND_TIMER_MODE:
CPL MILISECOND_TIMER_FLAG ;START TIMING
GO_MILISECOND_TIMER_MODE1:
JNB P3.3,GO_MILISECOND_TIMER_MODE1
RET
CHK_IF_DNMODE2: CJNE A,#2,CHK_IF_DNMODE3 ;判断是模式1
LJMP DOWN_CLK_M
CHK_IF_DNMODE3: CJNE A,#3,CHK_IF_DNMODE4
LJMP DOWN_SET_H
CHK_IF_DNMODE4: CJNE A,#4,CHK_IF_DNMODE5
LJMP DOWN_SET_M
CHK_IF_DNMODE5: CJNE A,#5,EXIT
LJMP GO_SECOND_TIMER_MODE
GO_SECOND_TIMER_MODE:
CPL SECOND_TIMER_FLAG
GO_SECOND_TIMER_MODE1:
JNB P3.4,GO_SECOND_TIMER_MODE1
RET
UP_CLK_H: INC CLK_H_RG
MOV A,CLK_H_RG
CJNE A,#24,UP_CLK_H1
MOV CLK_H_RG,#0
UP_CLK_H1: JNB P3.3,UP_CLK_H1
RET
UP_CLK_M: INC CLK_M_RG
MOV A,CLK_M_RG
CJNE A,#60,UP_CLK_M1
MOV CLK_M_RG,#0
INC CLK_H_RG
MOV A,CLK_H_RG
CJNE A,#24,UP_CLK_M1
MOV CLK_H_RG,#0
UP_CLK_M1: JNB P3.3,UP_CLK_M1
RET
UP_SET_M: INC M_RG
MOV A,M_RG
CJNE A,#60,UP_SET_M1
MOV M_RG,#0
INC H_RG
UP_SET_M1: JNB P3.3,UP_SET_M1
RET
UP_SET_H: INC H_RG
MOV A,H_RG
CJNE A,#24,UP_SET_H1
MOV H_RG,#0
UP_SET_H1: JNB P3.3,UP_SET_H1
RET
DOWN_CLK_M: DEC CLK_M_RG
MOV A,CLK_M_RG
CJNE A,#0FFH,DOWN_CLK_M1
MOV CLK_M_RG,#59
DEC CLK_H_RG
MOV A,CLK_H_RG
CJNE A,#0FFH,DOWN_CLK_M1
MOV CLK_H_RG,#0
DOWN_CLK_M1: JNB P3.4,DOWN_CLK_M1
SETB TR0
RET
DOWN_CLK_H: DEC CLK_H_RG
MOV A,CLK_H_RG
CJNE A,#0FFH,DOWN_CLK_H1
MOV CLK_H_RG,#23
DOWN_CLK_H1: JNB P3.4,DOWN_CLK_H1
SETB TR0
RET
DOWN_SET_M: DEC M_RG
MOV A,M_RG
CJNE A,#0FFH,DOWN_SET_M1
MOV M_RG,#59
DEC H_RG
DOWN_SET_M1: JNB P3.4,DOWN_SET_M1
SETB TR0
RET
DOWN_SET_H: DEC H_RG
MOV A,H_RG
CJNE A,#0FFH,DOWN_SET_H1
MOV H_RG,#23
DOWN_SET_H1: JNB P3.4,DOWN_SET_H1
SETB TR0
RET
;****************************************************************
;中断服务程序INT_T0
;****************************************************************
INT_T0: PUSH ACC
PUSH PSW
PUSH DPL
PUSH DPH
MOV TH0,#0D8H
MOV TL0,#0F0H ;恢复时间常数
JNB MILISECOND_TIMER_FLAG,DO_NOT_MILISECOND_TIME
;秒表开始计时标签,为0时就直接跳过秒表,为1时就计时
INC TIMER_MS_RG
MOV A,TIMER_MS_RG
CJNE A,#100,DO_NOT_MILISECOND_TIME
MOV TIMER_MS_RG,#0
INC TIMER_S_RG
MOV A,TIMER_S_RG
CJNE A,#100,DO_NOT_MILISECOND_TIME
MOV TIMER_S_RG,#0
DO_NOT_MILISECOND_TIME:
DJNZ COUNT0,EXIT_T0
MOV COUNT0,#24
JNB SECOND_TIMER_FLAG,DO_NOT_SECOND_TIME
INC TIMER_MS_RG
MOV A,TIMER_MS_RG
CJNE A,#60,DO_NOT_SECOND_TIME
MOV TIMER_MS_RG,#0
INC TIMER_S_RG
MOV A,TIMER_S_RG
CJNE A,#60,DO_NOT_SECOND_TIME
MOV TIMER_S_RG,#0
DO_NOT_SECOND_TIME:
DJNZ COUNT1,EXIT_T0
MOV COUNT1,#60
INC M_RG
MOV A,M_RG
CJNE A,#60,CMP
MOV M_RG,#0
INC H_RG
MOV A,H_RG
CJNE A,#24,CMP
MOV H_RG,#0
CMP: MOV A,CLK_M_RG ;比较是否到了闹铃时刻
CJNE A,M_RG,EXIT_T0
MOV A,CLK_H_RG
CJNE A,H_RG,EXIT_T0
CPL P1.2
LCALL CLOCK_DELAY
SETB P1.2
EXIT_T0: POP DPH
POP DPL
POP PSW
POP ACC
RETI
;****************************************************************
;中断服务程序INT_T1
;****************************************************************
INT_T1: PUSH ACC
PUSH PSW
PUSH DPL
PUSH DPH
SETB RS0
SETB RS1
MOV TH1,#0F6H ; ?ms的中断
MOV TL1,#3CH
DJNZ POINT_FLASH_BUF0,IF_POINT_FLASH
MOV POINT_FLASH_BUF0,#120
CPL FLAG1
IF_POINT_FLASH: JNB FLAG1,NO_POINT_FLASH
MOV A,LED2
CLR ACC.7
MOV LED2,A
NO_POINT_FLASH: DJNZ LED_FLASH,SET_LED
MOV LED_FLASH,#100
CPL FLAG
SET_LED: MOV DPTR,#SCAN_TABLE ;LED扫描显示
MOV A,SCAN
ADD A,SCAN
MOVC A,@A+DPTR
MOV R0,A
MOV A,@R0
MOV P0,A
MOV A,SCAN
ADD A,SCAN
INC DPTR
MOVC A,@A+DPTR
MOV P2,A ;选通LED
INC SCAN
MOV A,SCAN
CJNE A,#4,EXIT_T1
MOV SCAN,#0
EXIT_T1: POP DPH
POP DPL
POP PSW
POP ACC
RETI
;****************************************************************
;二进制转十进制..(R6R7-->R2R3R4)
;****************************************************************
BCTD: MOV R5,#16
CLR A
MOV R2,A
MOV R3,A
MOV R4,A
LOOP: CLR C
MOV A,R7
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
MOV A,R3
ADDC A,R3
DA A
MOV R3,A
MOV A,R2
ADDC A,R2
DA A
MOV R2,A
DJNZ R5,LOOP
RET
;****************************************************************
;延时程序,用于闹钟延时
;****************************************************************
CLOCK_DELAY: MOV DELAY_BUF0,#255
MOV DELAY_BUF1,#255
MOV DELAY_BUF2,#255
GO_NOP: NOP
JNB P3.3,SHUT_CLOCK
JNB P3.4,SHUT_CLOCK
DJNZ DELAY_BUF0,GO_NOP
DJNZ DELAY_BUF1,GO_NOP
DJNZ DELAY_BUF2,GO_NOP
MOV DELAY_BUF0,#255
MOV DELAY_BUF1,#255
MOV DELAY_BUF2,#255
SHUT_CLOCK: RET
BUTTON_SOUND_DELAY0:
MOV DELAY_BUF3,#2
MOV DELAY_BUF4,#100
GO_NOP1: DJNZ DELAY_BUF3,GO_NOP1
DJNZ DELAY_BUF4,GO_NOP1
MOV DELAY_BUF3,#2
MOV DELAY_BUF4,#100
RET
;****************************************************************
;数码表
;****************************************************************
LED_CODE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H
DB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH
;****************************************************************
;扫描控制表
;****************************************************************
SCAN_TABLE: DB LED4,1110B
DB LED3,1101B
DB LED2,1011B
DB LED1,0111B
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -