📄 ex6-1.asm
字号:
.sect "init"
.global init,SINP ;库文件中的变量的使用
.text
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;init start!!!
.word init
.space 8
.word timer0
init: ldp 0,dp
ldi @STCK,sp ;INIT STACK
ldi 1800H,st ;INIT ST
ldi @MCTL,ar0 ;INIT MAIN BUS
ldi MBUS1,r0
sti r0,*ar0
ldi @MCTLS,ar0
sti r0,*ar0
ldi 0,r0
ldi @TSDATA,ar0
rpts SAMNUM
sti r0,*ar0++
ldi @PORT232,ar1
rpts 030h
sti r0,*ar1++
ldi 0,r0
ldi @ADADER,ar0 ;SET A/D MODE A CHANNL 1 LU
sti r0,*ar0
ldi @ADADERM,ar0
sti r0,*ar0 ;RUN A/D
ldi @TNUM,ar0
sti r0,*ar0
ldi @TSDATA,ar0
ldi @SADDR,ar1
sti ar0,*ar1
;-------------------------DDS
call ddsinit
ldf 11.4,r0
ldi @F1,ar0
stf r0,*ar0
float 1689,r0
ldi @FL,ar0
stf r0,*ar0
float 1711,r0
ldi @FH,ar0
stf r0,*ar0
call sinit
;-------------------------DDS
call initt0 ;timer0 init
ldi 100H,IE ;ACTIVE TIMER0
or 2000h,st
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;init end!!!
start: ldi @TNUM,ar0
ldi *ar0,r0
absi r0
cmpi 2000h,r0
blt start
ldi 0,r0
sti r0,*ar0
ldi @LEDS,ar0
ldi *ar0,r0
cmpi 0,r0
ldieq 1,r0
ldine 0,r0
sti r0,*ar0
ldi @LED,ar0
sti r0,*ar0
call msamp ;搬移
call haming ;加汉明窗
ldi @INADDRD,ar0
ldi @INADDR,r0
sti r0,*ar0
ldi @LOGFFT,ar0
ldi SULOG,r0 ;13阶8192点FFT
sti r0,*ar0
ldi @LOGIFFT,ar0
ldi SULOG1,r0 ;8阶256点IFFT
sti r0,*ar0
call fft
call zfft
ldi 0,ar0
ldi 4095,ar1
addi @INADDR,ar0 ;起始地址ar0
addi @INADDR,ar1 ;终止地址ar1
ldi DLENTH,r0 ;数据长度r0
call spc1
ldi @PWADDR,ar0
; addi 100,ar0 ;直流分量的频谱在前100个单元内,他们的幅度较大,避开他们
ldi @PWADDR,ar1
addi 0fffh,ar1 ;fffh=4095
call sort
ldi ar0,ar3 ;频谱幅度最大的地址
subi @PWADDR,ar0 ;幅度最大的地址减首地址,得出是第几根
float ar0,r1 ;转化为浮点型数据进行存储
ldi @FC,ar1 ;最高频率存入FC
stf r1,*ar1
ldi @FCAMP,ar1 ;最大的幅度存入FCAMP
stf r0,*ar1
ldi @PWADDR,ar0 ;因第一次已经将最大幅度谱线及其附近10个清零,便于找出幅度第二大的谱线
; addi 100,ar0
ldi @PWADDR,ar1
addi 0fffh,ar1
call sort ;此步后,ar0存入第二大谱线,ar3中的是第一大谱线
subi ar0,ar3,ar4 ;两者相减,得出之间相差的距离
absi ar4
subi @PWADDR,ar0
float ar0,r4 ;r4中是第二大谱线的地址(1)
ldf r0,r5 ;r5中是第二大谱线的幅值(1)
ldi @PWADDR,ar0
; addi 100,ar0
ldi @PWADDR,ar1
addi 0fffh,ar1
call sort
subi ar0,ar3,ar5
absi ar5
subi @PWADDR,ar0
float ar0,r1 ;此时r1中是第二大谱线的地址(2),r0中是第二大谱线的幅值(2)
cmpf r1,r4 ;比较两个第二大谱线频率的大小,赋给上下边频
blt FCOMP
ldi @F2,ar6 ;若r1<r4,r1为左,r2为右
ldi @F3,ar7
stf r1,*ar6
stf r4,*ar7
ldi @F2AMP,ar6
ldi @F3AMP,ar7
stf r0,*ar6
stf r5,*ar7
br FMCMP
FCOMP: ldi @F2,ar6 ;若r1>r4,r1为右,r2为左
ldi @F3,ar7
stf r4,*ar6
stf r1,*ar7
ldi @F2AMP,ar6
ldi @F3AMP,ar7
stf r5,*ar6
stf r0,*ar7
FMCMP: subi ar4,ar5 ;比较两条次大谱线与最大谱线间的距离
cmpi 3,ar5
bgt ret ;如果不相等,此次比较无效
float ar4,r1 ;相等的话,此值赋给FM,即FM是第一大和第二大谱线间隔
ldi @FM,ar1
stf r1,*ar1
ret: nop
call output
br start
;--------------------------------------------------------------comm_sub list
; 1: timer0 2: msamp 3: haming 4: spc1 5: initt0
; 6: ddsinit 7: sinit 8: initt1 9: invf 10: sqrt 11: fft
; 12: sort
;--------------------------------------------------------------comm sub list
;INTERRUPT SERVER;;;;;;;;;;;;;;;;;;;;;;comm sub1: timer0
timer0: push st
push ar0
push ar1
push ar2
push BK
ldi SAMNUM,BK
ldi @MCTL,ar0
ldi MBUS7,ar1
sti ar1,*ar0
ldi @ADADER,ar0
ldi *ar0++,ar2
addi 2000h,ar2
and 3fffh,ar2
sti ar2,*ar0
ldi @SADDR,ar0
ldi *ar0,ar0
sti ar2,*ar0++%
ldi @SADDR,ar2
sti ar0,*ar2
ldi @MCTL,ar1
ldi @MCTLS,ar0
ldi *ar0,ar0
sti ar0,*ar1
ldi @TNUM,ar0
ldi *ar0,ar1
addi 1,ar1
sti ar1,*ar0
pop BK
pop ar2
pop ar1
pop ar0
pop st
reti
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub2: msamp
msamp: ldi @SAMNUM,BK
ldi @INADDR,ar2
ldi @SADDR,ar0
ldi *ar0,ar1
ldi DLENTH,rc
subi 2,rc
float *ar1++%,r0
rptb samp0
samp0: float *ar1++%,r0
|| stf r0,*ar2++
stf r0,*ar2++
ldf 0.0,r0
ldi DLENTH,rc ;SET DATA LENGTH
subi 1,rc
rptb samp1
samp1: stf r0,*ar2++ ;IMAG PART CLEAR end
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub3: HAMING_windows
haming: ldi @INADDR,ar0
ldi 8192,ar7
ldi @SINTAB,ar6 ;SET SINTAB ADDER
addi 17ffh,ar6 ;97,11
ldi ar7,r5
lsh -1,r5
subi 1,r5
ldi ar7,rc ;SET REPEAT LEN.
subi 1,rc
rptb ham
ldf *ar0,r2
cmpi r5,rc ;1fffh-1000h 1 part
blt part2
beq mid ;0fffh-0 2 part
ldf *ar6--,r6
br nom
mid: nop *ar6++
part2: ldf *ar6++,r6
nom: addf 1.0,r6
mpyf 0.46,r6
addf 0.08,r6
mpyf r6,r2
ham: stf r2,*ar0++
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub4: spc1
spc1: ldi @PWADDR,ar2 ;interface:ar0,ar1
subi3 ar0,ar1,rc ; ar0:real part addr.
addi3 r0,ar0,ar1 ; output addr. PWADDR
rptb sends ;use:PWADDR DLENTH
ldf *ar1++,r1 ;use:ar0-ar2,r0,r1,rc
|| ldf *ar0++,r0
mpyf r0,r0
mpyf r1,r1
addf r1,r0
sends: stf r0,*ar2++
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub5: initt0
initt0: ldi 0,r0
ldi 808h,ar0
lsh 12,ar0
addi 20h,ar0
sti r0,*+ar0(4)
ldi FS,r0
sti r0,*+ar0(8)
ldi 3c1h,r0
sti r0,*ar0
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub6: ddsinit
ddsinit:ldi @MCTL,ar0
ldi MBUS7,r0
sti r0,*ar0
ldi 4000h,r0
lsh 4,r0
rpts r0
nop
ldi 0,r0
ldi @DDS_PHASE0,ar0
sti r0,*ar0
ldi @DDS_PHASE1,ar0
sti r0,*ar0
ldi @DDS_PHASE2,ar0
sti r0,*ar0
ldi @DDS_PHASE3,ar0
sti r0,*ar0
ldi @MCTL,ar0
ldi MBUS1,r0
sti r0,*ar0
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub7: sinit
sinit: ldi @F1,ar0
ldf *ar0,r0
call initt1
ldi @MCTL,ar0
ldi MBUS7,r0
sti r0,*ar0
ldi @FL,ar0
ldf *ar0,r0
ldi @FH,ar1
ldf *ar1,r1
mpyf @SINGFXS,r0
addf 0.5,r0
fix r0
mpyf @SINGFXS,r1
addf 0.5,r1
fix r1
ldi 0fh,r6
lsh 16,r6
and3 r6,r0,r5
lsh -16,r5
ldi @DDS_FREQ0H,ar0
sti r5,*ar0
ldi @DDS_FREQ0L,ar0
sti r0,*ar0
and3 r1,r6,r5
lsh -16,r5
ldi @DDS_FREQ1H,ar0
sti r5,*ar0
ldi @DDS_FREQ1L,ar0
sti r1,*ar0
ldi @MCTL,ar0
ldi MBUS1,r0
sti r0,*ar0
ldi @MCTLS,ar0
sti r0,*ar0
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sub8: initt1
initt1: call invf ;input data R0 float
ldf @FT15M,r4
mpyf r0,r4
addf 0.5,r4
fix r4
ldi 0h,r0 ;r4=FS
ldi 808h,ar0 ;INIT TIMER1
lsh 12,ar0
addi 30h,ar0
sti r0,*+ar0(4) ;COUNTER CLEAR
sti r4,*+ar0(8) ;15000000/FS
ldi 3c1h,r0 ;RUN TIMER1
sti r0,*ar0
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub9: invf
invf: ldf r0,r3 ;use r0,r1,r2,r3
absf r0 ;input & output use r0
pushf r0
pop r1
ash -24,r1
negi r1
subi 1,r1
ash 24,r1
push r1
popf r1
mpyf r1,r0,r2
subrf 2.0,r2
mpyf r2,r1
mpyf r1,r0,r2
subrf 2.0,r2
mpyf r2,r1
mpyf r1,r0,r2
subrf 2.0,r2
mpyf r2,r1
mpyf r1,r0,r2
subrf 2.0,r2
mpyf r2,r1
rnd r1
mpyf r1,r0,r2
subrf 1.0,r2
mpyf r1,r2
addf r2,r1
rnd r1,r0
negf r0,r2
ldf r3,r3
ldfn r2,r0
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub10: sqrt
sqrt: ldf r0,r3 ;use r0,r1,r2,r3
retsle ;input & output use r0
pushf r0
pop r1
ash -24,r1
addi 1,r1
ash -1,r1
negi r1,r1
ash 24,r1
push r1
popf r1
mpyf 0.5,r0
mpyf3 r1,r1,r2
mpyf r0,r2
subrf 1.5,r2
mpyf r2,r1
rnd r1,r1
mpyf3 r1,r1,r2
mpyf r0,r2
subrf 1.5,r2
mpyf r2,r1
rnd r1,r1
mpyf3 r1,r1,r2
mpyf r0,r2
subrf 1.5,r2
mpyf r2,r1
rnd r1,r1
mpyf3 r1,r1,r2
mpyf r0,r2
subrf 1.5,r2
mpyf r2,r1
rnd r1,r1
mpyf3 r1,r1,r2
mpyf r0,r2
subrf 1.5,r2
mpyf r2,r1
rnd r1,r0
mpyf r3,r0
rets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;comm sub11: fft
fft: ldi @LOGFFT,ar0 ;ar0 save 0d--8192
ldi 1,ar1
lsh3 *ar0,ar1,r7
ldi r7,ir0
ldi r7,ar7
lsh -1,ar7
ldi 2048,ir1
ldi 13,ar4
subi *ar0,ar4
lsh3 ar4,ar1,ar5
ldi 1,ar6
fft1: ldi @INADDRD,ar0
ldi *ar0,ar0
addi3 ar7,ar0,ar1
addi3 r7,ar0,ar2
addi3 ar7,ar2,ar3
ldi ar6,rc
subi 1,rc
rptb fft2
addf3 *ar1,*ar0,r0
subf3 *ar1,*ar0,r1
addf3 *ar3,*ar2,r2
subf3 *ar3,*ar2,r3
stf r1,*ar1++(ir0)
|| stf r0,*ar0++(ir0)
fft2: stf r3,*ar3++(ir0)
|| stf r2,*ar2++(ir0)
cmpi 1,ar7
bzd fft5
ldi 1,r6
ldi @SINTAB,ar4
fft3: addi ar5,ar4
ldf *ar4,r5
ldi r6,ar0
ldi @INADDRD,ar1
ldi *ar1,ar1
addi ar1,ar0
addi3 ar7,ar0,ar1
addi3 r7,ar0,ar2
addi3 ar7,ar2,ar3
addi 1,r6
ldi ar6,rc
subi 1,rc
rptb fft4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -