📄 222.asm
字号:
data segment
led db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh,40h,0ffh,00h,77h
disbuff db 8 dup(?)
pa equ 288h
pb equ 289h
pc equ 28ah
c8255 equ 28bh
clk0 equ 280h
clk1 equ 281h
clk2 equ 282h
c8253 equ 283h
hour db 12h
minute db 59h
second db 45h
mode db 00h
centisd db 00h
count db 00h
acount db 00h
ahour db 13h
aminute db 00h
DCOUNT db 00h
tstop db 00h
alarm db 00h
tdcount db 00h
alcount db 00h
ltncount dw 00h
mark db 00h
ftp db 00h
ps db 00h ;现态
fs db 00h ;前态
flag db 00h
filter db 5 dup(0)
data ends
code segment
assume cs:code,ds:data
start: mov ax,data
mov ds,ax
call initall ;系统初始化
call selfcheck ;系统自检
start1:
call dbuffdeal ;显示内容送显缓
call shine
call ledshow ;显示刷新
call keyinput ;开关量输入及消抖
call timerdeal ;计数处理
call rhour ;整点报时
call alarmclock ;闹铃处理
call adtimer ;调校与设置操作处理
call adjust
call Ltnoper ;长时间无操作处理
mov al,ps
cmp al,fs
jz w1
call keyshow
w1:mov dl, 0ffh ;判断PC是否有按键
mov ah ,06h
int 21h
jz start1 ;若无,则继续主循环
mov ah,4ch ;返回dos
int 21h
*********系统初始化************
initall proc near
mov al,37h ;8253初始化
mov dx,c8253
out dx,al
mov ax,1250h ;计数值1.25ms
mov dx,clk0
out dx,al
mov al,ah
out dx,al
mov al,88h ;8255初始化
mov dx,c8255
out dx,al
ret
initall endp
********系统自检***************
selfcheck proc near
q1: mov al,0ffh ;段码置8,显示8
mov dx,pa
out dx,al
mov al,00h ;位码置0
inc dx
out dx,al
mov dl,0ffh ;判断PC是否有按键
mov ah,06h
int 21h
jz q1 ;有则退出
ret
selfcheck endp
********显示内容送显缓**********
dbuffdeal proc near
lea si,disbuff
mov bl,0ah ;取出字符-
cmp mode,00h ;模式0下,进行拆时,拆分和拆秒
jz l1
cmp mode,01h ;模式1下, 进行拆时,拆分和拆秒
jz l1
cmp mode,02h ;不在02模式下,进行闹钟的拆时,拆分和拆秒
jnz l2
l1: mov al,hour ;拆时
call aa ;调用拆字子程序
mov [si],bl ;把小时的显示部分送到首地址开始的两个单元
inc si ;指向存放 "-"的单元
mov al,minute ;拆分
call aa ;调用拆字子程序
mov [si],bl ;把分的显示部分送到对应的两个单元
inc si ;指向存放 "-"的单元
mov al,second ;拆秒
call aa ;调用拆字子程序
jmp exit
l2: mov al,ahour ;闹钟部分的拆时
call aa
mov [si],bl ;把小时的显示部分送到首地址开始的两个单元
inc si ;指向存放 "-"的单元
mov al,aminute ;闹钟部分的拆分
call aa
mov dl,0ch
mov [si],dl
inc si
mov [si],dl
inc si
mov dl,0dh
mov [si],dl
cmp alarm,01h
jnz exit
bnao:mov dl,0ch ;alarm为01是,闹钟不闹,显示秒的地方设为暗码
mov [si],dl
exit:ret
dbuffdeal endp
******** ************
shine proc near
lea si,disbuff
cmp mode,0
jz sexit ;在0模式下不闪
cmp mode,01H
jnz tmt
call flash ;在1模式下调用闪烁的子程序
jmp sexit
tmt:cmp mode,02H
jnz ahr
add si,3
call flash ;在1模式下调用闪烁的子程序
jmp sexit
ahr:cmp mode,03H
jnz amt
call flash ;在1模式下调用闪烁的子程序
jmp sexit
amt:cmp mode,04H
jnz sexit
add SI,3
call flash ;在1模式下调用闪烁的子程序
jmp sexit
sexit: ret
shine endp
******** 要显示的内容存入显缓 ********
aa proc near
mov dl,al
mov cl,4
shr dl,cl
mov [si],dl
inc si
mov dl,al
and dl,0fh
mov [si],dl
inc si
ret
aa endp
****** 闪烁子程序 *******
flash proc near
cmp mark,0 ;为0,则亮
jz normal
mov byte ptr [si],12 ;不为0,送暗码
mov byte ptr [si+1],12
nomal:inc DCOUNT
cmp DCOUNT,50 ;计0.5秒
jnz nback ;未计到,调出循环
mov DCOUNT,0 ;到0.5秒,标志位取反,灭灯0.5秒
xor mark,01h
nback:ret
flash endp
********显示刷新********
ledshow proc near
display: lea bx,led
lea si,disbuff
mov ah,1
not ah
again: mov dx,pc
wait0: in al,dx
test al,80h
jz wait0 ;等待高电平
wait1: in al,dx
test al,80h
jnz wait1 ;等待低电平
mov al,[si]
xlat ;查表
mov dx,288h
out dx,al ;送段码
inc dx
mov al,ah
out dx,al ;送位码
inc si
rol ah,1 ;循环8次,依次点亮位码
cmp ah,0feh
jnz again ;未到8次,继续循环
ret
ledshow endp
********计数处理*********
timerdeal proc near
cmp tstop,1
jz exit1 ;标记为0,正常计数
mov al,centisd
inc al
mov centisd,al
cmp al,100
jb exit1 ;未循环100次,即未到一秒, 退出循环
mov al,0
mov centisd,al
mov al,second
inc al ;循环100次,即到一秒, second自加1
daa
mov second,al
cmp al,60h
jb exit1 ;未加到60,退出循环
mov al,0
mov second,al
mov al,minute
inc al ; second加到60后, minute自加1
daa
mov minute,al
cmp al,60h
jb exit1 ;未加到60,退出循环
mov al,0
mov minute,al
mov al,hour
inc al ; minute加到60后, hour自加1
daa
mov hour,al
cmp al,24h
jne exit1 ; hour未加到24, 退出循环
mov al,0
mov hour,al
exit1:ret
timerdeal endp
**********整点报时********
rhour proc near
mov al,0 ;灭灯,防止调校后产生干扰
mov dx,pc
out dx,al
cmp mode,00
jnz exit2 ;不00在模式下,退出
mov al,minute ;若在00模式下,执行整点报时程序
cmp al,00h
jz m1 ;在00分时再与秒比
cmp al,59h ;不为00分与59分比
jb lp1 ;小于59分再与30分比
mov al,second ;
cmp al,50h
je lp2 ;在59分50秒时整点报时
cmp al,52h
je lp2 ;在52秒时整点报时
cmp al,54h
je lp2 ;在54秒整点报时
cmp al,56h
je lp2 ;在56秒整点报时
cmp al,58h
je lp2 ;在58秒整点报时
jmp exit2
m1: mov al,second
cmp al,00h
je lp2 ;在00秒整点报时
jmp exit2
lp1:cmp al,30h
jnz exit2
mov al,second ;满足30分时若为00秒半点报时
cmp al,00h
jnz exit2
lp2:mov dx,pc ;亮灯程序
mov al,01h
out dx,al
mov al,count ;设定亮灯时间为1秒
inc al
mov count,al
cmp al,64h
jnz exit2 ;不到1秒退出
mov count,0
lp3:mov al,0 ;灭灯程序
mov dx,pc
out dx,al
exit2:ret
rhour endp
**********闹铃处理*********
alarmclock proc near
cmp mode,00h
jnz m2 ;不为00模式退出
mov al,alarm
cmp al,00h
jnz exit3 ;标志位为00时退出,否则执行闹铃程序
mov al,ahour
cmp al,hour
jnz exit3 ;不为设定的闹钟的时,退出
mov al,aminute
cmp al,minute
jnz exit3 ;不为设定的闹钟的时,退出
mov dx,pc ;亮到程序
mov al,01h
out dx,al
mov al,second
cmp al,05h
jae m2 ;闹的时间小于5秒时退出
jmp exit3
m2: mov dx,pc ;闹的时间等于5秒时灭灯
mov al,00h
out dx,al
exit3:ret
alarmclock endp
*********键盘输入************
keyinput proc near
lea si,filter ;滤波的五个单元
mov al,ps
mov fs,al ;现态赋给前态
mov cx,4
lop:mov al,[si+1] ;滚动,下一个单元的值赋给前一个单元
mov [si] ,al
inc si
loop lop
mov dx,pc
in al,dx ;采集的值送入最后一个单元
and al,60h
mov [si],al
lop1:lea si,filter
mov al,[si]
cmp al,[si+1]
jne exit4 ;前一个单元的值于后一个的比不等退出
inc flag
inc si
cmp flag,5
jb lop1 ;循环五次
mov flag,0 ;五个单元的值相等,消抖成功
mov al,[si]
mov ps,al ;相等的值送给现态
exit4:ret
keyinput endp
********键盘显示*********
keyshow proc near
mov al,ps
mov cl,4
shr al,cl
add al,30h
mov dl,al
mov ah,02h
int 21h
mov al,fs
shr al,cl
add al,30h
mov dl,al
mov ah,02h
int 21h
ret
keyshow endp
*********调校*************
adtimer proc near
test fs,40h
jz u2 ;前态为0,跳到判断现态
test ps,40h ;前态为1,判现态
jz u3
u2: test ps,40h
jnz zhuan ;现态不为0跳出
cmp mode,0
jnz zhuan ;FS,PS=0,0,若不在0模式跳出
inc tdcount
cmp tdcount,50
jb zhuan ;开关时间小于0.5秒跳出
inc mode ;等于,mode 自加1
mov tdcount,0
jmp u4
u3: cmp mode,0
jz zhuan ;FS,PS=1,1,若在0模式下跳出
inc mode
u4: cmp mode,06h
jb zhuan
mov mode,00h ;mode为06时清0
mov tstop,0
zhuan:ret
adtimer endp
********设置********
adjust proc near
test fs,20h
jz t1 ;前态为0,跳到判断现态
test ps,20h
jz t2 ;
jmp ppp
t1: test ps,20h
jnz ppp
mov ltncount,0 ; FS,PS=0,0时,快调
inc acount
cmp acount,50
jb ppp
cmp acount,60
jz t3
jmp ppp
t2: mov ltncount,0
mov acount,0
cmp mode,00h
jnz t4
ppp:jmp exit5
t3: mov acount,50
t4: cmp mode,01h
jnz h1
mov dx,c8255
mov al,00h
out dx,al
mov tstop,01h
mov second,0
mov centisd,0
mov al,hour
inc al
daa
mov hour,al
cmp al,24h
jnz pq
mov hour,0
pq: jmp exit5
h1: cmp mode,02h
jnz h2
mov tstop,01h
mov second,0
mov centisd,0
mov al,minute
inc al
daa
mov minute,al
cmp al,60h
jnz hp
mov minute,0
hp: jmp exit5
h2: cmp mode,03h
jnz h3
mov tstop,00h
mov al,ahour
inc al
daa
mov ahour,al
cmp al,24h
jnz s1
mov ahour,0
s1: jmp exit5
h3: cmp mode,04h
jnz h4
mov tstop,00h
mov al,aminute
inc al
daa
mov aminute,al
cmp al,60h
jnz s2
mov aminute,0
s2: jmp exit5
h4: cmp mode,05h
jnz exit5
xor alarm,01h
mov tstop,00h
exit5:ret
adjust endp
**********长时间无操作处理*******
ltnoper proc near
cmp mode,0
;在00模式下跳出
jz exit6
test ps,40h
jz exit6
test fs,40h
jz exit6
inc ltncount
cmp ltncount,1000
jb exit6
mov tstop,0
mov mode,0
mov ltncount,0
exit6:ret
ltnoper endp
code ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -