📄 slavr73b.asm
字号:
7.3. A LED键盘扫描综合程序
源程序: SLAVR73A.ASM
综合程序功能如下:
(1). 键盘扫描输入程序,0-F为16个数字键; 还有上档命令键,EXEC--执行键;
E2PROM--读键; SRAM--读写键; MON--返回初始状态键;
LAST--上一单元地址键; NEXT--下一单元地址键;
SHIFT--转换上档命令键,先按SHIFT键,再按命令键,就执行上档键的命令;
/RST--复位键,执行程序后,要机器回到初始化状态,必须按复位键;
(2) 按数字键显示对应数字,并有小数点作为光标,提示下一步工作位置,
按命令键(先按SHIFT)执行相应命令;
(3) 对应功能入口地址(地址数字后零可省)
0070H-01FFH读、写内部SRAM(监控规定SRAM读写范围)
0000H-01FFH读片内E2PROM数据
0200H-歌曲-祝你生日快乐,万水千山总是情
0300H-LED上8字循环显示
0320H-LED上0-F字符循环显示
* 程序清单见光盘文件SLAVR73A.ASM
.include "8515def.inc"
.org $0000
rjmp reset
.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 tempdh =r2
.def tempdl =r3
.def SCNTT =r26
.def MUSN =r22
.def TONL =r21
.def TONH =r20
.def PLYTON =r25
.def TONSET =r24
.def TONLNG =r23
.equ label =$0f00
.cseg
.org 0x06
intt1:rjmp outpm ;T1中断入口。
.cseg
.org 0x010
outpm:out TCNT1H,TONH
out TCNT1L,TONL
sbis PORTc,00
rjmp SETOP1
setop0:cbi portc,00
ldi musn,$00
reti
setop1:sbi portc,00
ldi musn,$01
reti
.org $0030
reset: clr r4
clr r5
clr r6
clr r7
clr zh
clr xh
clr yh
ldi temp,$02
out sph,temp
ldi temp,$5f
out spl,temp
rcall indipram ;调用初始化显示内存。
scanad: ldi temp,$07
ldi yl,$60
scann: rcall scan1
brts scann
scank: rcall scan1
brtc scank
rcall scan1
scans: clc
cpi keyn,$10
brcc commkey
rcall wraddram
dec temp
cpi temp,$03
brne scann
rjmp scanad
commkey: nop
cpi keyn,$13
breq reset
cpi keyn,$12
breq srmem
cpi keyn,$11
breq epmem
cpi keyn,$10
breq directt
rjmp scann
srmem: rjmp srmemt
epmem: rjmp epmemt
directt: rjmp direct
epmemt: rcall meradd ;调用由R7-R4产生的地址入TEMP2TEMP1。
cpi temp2,$02 ;EEPROM必须小于0200H。
brcs epdown
ldi temp2,$01
ldi temp1,$ff
rcall dviadd
epdown:out eearh,temp2
out eearl,temp1
sbi eecr,$00
in temp1,eedr
mov r2,temp1
mov r8,temp1
rcall dtor32 ;数据放入R3R2中。
rcall disbyreg ;改变显示内存。
clr yh
ldi yl,$64
ld temp,y
ldi temp1,$80
add temp,temp1
st y,temp
epscann:rcall scan1 ;键扫
brts epscann
epscank:rcall scan1
brtc epscank
rcall scan1
epscans:cpi keyn,$13
brne epreturn
rjmp reset
epreturn:cpi keyn,$10
brcc epcommkey
mov r3,keyn
rcall disbyreg
clr yh
ldi yl,$65
ld temp,y
ldi temp1,$80
add temp,temp1
st y,temp
escann:rcall scan1
brts escann
escank:rcall scan1
brtc escank
rcall scan1
escans:cpi keyn,$13
brne ereturn
rjmp reset
ereturn:cpi keyn,$10
brcc ecommkey
mov r2,keyn
rcall disbyreg
clr yh
ldi yl,$64
ld temp,y
ldi temp1,$80
add temp,temp1
st y,temp
rjmp epscann
epcommkey:cpi keyn,$13
brne epreturn1
rjmp reset
epreturn1:cpi keyn,$1e
breq eplastkey
cpi keyn,$1f
breq epnextkey
rjmp epscann
ecommkey:cpi keyn,$13
brne ereturn1
rjmp reset
ereturn1:cpi keyn,$1e
breq eplastkey
cpi keyn,$1f
breq epnextkey
rjmp escann
eplastkey:rcall meradd
mov temp,r3
swap temp
or temp,r2
cp temp,r8
breq eplast
cbi eecr,$00
out eearh,temp2
out eearl,temp1
sbi eecr,$02
sbi eecr,$01
epwrwt: sbic eecr,$01
rjmp epwrwt
eplast: cpi temp1,$00
brne eplastkey1
cpi temp2,$00
brne eplastkey1
rjmp epscann
eplastkey1:clc
subi temp1,$01
sbci temp2,$00
rcall dviadd
rjmp epmemt
epnextkey:rcall meradd
mov temp,r3
swap temp
or temp,r2
cp temp,r8
breq epnext
cbi eecr,$00
out eearh,temp2
out eearl,temp1
sbi eecr,$02
sbi eecr,$01
epwrwtn:sbic eecr,$01
rjmp epwrwtn
epnext: cpi temp1,$ff
brne epnextkey1
cpi temp2,$01
brne epnextkey1
rjmp epscann
epnextkey1:inc temp1
brne epnextkey2
inc temp2
epnextkey2:rcall dviadd
rjmp epmemt ;整段EEPROM读写结束。
srmemt: rcall meradd ;调用由R7-R4产生的地址入TEMP2TEMP1。
cpi temp2,$02
brcc srbegin
cpi temp2,$01
breq srdown
cpi temp1,$70
brcc srdown
ldi temp1,$70
clr temp2
rjmp srdown
srbegin:ldi temp2,$01
ldi temp1,$ff
srdown: rcall dviadd
rcall meradd
mov yh,temp2
mov yl,temp1
ld temp1,y
mov r2,temp1
mov r8,temp1
rcall dtor32 ;数据放入R3R2中。
rcall disbyreg ;改变显示内存。
clr yh
ldi yl,$64
ld temp,y
ldi temp1,$80
add temp,temp1
st y,temp
srscann:rcall scan1 ;键扫
brts srscann
srscank:rcall scan1
brtc srscank
rcall scan1
srscans:cpi keyn,$13
brne srreturn
rjmp reset
srreturn:cpi keyn,$10
brcc srcommkey
mov r3,keyn
rcall disbyreg
clr yh
ldi yl,$65
ld temp,y
ldi temp1,$80
add temp,temp1
st y,temp
sscann:rcall scan1
brts sscann
sscank:rcall scan1
brtc sscank
rcall scan1
sscans:cpi keyn,$13
brne sreturn
rjmp reset
sreturn:cpi keyn,$10
brcc scommkey
mov r2,keyn
rcall disbyreg
clr yh
ldi yl,$64
ld temp,y
ldi temp1,$80
add temp,temp1
st y,temp
rjmp srscann
srcommkey:cpi keyn,$13
brne srreturn1
rjmp reset
srreturn1:cpi keyn,$1e
breq srlastkey
cpi keyn,$1f
breq srnextkey
rjmp srscann
scommkey:cpi keyn,$13
brne srreturn2
rjmp reset
srreturn2:cpi keyn,$1e
breq srlastkey
cpi keyn,$1f
breq srnextkey
rjmp sscann
srlastkey:rcall meradd
mov temp,r3
swap temp
or temp,r2
cp temp,r8
breq srlast
mov yh,temp2
mov yl,temp1
st y,temp
nop
nop
srlast: cpi temp1,$70
brne srlastkey1
cpi temp2,$00
brne srlastkey1
rjmp srscann
srlastkey1:clc
subi temp1,$01
sbci temp2,$00
rcall dviadd
rjmp srmemt
srnextkey:rcall meradd
mov temp,r3
swap temp
or temp,r2
cp temp,r8
breq srnext
mov yh,temp2
mov yl,temp1
st y,temp
nop
nop
srnext: cpi temp1,$ff
brne srnextkey1
cpi temp2,$01
brne srnextkey1
rjmp srscann
srnextkey1:inc temp1
brne srnextkey2
inc temp2
srnextkey2:rcall dviadd
rjmp srmemt ;整段EEPROM读写结束。
disbyreg: ldi temp2,$07 ;调用通过R7-R2取显示字符入显示内存。
ldi yl,$60
clr yh
disbyreg1:mov zl,temp2
clr zh
ld temp3,z
mov zl,temp3
ldi zh,high(label*2)
lpm
dec temp2
st y+,r0
cpi yl,$66
brne disbyreg1
ret
dtor32: mov temp1,r2
andi temp1,$f0 ;数据放入R3R2中。
swap temp1
mov r3,temp1
mov temp1,r2
andi temp1,$0f
mov r2,temp1
ret
direct: mov temp1,r5
swap temp1
or temp1,r4
push temp1
mov temp1,r7
swap temp1
or temp1,r6
push temp1
lpm
inc r0
ret
meradd: mov temp1,r5
swap temp1
or temp1,r4
mov temp2,r7
swap temp2
or temp2,r6
ret
dviadd: mov r7,temp2
andi temp2,$0f
mov r6,temp2
mov temp2,r7
andi temp2,$f0
swap temp2
mov r7,temp2
mov r5,temp1
andi temp1,$0f
mov r4,temp1
mov temp1,r5
andi temp1,$f0
swap temp1
mov r5,temp1
ret
.org $0200
ldi temp,low(RAMEND) ;音乐生日快乐。
out SPL,temp
ldi temp,high(RAMEND)
out SPL+1,temp
wdr
ldi temp,$0f
out WDTCR,temp
ldi musn,$00
ldi temp,$00
out tccr1a,temp
out tccr1b,temp
ldi temp,$02
sts $0100,temp
LEDA: cli
ldi r16,0b10000000
out timsk,r16
ldi temp,$ff
out ddrc,temp
ldi temp,0b11111111
out portc,temp
clr temp2
clr temp1
ldi scntt,$02
clr tonlng
startp:wdr
ldi zh,HIGH(PLYTAB*2)
LDI ZL,LOW(PLYTAB*2)
nexmut:lpm
mov plyton,r0
ld r0,z+
lpm
mov tonlng,r0
or r0,plyton
ld r0,z+
brne playm
ldi temp,$00
out tccr1b,temp
cli
rjmp startp
playm:push zh
push zl
tst plyton
breq mustd
ldi zh,high(mustab*2)
ldi zl,low(mustab*2)
mov temp,plyton
dec temp
lsl temp
add zl,temp
ldi temp,$00
adc zh,temp
lpm
mov tonl,r0
out tcnt1l,r0
ld r0,z+
lpm
mov tonh,r0
out tcnt1h,r0
pop zl
pop zh
lds temp,$0100
out tccr1b,temp
sei
mustd:rcall plydel
dec tonlng
brne mustd
rjmp nexmut
plydel:ldi temp,185
dt3:ldi temp1,04
dt2:ldi temp2,250
dt1:wdr
wdr
wdr
wdr
wdr
dec temp2
brne dt1
dec temp1
brne dt2
dec temp
brne dt3
ret
.org $0300 ;8字循环程序。
rcall indipram
dip8: ldi temp,$7f ;8字循环显示程序.
rcall routdip
rjmp dip8
.org $0320
rcall indipram ;0-f循环显示程序.
aa5: clr zl
ldi zh,high(label*2)
ldi yl,$60
aa4: lpm
mov temp,r0
ld r0,z+
cpi zl,$11
breq aa5
rcall routdip
rjmp aa4
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,$64
brne pointc
ldi yl,$60
pointc: ld temp2,y
ldi temp3,$80
add temp2,temp3
st y,temp2
pop temp
ret
routdip: clr yh ;循环显示程序。
ldi yl,$60
aa1: ldi temp1,$80
nop
st y,temp
aa2: rcall scan1
dec temp1
brne aa2
push temp
ldi temp1,$10
clr temp
st y+,temp
aa3: rcall scan1
dec temp1
brne aa3
pop temp
cpi yl,$66
brne aa1
ret
indipram: ldi zh,high(label*2) ;初始化显示内存。
ldi zl,low(label*2)
ldi xl,$60
ldi temp,$f3
st x+,temp
clr temp
clr temp1
inlp: st x+,temp
inc temp1
cpi temp1,$05
brne inlp
ldi xl,$60
ret
SCAN1: push xh ;键扫显示子程序。
PUSH XL
PUSH TEMP3
PUSH TEMP2
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 TEMP2
POP TEMP3
POP XL
pop xh
RET
delay: push temp1
push temp3
ldi temp1,$10
dt11:ldi temp3,$20
dt21:nop
dec temp3
brne dt21
dec temp1
brne dt11
pop temp3
pop temp1
ret
delyt: ldi temp3,$20
dt31:dec temp3
brne dt31
ret
.cseg
.org $0f00
.dw 0x063f,0x4f5b,0x6d66,0x077d
.dw 0x6f7f,0x7c77,0x5e39,0x7179
.dw 0x0000
.equ plytab=0x0f10
.equ mustab=0x0fda
.cseg
.org plytab
.db 20,02,00,01,20,01,22,04,20,04
.db 25,04,24,04,00,04
.db 20,02,00,01,20,01,22,04,20,04
.db 27,04,25,04,00,04
.db 20,02,00,01,20,01,32,04,29,04
.db 25,04,24,04,22,04
.db 30,02,00,01,30,01,29,04,25,04
.db 27,04,25,04,00,04
.db 00,00
.cseg
.org mustab
.dw 63627,63730,63835,63927
.dw 64020,64102,64185,64259
.dw 64330,64399,64463,64523
.dw 64579,64632,64683,64731
.dw 64776,64819
.dw 64859,64897
.dw 64933,64967,64999,65029
.dw 65057,65084,65109,65133
.dw 65156,65177,65197,65216
.dw 65243,65251,65267,65282
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -