📄 综合a.asm
字号:
;
;SLAVR综合程序
;1.LED及LCD显示程序,有自动识别LED或LCD功能
;2.键盘扫描输入程序,0-F为16个数字键,还有上档功能键,EXEC-执行键,E2PROM-读键
;SRAM-读写键,MON-返回初始状态键,LAST-上一单无地址键,NEXT-下一单无地址键
;SHIFT-转换上档功能键,先按SHIFT键,再按标名的上档键,就执上档键的命令功能
;/RST-复位键,执行程序后,要机器回到初始化状态,必须按复位键
;按数字键显示对应数字,并有小数点作为光标,提示下一步工作位置,按命令键执行相应命令
;0070H-01FFH读、写内部SRAM(监控规定SRAM读写范围)
;0000H-01FFH读写片内E2PROM数据
;0200H-歌曲-祝你生日快乐,万水千山总是情
;0300H-LED上8字循环显示
;0320H-LED上0-F字符循环显示
;0400H-逐次逼近法A/D转换(需接网络电阻,另见说明)
;0500H-LCD初始化程序
;0700H-LCD上尖头字符左右移位程序
;0740H-LCD上0-F字符循环显示
;0800H-LCD显示LCD所有字符
;
.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
.def cnt1=r21
.def prl=r22
.def prh=r23
.def temp4=r24
.equ label =$0f00
.equ labelc =$0f10
.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: ldi temp,$02
out sph,temp
ldi temp,$5f
out spl,temp
RJMP RECOG
DELT3C: LDI TEMP2,$24
DT111C:WDR
DEC TEMP2
BRNE DT111C
RET
RECOG: cli
ldi temp,$ff
out ddrd,temp
out portd,temp
ldi temp,$00
out ddrb,temp
out portb,temp
LDI TEMP,0B00110000
OUT PORTD,TEMP
RCALL DELT3C
CBI PORTD,$05
RCALL DELT3C
sbi portd,$05
BUSY1: WDR
SBIC PINB,$07
RJMP LED
RJMP LCD
LED: clr r4
clr r5
clr r6
clr r7
clr zh
clr xh
clr yh
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 eedr,temp就可以。
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 eedr,temp就可以。
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
disbyregc: ldi temp2,$07 ;调用通过R7-R2取显示字符入显示内存。
ldi yl,$60
clr yh
disbyregc1:mov zl,temp2
clr zh
ld temp3,z
ldi zl,low(labelc*2)
ldi zh,high(labelc*2)
add zl,temp3
lpm
dec temp2
st y+,r0
cpi yl,$66
brne disbyregc1
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
wraddramc: push temp
clr zh ;读键存入显示内存及寄存器中。
mov zl,temp
st z,keyn
ldi zh,high(labelc*2)
ldi zl,low(labelc*2)
add zl,keyn
lpm
st y+,r0
cpi yl,$64
brne pointcc
ldi yl,$60
pointcc: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
.org $0400
.def hsb=r21 ;逐次逼近式A/D转换
.def msb=r18
.def lsb=r17
.def data=r16
.def datah=r18
.def datal=r17
ldi temp,$10
mov r7,temp
mov r6,temp
mov r5,temp
mov r4,temp
ldi temp3,$ff
out ddrd,temp3
adag: rcall disbyreg
ldi yl,$63
ld keyn,y
ldi temp3,$80
add keyn,temp3
st y,keyn
rcall scan1
rcall scan1
clr temp3
out ddrb,temp3
out portb,temp3
out ddra,temp3
out porta,temp3
rcall delay
adc08:clr data ;A/D转换。
ldi cnt,$08
ldi temp1,$80
nextd: mov temp2,temp1
or temp2,DATA
out portd,temp2
rcall delay
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -