📄 led钟.asm
字号:
;本程序一上电显示00:00:00等待设置或按shife+exec开始计时。
;本程序若直接按shife+exec即从00:00:00开始计时。
;若设置时间后按shift+exec即从所设置的时间开始计时。
.include"8515def.inc"
.def TEMP =r16
.def TEMP1 =r17
.def temp2 =r18
.def temp3 =r19
.def CNT =r20
.def SCNN =r21
.def KSNI =r22
.def SCNDP =r23
.def KEYN =r24
.def cnt1 =r25
.def hour=r24
.def minute=r22
.def second=r21
.equ label=$0f00 ;字形表首址
.org $0000
rjmp reset
.org $007
intt0: ldi temp,104 ;因25ms内差40us故补上40/(1/8)即320个CK。
bu: dec temp ;因中断需4CK这样:4+104*(1+2)+1+1+1+1=320。
brne bu
nop
inc cnt1 ;cnt1计数40次为1秒钟。
ldi temp,256-195 ;计数(256-195)次才产生1次中断。
out tcnt0,temp ;CK/1024分频,这样一次中断需25ms。
rjmp recog
.org $030
reset:
ldi temp,low(ramend) ;设置堆栈指针。
out spl,temp
ldi temp,high(ramend)
out sph,temp
clr r2 ;清工作寄存器。
clr r3
clr r4
clr r5
clr r6
clr r7
clr zh
clr xh
clr yh
clr keyn
clr second
clr minute
clr hour
clr cnt
clr yh
ldi temp,$80
mov r8,temp ;R8=$80
ldi yl,$60 ;设置显示內存地址指针Y为$0060.
rcall disram ;调用DISRAM。
ld temp,y
ldi temp1,$80
add temp,temp1
st y,temp
scanad: ldi temp,$07
ldi yl,$60
scann: rcall scan1 ;调用键扫显示子程序SCAN1。
brts scann
scank: rcall scan1
brtc scank
rcall scan1
scans: nop
cpi keyn,$10 ;KEYN=$10转EXEC。
brcc exec
rcall wraddram ;调用WRADDRAM。
dec temp ;TEMP减1。
cpi temp,$01
brne scann ;TEMP=1则转SCANN
rjmp scanad
exec: mov temp1,r7 ;把r7,r6的两个十进制换成一个十六进制入hour中
mov temp,r6
rcall dechex
mov hour,temp
mov temp1,r5 ;把r5,r4的两个十进制换成一个十六进制入minute中
mov temp,r4
rcall dechex
mov minute,temp
mov temp1,r3 ;把r3,r2的两个十进制换成一个十六进制入second中
mov temp,r2
rcall dechex
mov second,temp
ldi temp,$05 ;T0设置为CK/1024分频。
out tccr0,temp
ldi temp,256-195
out tcnt0,temp ;装载T0时间常数。
ldi temp,$ff ;设置b口,d口为输出
out ddrb,temp
out ddrd,temp
sei ;开中断总开关
ldi temp,$02
out timsk,temp ;允许t0中断。
display:rcall disram ;调用disram
clr yh ;设置显示内存地址指针Y为$0060
ldi yl,$60
ldi scndp,$df ;设置扫描显示码SCNDP起址0B11011111.
agdis: ld r1,y+
cpi yl,$62
brne npoint
add r1,r8
npoint: cpi yl,$64
brne next
add r1,r8
next: out portb,r1 ;把R1送B口显示
out portd,scndp ;扫亮某个数码管
sec ;C=1
ror scndp ;右移SCNDP
rcall delay ;延时
cpi yl,$66
brne agdis ;未扫亮最后一位继续
rjmp display
recog: cpi cnt1,40 ;40次中断为40*25ms=1秒
brne inthome ;40次中断未到转inthome
clr cnt1 ;40次中断到则清cnt1
inc second ;秒寄存器加1
cpi second,60
brne change ;秒寄存器未满转change
clr second ;否则清秒寄存器
inc minute ;分寄存器加1
cpi minute,60
brne change ;分寄存器未满转change
clr minute ;否则清分寄存器
inc hour ;时寄存器加1
cpi hour,24
brne change ;时寄存器未满转change
clr hour ;否则清时寄存器
reti ;中断返回
change: mov temp,second ;把second中的十六进制转换成二个十进制数存入r3,r2中
rcall hexdec
mov r3,temp1
mov r2,temp
mov temp,minute ;把minute中的十六进制转换成二个十进制数存入r5,r4中
rcall hexdec
mov r5,temp1
mov r4,temp
mov temp,hour ;把hour中的十六进制转换成二个十进制数存入r7,r6中
rcall hexdec
mov r7,temp1
mov r6,temp
inthome:reti ;中断返回
hexdec: clr temp1 ;把temp中的十六进制转成二个十进制入temp1,temp中的子程序
hexdec1:subi temp,10
brcs negs
inc temp1
rjmp hexdec1
negs: subi temp,$f6
ret ;子程序返回
dechex: push temp ;把temp1,temp的两个十进制数转换成一个十六进制入temp中
ldi temp2,$0a
clr temp
dechex1:cpi temp1,$00
breq dh
dec temp1
add temp,temp2
rjmp dechex1
dh: pop temp1
add temp,temp1
ret ;子程序返回
disram: push yl ;压栈保护
push zl
push xl
ldi zh,high(label*2) ;Z指针指向字形表首址label*2
ldi zl,low(label*2)
clr xh
ldi xl,$60
ldi yl,$07
ramag: ld temp2,y ;y为间址的内容送temp2
dec yl
mov zl,temp2
lpm
st x+,r0 ;把r0的内容送到$0060-$0065中
cpi xl,$66
brne ramag
pop xl
pop zl
pop yl ;退栈
ret ;子程序返回
wraddram:push temp ;读键存入显示内存及寄存器中。
clr zh
mov zl,temp
st z,keyn
ldi zh,high(label*2)
mov zl,keyn
lpm
st y+,r0
cpi yl,$66
brne pointc
ldi yl,$60
pointc: ld temp2,y
ldi temp3,$80
add temp2,temp3
st y,temp2
pop temp
ret ;子程序返回
delay: push temp ;延时子程序
lp1: ldi temp2,$10
lp2: dec temp
brne lp2
dec temp2
brne lp2
pop temp
ret ;子程序返回
SCAN1: push xh ;键盘扫描显示子程序。
PUSH XL
PUSH TEMP1
PUSH TEMP
LDI XL,$60
SET
LDI SCNN,$00
LDI SCNDP,0B11011111
LDI CNT,$06
LDI KSNI,0B11110111
COL1: LDI TEMP,$FF
OUT DDRb,TEMP
OUT DDRC,TEMP
OUT PORTC,TEMP
OUT DDRd,TEMP
OUT PORTd,SCNDP
LD R1,X+
OUT PORTb,R1
RCALL DELAY
MOV TEMP,CNT
SUBI TEMP,$03
BRCS NOSK
LDI TEMP1,$04
LDI TEMP,0B00001111
OUT DDRc,TEMP
OUT PORTc,KSNI
RCALL DELYT
IN TEMP,PINc
ANDI TEMP,0B11110000
SWAP TEMP
KROW: SEC
ROR TEMP
BRCS NOKEY
CLT
MOV KEYN,SCNN
SBIS PINd,$07
ADIW KEYN,$10
NOKEY: INC SCNN
DEC TEMP1
BRNE KROW
SEC
ROR KSNI
NOSK: SEC
ROR SCNDP
DEC CNT
BRNE COL1
LDI TEMP,$FF
OUT DDRC,TEMP
OUT PORTC,TEMP
POP TEMP
POP TEMP1
POP XL
pop xh
RET
delyt: ldi temp3,$20
dt31:dec temp3
brne dt31
ret
.cseg
.org $0f00
.dw 0x063f,0x4f5b,0x6d66,0x077d
.dw 0x6f7f,0x7c77,0x5e39,0x7179
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -