📄 cj.asm
字号:
; E2004b_e.asm
; 偶数组号
; (Electronic Calendar and Clock)
; Reference for Grade 2004, s.c.u.t.
; Key0(for shift/adjust) connected to INT1
; Key1(for un-flash/flash) connected to INT0
; Revised by Jerry Lin
; 2007.3
; 学生姓名:
; 学生学号:
; 分组编号:
;变量定义
TICK_CNT EQU 20H ;T0溢出计数器
SECOND_BCD EQU 21H
MINUTE_BCD EQU 22H
HOUR_BCD EQU 23H
DAY_BCD EQU 24H
MONTH_BCD EQU 25H
YEAR_BCD EQU 2H
ASCON EQU 27H
AMIN EQU 28H
AHOUR EQU 29H
MSS EQU 2AH
MSCON EQU 2BH
MMIN EQU 2CH
MFLAG EQU 31H
FLASH_FLAG EQU 2DH
;R7: 0-时间;1-日期
;中断向量表
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP EX0_INT ; port INT0
ORG 000BH
LJMP T0_INT ; port T0
ORG 0013H
LJMP EX1_INT ; port INT1
;主程序
ORG 0040H
MAIN: NOP ; main program
;初始化堆栈
MOV SP,#60H
;初始化变量
MOV SECOND_BCD,#00H ; BCD of "second"
MOV MINUTE_BCD,#30H ; BCD of "minute"
MOV HOUR_BCD,#10H ; BCD of "hour"
MOV DAY_BCD,#24H ; BCD of "day"
MOV MONTH_BCD,#11H ; BCD of "month"
MOV YEAR_BCD,#08H ; BCD of "year"
MOV ASCON,#00H
MOV AMIN,#31H
MOV AHOUR,#10H
MOV MMIN,#00H
MOV MSCON,#00H
MOV MSS,#00H
MOV FLASH_FLAG,#00H ; flag for un-flash/flash
MOV MFLAG,#00H
MOV R7,#00H ; flag for shift(time/date)
;
MOV TL0,#0B0H ; constant for 0.1s
MOV TH0,#3CH ; 50,000 for 6MHz
MOV TICK_CNT,#14H ; times of overflow
MOV TMOD,#01H ; Mode 1 for T0, Timer Mode
SETB ET0 ; open T0
SETB EX0 ; open INT0, Key1
SETB EX1 ; open INT1, Key0
SETB EA ; total open
SETB PT0 ; priority for T0,高优先级
SETB TR0 ; start T0, Run
SJMP $ ; wait for interrupt
; -------------------------------------------------
; sub: T0 interrupt
; 定时器0中断
T0_INT: MOV A,MFLAG
CJNE A,0FFH,NORM
MOV TL0,#0F0H
MOV TH0,#0D8H
MOV A,MSS
INCMSS: CJNE A,#99H,MIN1 ; is up to 59 seconds ?
SJMP MIN2 ; 0.01秒进位
MIN1: ADD A,#01H
DA A
MOV MSS,A
LJMP T0_RET
MIN2: MOV MSS,#00H
MOV A,MSCON ; take BCD of "minute"
CJNE A,#59H,MIN3 ; is up to 59 minutes ?
SJMP MIN4
MIN3: ADD A,#01H
DA A
MOV MSCON,A
LJMP T0_RET
MIN4: MOV MSCON,#00H ; 分进位
MOV A,MMIN ; take BCD of "hour"
CJNE A,#59H,MIN5 ; is up to 23 hours ?
MOV MMIN,#00H ; “时”进位
LJMP T0_RET
MIN5: ADD A,#01H
DA A
MOV MMIN,A
LJMP T0_RET
NORM: MOV TL0,#0B0H ; constant for 0.05s
MOV TH0,#3CH ; Timer 0重装载
DJNZ TICK_CNT,NOT_1S ; is up to 1 second ?
SJMP IS_1S
NOT_1S: LJMP T0_RET
; 1秒时间到
IS_1S: MOV A,SECOND_BCD ; take BCD of "second"
CJNE A,#59H,IN3 ; is up to 59 seconds ?
SJMP IN4
IN3: LJMP SECOND_INC ; 秒加1
IN4: MOV SECOND_BCD,#00H ; 秒进位
MOV A,MINUTE_BCD ; take BCD of "minute"
CJNE A,#59H,IN5 ; is up to 59 minutes ?
SJMP IN6
IN5: LJMP MINUTE_INC
IN6: MOV MINUTE_BCD,#00H ; 分进位
MOV A,HOUR_BCD ; take BCD of "hour"
CJNE A,#23H,HOUR_INC ; is up to 23 hours ?
MOV HOUR_BCD,#00H ; “时”进位
MOV A,MONTH_BCD ; take BCD of "month"
CJNE A,#02H,NOT_FEB ; is February ?
;2月处理
;--------------------------
FEB: NOP
ACALL BCD_DIV4 ; BCD of "year in 26H" divided by 4
MOV A,R3 ; remainder in R3
CJNE A,#00H,NOT_LEAP_Y ; "00" means leap year
;闰年,29天
LEAP_Y: MOV A,DAY_BCD ; take BCD of "day" in Feb.
CJNE A,#29H,DAY_INC ; is up to 29 days (leap year)?
MOV DAY_BCD,#01H ; keep the first day
MOV MONTH_BCD,#03H ; increase "month"
LJMP CHECK
;非闰年
NOT_LEAP_Y: MOV A,DAY_BCD ; take BCD of "day" in Feb.
CJNE A,#28H,DAY_INC ; is up to 28 days (common year)?
MOV DAY_BCD,#01H ; keep the first day
MOV MONTH_BCD,#03H ; increase "month"
SJMP CHECK
;---------------------------
;非2月处理
;30/31天?
NOT_FEB: NOP ; other "month" except Feb.
CJNE A,#04H,Y01 ; is April ?
AJMP MON_30D
Y01: CJNE A,#06H,Y02 ; is June ?
AJMP MON_30D
Y02: CJNE A,#09H,Y03 ; is September ?
AJMP MON_30D
Y03: CJNE A,#11H,T11 ; is November ?
AJMP MON_30D
;31天
T11: MOV A,DAY_BCD ; take BCD of "day"
CJNE A,#31H,DAY_INC ; is up to 31 days ?
AJMP NEXT_MONTH
;30天
MON_30D: MOV A,DAY_BCD ; take BCD of "day"
CJNE A,#30H,DAY_INC ; is up to 30 days ?
;天进位
NEXT_MONTH: MOV DAY_BCD,#01H ; keep the first day
MOV A,MONTH_BCD ; take BCD of "month"
CJNE A,#12H,MONTH_INC ; is December ?
; 月进位
MOV MONTH_BCD,#01H ; keep the first month
MOV A,YEAR_BCD ; take BCD of "year"
CJNE A,#99H,YEAR_INC ; is up to 99 years ?
MOV YEAR_BCD,#00H ; keep the first year
SJMP CHECK
;年加1
YEAR_INC: MOV A,YEAR_BCD ; take BCD of "year"
ADD A,#01H ; increase "year"
DA A ; adjust BCD
MOV YEAR_BCD,A ; keep "year"
SJMP RESET_CNT
MONTH_INC: MOV A,MONTH_BCD ; take BCD of "month"
ADD A,#01H ; increase "month"
DA A ; BCD码调整
MOV MONTH_BCD,A ; keep "month"
SJMP RESET_CNT
DAY_INC: MOV A,DAY_BCD ; take BCD of "day"
ADD A,#01H ; increase "day"
DA A ; BCD码调整
MOV DAY_BCD,A ; keep "day"
SJMP RESET_CNT
HOUR_INC: MOV A,HOUR_BCD ; take BCD of "hour"
ADD A,#01H ; increase "hour"
DA A ; BCD码调整
MOV HOUR_BCD,A ; keep "hour"
SJMP CHECK
MINUTE_INC: MOV A,MINUTE_BCD ; take BCD of "minute"
ADD A,#01H ; increase "minute"
DA A ; BCD码调整
MOV MINUTE_BCD,A ; keep "minute"
SJMP CHECK
SECOND_INC: MOV A,SECOND_BCD ; take BCD of "second"
ADD A,#01H ; increase "second"
DA A ; BCD码调整
MOV SECOND_BCD,A ; save back "second"
CHECK:
MOV A,HOUR_BCD ;闹钟检查
CJNE A,AHOUR,OFF
MOV A,MINUTE_BCD
CJNE A,AMIN,OFF
CLR P2.0
SJMP RESET_CNT
OFF: SETB P2.0
RESET_CNT: MOV TICK_CNT,#14H ; retrieve times of overflow
T0_RET: RETI
;--------------------------------------------------------------------
; -------------------------------------------------------------------
; sub: LED Display
;显示子程序
DISPLAY:MOV DPTR,#TAB ; set address of code table
MOV A,R7 ; take flag for shift
CJNE A,#00H,DISP_DATE ; "00" for showing time ;R0: point to display buffer
DISP_TIME: MOV R0,#SECOND_BCD ; beginning from "second"
SJMP TSA
DISP_DATE: CJNE A,#01H,DISP_ATIME ;显示时间或日期或闹钟时间
MOV R0,#DAY_BCD ; "01" for showing date
SJMP TSA
DISP_ATIME: CJNE A,#02H,DISP_MIAOB
MOV R0,#ASCON
CLR P0.7
SJMP GO2
DISP_MIAOB: MOV R0,#MSS
;显示时间或日期或闹钟时间
TSA: SETB P0.7
GO2: MOV A,@R0 ; begin from "day"
ANL A,#0FH ; get the "low half byte"
MOVC A,@A+DPTR ; take character from code table
MOV R1,A ; keep in R1 for DS6 showing
MOV A,@R0
SWAP A
ANL A,#0FH ; get the "high half byte"
MOVC A,@A+DPTR ; take character from code table
MOV R2,A ; keep in R2 for DS5 showing
;---------------
INC R0
MOV A,@R0 ; next one from "month"
ANL A,#0FH ; get the "low half byte"
MOVC A,@A+DPTR
MOV R3,A ; keep in R3 for DS4 showing
MOV A,@R0
SWAP A
ANL A,#0FH ; get the "high half byte"
MOVC A,@A+DPTR
MOV R4,A ; keep in R4 for DS3 showing
;-------------
INC R0
MOV A,@R0 ; next one from "year"
ANL A,#0FH ; get the "low half byte"
MOVC A,@A+DPTR
MOV R5,A ; keep in R5 for DS2 showing
MOV A,@R0
SWAP A
ANL A,#0FH ; get the "high half byte"
MOVC A,@A+DPTR
MOV R6,A ; keep in R6 for DS1 showing
;---------------------
;P1:位选线
;P0:段选线
NOP
TDP: MOV P1,#0FFH ; close all showing///
;Display DS6
MOV P0,R1 ; send character to DS6
MOV A,FLASH_FLAG ; get flag of un-flash/flash
CJNE A,#03H,A02 ; "03" is flash on DS5&DS6
SJMP A03
A02: CJNE A,#06H,A06; ; "06" is flash on DS5&DS6 (修改)
SJMP A03
A06: CJNE A,#09H,A04
;==3 or 6, 9flash on DS5&DS6
A03: MOV A,TICK_CNT ; take Counter of overflow
RRC A
JNC A05 ; check bit C ( 1 or 0 )
A04: MOV P1,#0FEH ; turn on DS6
A05: LCALL DELAY
MOV P1,#0FFH ; close all showing
;Display DS5
MOV P0,R2 ; send character to DS5
MOV A,FLASH_FLAG ; get flag of un-flash/flash
CJNE A,#03H,B02 ; "03" is flash on DS5&DS6
SJMP B03
B02: CJNE A,#06H,B06
SJMP B03 ; "06" is flash on DS5&DS6
B06: CJNE A,#09H,B04
;==3 or 6, flash on DS5&DS6
B03: MOV A,TICK_CNT ; take times of overflow
RRC A
JNC B05 ; check bit C ( 1 or 0 )
B04: MOV P1,#0FDH ; turn on DS5
B05: LCALL DELAY
MOV P1,#0FFH ; close all showing
;Display DS4
MOV P0,R3 ; send character to DS4
MOV A,FLASH_FLAG ; get flag of un-flash/flash
CJNE A,#02H,C02 ; "02" is flash on DS3&DS4
SJMP C03
C02: CJNE A,#05H,C06 ; "05" is flash on DS3&DS4
SJMP C03
C06: CJNE A,#08H,C04
C03: MOV A,TICK_CNT ; take times of overflow
RRC A
JNC C05 ; check bit C ( 1 or 0 )
C04: MOV P1,#0FBH ; turn on DS4
C05: LCALL DELAY
MOV P1,#0FFH ; close all showing
;Display DS3
MOV P0,R4 ; send character to DS3
MOV A,FLASH_FLAG ; get flag of un-flash/flash
CJNE A,#02H,D02 ; "02" is flash on DS3&DS4
SJMP D03
D02: CJNE A,#05H,D06 ; "05" is flash on DS3&DS4
SJMP D03
D06: CJNE A,#08H,D04
D03: MOV A,TICK_CNT ; take times of overflow
RRC A
JNC D05 ; check bit C ( 1 or 0 )
D04: MOV P1,#0F7H ; turn on DS3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -