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

📄 clock.asm

📁 电子时钟Clock.asm的源程序
💻 ASM
字号:
TYPE12	EQU	12	;12小时型时钟
TYPE24	EQU	24	;24小时型时钟

Z8279    EQU       212H	;控制口地址,写:命令,读:状态
D8279    EQU       210H	;数据口地址,写:显示,读:键盘

LEDMOD   EQU       00H  ;左边输入,八位显示外部译码八位显示
LEDFEQ   EQU       38H	;扫描频率

TIM_CTL EQU       22bH	;定时器控制口
TIMER0  EQU       228H	;定时器0数据口
TIMER1  EQU       229H	;定时器1数据口

MODE03  EQU       00110110B		;定时器0方式3
MODE10  EQU       01110000B		;定时器1方式0

Time0Const EQU	5000
Time1Const EQU	5

INT00 EQU 200h
INT01 EQU 201h

BLANK	EQU 01000000B	;字符闪烁属性
DOT		EQU 10000000B	;显示点的属性

TIMESHOW	EQU	0	;正常时钟显示状态
TIMESET		EQU	1	;时间设置状态
TYPESET		EQU 2	;时钟模式改变状态

CODE     SEGMENT
ASSUME    CS:CODE,DS:CODE
START:  

		Push	Cs
		Pop		Ds
			 
		CALL Init					;初始化
		Call Clear
		Call Display

Again:
		Cmp ClockStatus,TIMESHOW	;如果正常时钟显示状,则显示时间
		Jne Again1
		
		Call TimePut

Again1:
		Call Display
		Call ReadKey
		Jnc	Again
		
		Call KeyCmdProc

		Jmp Again
	
	
;键盘命令处理子程序
;
;
KeyCmdProc Proc
		Test Al,80H
		Jz KeyN		;数字键按下跳转
		Cmp Al,80H
		Jz KeyA			;A键按下跳转
		Cmp Al,81H
		Jz KeyB			;B键按下跳转
		Cmp Al,82h
		Jz KeyC			;C键按下跳转
		Cmp Al,83h
		Jz KeyD			;D键按下跳转
		Cmp Al,84h
		Jz KeyE			;E键按下跳转
		Cmp Al,85h
		Jz KeyF			;F键按下跳转
		Cmp Al,86H
		Jz KeyG			;.键按下跳转
		Cmp Al,87H
		Jz KeyH			;,键按下跳转
		Cmp Al,88h
		Jz KeyI			;-键按下跳转
		Cmp Al,89h
		Jz KeyJ			;+键按下跳转
		Cmp Al,8Ah
		Jz KeyK			;:键按下跳转
		Cmp Al,8Bh
		Jz KeyL			;REG键按下跳转
		Ret

KeyN:	Call NumKey
		Ret
KeyA:	Call SetTime
		Ret
KeyB:	Call ChangeType
		Ret
KeyC:
		Ret
KeyD:
		Ret
KeyE:	Call Cancel
		Ret
KeyF:	Call Confirm
		Ret
KeyG:
		Ret
KeyH:
		Ret
KeyI:	Call LeftMove
		Ret
KeyJ:	Call RightMove
		Ret
KeyK:
		Ret
KeyL:
		Ret
	
KeyCmdProc Endp


;设置时钟类型
;
;
ChangeType Proc
		Cmp ClockStatus,TYPESET
		Je ChangeType1
		
		Mov ClockStatus,TYPESET
		Call Clear
		Mov Ah,13H					;设置提示符P,表示进入设置状态。  
		Mov Al,00h
		Mov Bx,0
		Call SetChar
		
		Mov Al,ClockType
ChangeType0:
		Call NtoS
		
		Mov Cx,Ax
		Mov Al,00h
		Mov Bx,3
		Call SetChar
		
		Mov Ah,Cl
		Mov Bx,2
		Call SetChar
		Jmp ChangeTypeRet
		
ChangeType1:
		Mov Ah,DispBuffer+2*2
		Mov Al,DispBuffer+3*2
		Call CharToNum
		Cmp Al,TYPE12
		Je ChangeType2
		Mov Al,TYPE12
		Jmp ChangeType0
ChangeType2:
		Mov Al,TYPE24
		Jmp ChangeType0
		
ChangeTypeRet:
		Ret
ChangeType Endp

;+键处理子程序
;
RightMove Proc
		Cmp ClockStatus,TIMESET
		Je RightMoveTimeSet
		Jmp RightMoveRet
		
RightMoveTimeSet:
		Mov Bx,DigPos
		Inc Bx
		Mov Al,BLANK
		Call ClrCharAttr
		
		Cmp DigPos,5
		Jnz RightMoveTimeSet1
		Mov DigPos,-1
		
RightMoveTimeSet1:
		Inc DigPos
		Mov Bx,DigPos
		Inc Bx
		Mov Al,BLANK
		Call SetCharAttr

				
RightMoveRet:
		Ret
RightMove Endp


;-键处理子程序
;
LeftMove Proc
		Cmp ClockStatus,TIMESET
		Je LeftMoveTimeSet
		Jmp LeftMoveRet
		
LeftMoveTimeSet:
		Mov Bx,DigPos
		Inc Bx
		Mov Al,BLANK
		Call ClrCharAttr
		
		Cmp DigPos,0
		Jnz LeftMoveTimeSet1
		Mov DigPos,6
		
LeftMoveTimeSet1:
		Dec DigPos
		Mov Bx,DigPos
		Inc Bx
		Mov Al,BLANK
		Call SetCharAttr

				
LeftMoveRet:
		Ret
LeftMove Endp


;数字键处理子程序
;
NumKey Proc
		Cmp ClockStatus,TIMESET
		Je NumkTimeSet
		Jmp NumKeyRet
		
NumkTimeSet:
		Cmp DigPos,0
		Jne NumkTimeSetNext1
		Cmp Al,3				;时的十位只能是 0,1,2
		Jc	NumKTimeSetNext0
		Jmp NumKeyRet
NumKTimeSetNext0:
		Mov Ah,Al
		Mov Bx,1
		Mov Al,00h
		Call SetChar
		Jmp NumkTimeSetEnd
		
NumkTimeSetNext1:
		Cmp DigPos,1
		Jne NumkTimeSetNext2
		Cmp DispBuffer+2,2
		Jne	NumkTimeSetNext11
		Cmp Al,5				;时的十位是2时,各位只能是0-4
		Jc	NumkTimeSetNext11
		Jmp NumKeyRet
NumkTimeSetNext11:
		Mov Ah,Al
		Mov Bx,2
		Mov Al,80h
		Call SetChar		
		Jmp NumkTimeSetEnd
		
		
NumkTimeSetNext2:
		Cmp DigPos,2
		Jne NumkTimeSetNext3
		Cmp Al,6				;分钟的十位只能是 0-5
		Jnc NumKeyRet
		Mov Ah,Al
		Mov Bx,3
		Mov Al,00h
		Call SetChar
		Jmp NumkTimeSetEnd

NumkTimeSetNext3:
		Cmp DigPos,3
		Jne NumkTimeSetNext4
		Mov Ah,Al				;分钟的个位可以是 0-9
		Mov Bx,4
		Mov Al,80h
		Call SetChar
		Jmp NumkTimeSetEnd
		
NumkTimeSetNext4:
		Cmp DigPos,4
		Jne NumkTimeSetNext5
		Cmp Al,6				;秒的十位只能是 0-5
		Jnc NumKeyRet
		Mov Ah,Al
		Mov Bx,5
		Mov Al,00h
		Call SetChar
		Jmp NumkTimeSetEnd
		
NumkTimeSetNext5:
		Mov Ah,Al				;秒的个位可以是 0-9
		Mov Bx,6
		Mov Al,80h
		Call SetChar
		
NumkTimeSetEnd:		

		Mov Bx,DigPos			;本位的闪烁数字改为不闪烁
		Inc Bx
		Mov Al,BLANK
		Call ClrCharAttr
		
		Cmp DigPos,5			;计算下一个位置
		Jnz NumkTimeSet1
		Mov DigPos,-1
		
NumkTimeSet1:					
		Inc DigPos				;下一位数字闪烁
		Mov Bx,DigPos
		Inc Bx
		Mov Al,BLANK
		Call SetCharAttr

				
NumKeyRet:
		Ret
NumKey Endp

;设置时间子程序
;
SetTime Proc
		Mov ClockStatus,TIMESET		;状态改为时间设置。
		Mov Ah,13H					;设置提示符P,表示进入时间设置状态。  
		Mov Al,00h
		Mov Bx,0
		Call SetChar
		
		Mov DigPos,0
		Mov Bx,DigPos
		Inc Bx
		Mov Al,BLANK
		Call SetCharAttr
		
		Ret
SetTime Endp


;设置确认子程序
;
Confirm Proc
		Cmp ClockStatus,TIMESET
		Je Confirm1
		Cmp ClockStatus,TYPESET
		Je Confirm2
		Jmp ConfirmRet
Confirm1:								;时间设置确认
		Cli
		Mov Ah,DispBuffer+1*2
		Mov Al,DispBuffer+2*2
		Call CharToNum
		Mov Hour,Al

		Mov Ah,DispBuffer+3*2
		Mov Al,DispBuffer+4*2
		Call CharToNum
		Mov Minute,Al

		Mov Ah,DispBuffer+5*2
		Mov Al,DispBuffer+6*2
		Call CharToNum
		Mov Second,Al
		Sti
		Mov ClockStatus,TIMESHOW
		Jmp ConfirmRet
		
Confirm2:								;时钟显示类型确认
		Mov Ah,DispBuffer+2*2
		Mov Al,DispBuffer+3*2
		Call CharToNum
		Mov ClockType,Al
		Mov ClockStatus,TIMESHOW
		Jmp ConfirmRet
						
ConfirmRet:
		Ret
Confirm Endp	
	

;操作放弃子程序
;
Cancel Proc
		Mov ClockStatus,TIMESHOW	;将状态设为TIMESHOW
		Ret
Cancel Endp


;字符转数字子程序
;输入参数:  AH:高位,AL:低位
;输出参数:  AL:数
CharToNum Proc
		Push Bx
		Shl Ah,1
		Mov Bh,Ah
		Shl Ah,1
		Shl Ah,1
		Add Ah,Bh
		Add Al,Ah
		Pop Bx
		Ret
CharToNum Endp

;数转2位字符串
;输入Al
;输出Ah:个位
;    Al:十位
;影响Ax
NtoS Proc
		Push Bx
		Mov Ah,0
		Mov Bl,10
		Div Bl
		Pop Bx
		Ret
NtoS Endp

;置字符子程序
;输入参数 AH:字符,AL:属性,BX:位置
;输出参数:无
SetChar Proc
		Push Bx
		Shl Bx,1
		Mov DispBuffer[Bx],Ah
		Inc Bx
		Mov DispBuffer[Bx],Al
		Pop Bx
		Ret
SetChar Endp

;置字符属性子程序
;输入参数 AL:属性,BX:位置
;输出参数:无
SetCharAttr Proc
		Push Bx
		Shl Bx,1
		Inc Bx
		Or DispBuffer[Bx],Al
		Pop Bx
		Ret
SetCharAttr Endp
	
;清字符属性子程序
;输入参数 AL:属性,BX:位置
;输出参数:无
ClrCharAttr Proc
		Push Ax
		Push Bx
		Shl Bx,1
		Inc Bx
		Not Al
		And DispBuffer[Bx],Al
		Pop Bx
		Pop Ax
		Ret
ClrCharAttr Endp


;中断子程序
;十分之一秒中断子程序
;
Time Proc
		Push Ax
		Push Bx
		Push Cx
		Push Dx
		Push Si
		Push Di
		
		MOV     DX,TIMER1		;定时器1常数设置
		MOV     Ax,Time1Const
		OUT     DX,AL
		MOV     Al,Ah
		OUT     Dx,Al
		
		Cmp Second1,9	;十分之一秒加一
		Jz Time1
		Inc Second1
		Jmp Time5
	
Time1:	Mov Second1,0	;秒加一
		Cmp Second,59
		Jz Time2
		Inc Second
		Jmp Time5

Time2:	Mov Second,0	;分钟加一
		Cmp Minute,59
		Jz Time3
		Inc Minute
		Jmp Time5
	
Time3:	Mov Minute,0	;小时加一
		Cmp Hour,23
		Jz Time4
		Inc Hour
		Jmp Time5
	
Time4:	Mov Hour,0		;

Time5:
        MOV DX,INT00
        MOV AL,20H
        OUT DX,AL

		Pop Di
		Pop Si
		Pop Dx
		Pop Cx
		Pop Bx
		Pop Ax
		IRet
Time Endp	
	
	
;读键盘子程序
;输入参数:无
;输出参数:CF=1 Al:键值
;          CF=0     无键
;影响寄存器:Al
Readkey Proc
		Push Bx
		Push Cx
		Push Dx

		MOV	Dx, Z8279	;8279控制口地址

ReadKey1:
		IN	Al, Dx
		;Test Al,80h
		;Jz ReadKey1		
		
		TEST	AL, 07H	;测试最低3位,确定有无键盘输入
		JZ	ReadKeyNo
		MOV	Dx, D8279	;从数据端口读取按键的扫描码
		IN	Al, DX

		Cmp	Al,0Ah
		Jc	ReadkeyRet
	
		Mov	Bx,0
		Mov Cx,12
Readkey2:
		Cmp Al,ScanCode2[Bx]
		Jz	Readkey3
		Inc Bx
		Loop ReadKey2
	
Readkey3:
		Mov	Al,Bl
		Or	Al,80h
		Stc
		Jmp	ReadKeyRet
		
ReadKeyNo:
		Clc
		
ReadkeyRet:
		Pop Dx
		Pop Cx
		Pop Bx
		Ret
Readkey Endp




;显示子程序
;将显示缓冲区的内容在显示器上显示
;无数人输出
;不影响任何寄存器
Display Proc
		push	Ax
		Push	Bx
		Push	Cx
		Push	Dx
		Push	Si

		Mov	Cx,8
		Mov	Bx,15
Display1:
		Xor Ax,Ax
		Dec	Bx
		Mov	Al,DispBuffer[Bx]
		Mov	Si,Ax
		Mov	Al,LED[Si]
		Inc	Bx
		Mov	Ah,DispBuffer[Bx]
		Sub	Bx,2
		Test Ah,BLANK
		Jz	Display2
		Cmp Second1,5
		Jc	Display2
		Mov Al,00h
Display2:		
		Mov	Dx,D8279
		And Ah,80h
		Or	Al,Ah
		Out	Dx,Al
		Loop	Display1
		Pop	Si
		Pop	Dx
		Pop	Cx
		Pop	Bx
		Pop	Ax
		Ret
Display Endp


;清显示器
;输入参数:无
;输出参数:无
;影响寄存器:无
Clear Proc
		Push Bx
		Push Cx
		Mov Bx,0
		Mov Cx,8
Clear1:
		Mov Word ptr DispBuffer[Bx],0010H
		Add Bx,2
		Loop Clear1
		Pop Cx
		Pop Bx
		Ret
Clear Endp

;输出时钟
TimePut Proc
		Cmp Hour,TYPE12
		Jnc	TimePutpm
		Mov Dispbuffer,11h
		Jmp TimePut1
TimePutpm:
		Mov Dispbuffer,12h
	
TimePut1:
		Mov DispBuffer+1,00h
	
		Cmp ClockType,TYPE24
		Jz	TimePut24
TimePut12:
		Mov Al,Hour
		Cmp	Al,13
		Jc	TimePut24
		Sub Al,12
		Jmp TimePut241
		
TimePut24:
		Mov	Al,Hour
TimePut241:
		Call NtoS
		Mov DispBuffer+1*2,al
		Mov DispBuffer+1*2+1,00h
		Mov DispBuffer+2*2,ah
		Mov DispBuffer+2*2+1,DOT

TimePut2:
		Mov	Al,Minute
		Call NtoS
		Mov DispBuffer+3*2,al
		Mov DispBuffer+3*2+1,00h
		Mov DispBuffer+4*2,ah
		Mov DispBuffer+4*2+1,DOT
	
		Mov	Al,Second
		Call NtoS
		Mov DispBuffer+5*2,al
		Mov DispBuffer+5*2+1,00h
		Mov DispBuffer+6*2,ah
		Mov DispBuffer+6*2+1,DOT
	
		Mov	Al,Second1
		Mov DispBuffer+7*2,10h
		Mov DispBuffer+7*2+1,00h

		;Or DispBuffer+0*2+1,BLANK
		;Or DispBuffer+1*2+1,BLANK
		;Or DispBuffer+2*2+1,BLANK
		;Or DispBuffer+3*2+1,BLANK
		;Or DispBuffer+4*2+1,BLANK
		;Or DispBuffer+5*2+1,BLANK
		;Or DispBuffer+6*2+1,BLANK
		;Or DispBuffer+7*2+1,BLANK

		Ret
TimePut Endp



;初始化子程序	 
Init Proc
		CLI
		
		MOV AL,13H                ;ICW1:边沿触发,单片,要ICW4
		MOV DX,INT00
		OUT DX,AL

		MOV AL,8                  ;中断号从8开始
		MOV DX,INT01
		OUT DX,AL
		MOV Cx,0fffh
l00:	LOOP l00

		MOV AL,9                 ;全嵌套方式,86/88系统
		MOV DX,INT01
		OUT DX,AL
		MOV Cx,0fffh
l01:	LOOP l01

		MOV DX,INT01
		MOV AL,00H               ;八个中断全部开放
		OUT DX,AL
		MOV Cx,0fffh
l02:	LOOP l02

		MOV DX,INT00
		MOV AL,20H              ;非特殊EOI结束中断
		OUT DX,AL
		MOV Cx,0fffh
l03:    LOOP l03
	 
		MOV       DX,Z8279     ;8279初始化为 左边输入,八位显示外部译码八位显示
		MOV       AL,LEDMOD
		OUT       DX,AL
	 
		MOV       AL,LEDFEQ   ;8279的扫描频率
		OUT       DX,AL

		MOV     DX,TIM_CTL        ;定时器0工作在方式3
		MOV     AL,MODE03
		OUT     DX,AL
		MOV     DX,TIMER0
		MOV     Ax,Time0Const
		OUT     DX,AL
		MOV     Al,Ah
		OUT     Dx,Al
		
		MOV     DX,TIM_CTL       ;定时器1工作在方式0
		MOV     AL,MODE10
		OUT     DX,AL
		MOV     DX,TIMER1
		MOV     Ax,Time1Const
		OUT     DX,AL
		MOV     Al,Ah
		OUT     Dx,Al


		MOV		AX,0H							;设置中断向量
		MOV		ES,AX
		MOV		Word ptr Es:[0020h],Offset Time
		MOV		Word ptr Es:[0022h],8100h
		
		STI	 
		Ret
Init Endp	 

	ClockStatus DB TIMESHOW

	ClockType	DB	TYPE24	;时钟类型

	Hour	DB 11	;小时
	Minute	DB 59	;分钟
	Second	DB 50	;秒
	Second1	DB 0	;十分之一秒

	DigPos	DW 0	;时钟设置时使用,0:小时十位,1:小时各位,2:分钟十位,3:分钟各位,4:秒十位,5:秒各位

	ScanCode1	DB 00h,01h,02h,03h,04h,05h,06h,07h,08h,09h				;键盘扫描码
	ScanCode2	DB 0ah,0bh,0ch,0dh,0eh,0fh,10h,11h,12h,13h,14h,15h		;键盘扫描码

	DispBuffer DB 11h,00h,12h,80h,3,00h,4,80h,5,00h,6,80h,7,00h,8,80h     ;显示缓冲区,8个显示器,16个字节(第一字节内容,第二字节属性),

	LED	DB  3FH,06H,5BH,4FH,66H,6DH,7DH,27H,7FH,6FH,77H,7CH,39H,5EH,79H,71H  ;字形表  0 ~ f:显示 0~F
    	DB  00h,63h,5ch	;字形表  10:暗,11:上午,12:下午
		DB	73H         ;P:13H, 	
	 
CODE  ENDS
END      START                                              

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -