⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cj.asm

📁 基于单片机的汇编语言
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; 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 + -