📄 dtmf.asm
字号:
** =minium signalpower(-..db) *
** gain_amp =gain_const×sqrt(gain_power) *
** gain_lev =1/N *
** gain_scale=gain_lev/gain_amp *
** x(n)=x(n)×gain_scale *
**FRCT=1,SXM=1 *
**********************************************************************
_gaincntrl:
nop
pshm ST0
pshm ST1
pshm AR1
pshm AR6
pshm AR7
nop
frame #-10 ;--局部变量--
;*SP(0)=gain_pow(HI)
;*SP(1)=gain_pow(LO)
;*SP(2)=gain_lim(HI)
;*SP(3)=gain_lim(LO)
;*SP(4)=gain_amp
;*SP(5)=gain_lev
;*SP(6)=gain_scale
;*SP(7)=gain_const ;*SP(8)=gain_delta
;*SP(9)=ptr to data
;---arguments---
;(A)=ptr to DTMFDECOBJ
stlm A,AR5
nop
nop
nop
ld *AR5,A
stl A,*SP(9)
; ----变量初始化------
ld #0005h,16,A ;(A)=00050000h
or #0505h,A ;(A)=00050505h=1/(64×N)(Q31)
sth A,*SP(2) ;(A)=-->gain_lim (32bit)
stl A,*SP(3)
ld #00E3h,A ;(AL)=00E3h=(0.5×sqrt(2))/N
stl A,*SP(5) ;(AL)-->gain_lev (16bit) ld #6564h,A ;(AL)=6564h=sqrt(64/102)
stl A,*SP(7) ;(AL)-->gain_const
ld #4000h,A ;(AL)=4000h=0.5
stl A,*SP(8) ;(AL) --> gain_delta
ssbx FRCT
;---计算信号能量-----
ld *SP(9),A
stlm A,AR2 ;AR2 指向数据缓冲区
rptz B,#(N-1) ;for(n=0;n<N-1;n++)
squra *AR2+,B ;(B)=(B)+x(n)×x(n)
sfta B,-6 ;(B)=(1/64)×(B)
sth B,*SP(0) ;(B)-->gain_pow (32bit)
stl B,*SP(1) ;gain_pow=(N/64)×sigpower
ld *SP(2),16,A ;(A)=gain_lim=1/(64×N) (32bit)
or *SP(3),A
sub A,B ;(B)=gain_pow-gain_lim
bc gain2,BLEQ ;if(gain_pow>gain_lim)
;{
;-----计算gain_amp=sqrt(gain_pow)-----
st #4000h,*SP(4) ;初始化gain_amp
st #4000h,*SP(8) ;初始化gain_delta
mvmm SP,AR2
mar *+AR2(8) ;AR2 指向gain_delta
stm #(sqrt_iterations-1),BRC
rptbd sqrtloopend-1
squr *SP(4),A ;(A)=yold×yold
dsub *SP(0),A ;(A)=yold×yold-x
sqrtloop
bcd sqrt1,AGT
ld *SP(4),16,B ;(B)=yold
sub *AR2,15,B ;(B)=yold-(1/2)×delta
;if(y needs to be larger)
add *AR2,16,B ;(B)=yold+(1/2)×delta
sqrt1 sth B,*SP(4) ;(BH)-->ynew
ld *AR2,15,A ;(AH)=(1/2)delta
sth A,*AR2 ;(AH)-->delta new
squr *SP(4),A
dsub *SP(0),A ;(A)=yold×yold-x
sqrtloopend
;--计算gain_amp=sqrt(64/N)*gain_amp---
ld *SP(7),T ;(T)=gain_const
mpy *SP(4),A ;(A)=sqrt(64/102)×gain_amp
sth A,*SP(4) ;(AH)-->gain_amp
;---计算gain_lev/gain_amp
ld *SP(5),16,A ;(AH)=gain_lev
rpt #(16-1)
subc *SP(4),A ;计算(gain_lev/gain_amp)
and #0fffh,A ;保留商(AL),屏蔽余数
sfta A,15 ;左移商到累加器高位
sth A,*SP(6) ;(AH)-->gain_scale
;用(gain_lev/gain_amp)定标数据
ld *SP(9),A
stlm A,AR2 ;AR2 指向数据
mvmm SP,AR3
mar *+AR3(6) ;AR3指向gain_scale
stm #(N-1),BRC
rptb gain1-1 ;for(n=0;n<N;n++) { ;;#
mpy *AR2,*AR3,A ;(A)=x(n)×(gain_lev/gain_amp)
sth A,*AR2+ ;(AH)-->x(n)
gain1 ;}
gain2
frame #10
nop
popm AR7
popm AR6
popm AR1
popm ST1
popm ST0
ret
**************************************************
**子程序:goertzel *
**输入: 指向结构DTMFDECOBJ的指针 *
**输出:无 *
**描述:该程序对102个数据计算差分方程 *
**因为有增益控制保护可能的溢出,固程序不检查溢出*
**由于二次谐波在子程序dtmfchecks()中计算,故这里只计算基频(8个)*
**子程序同样计算8个基频的能量模板 *
**随后复位滤波器抽头系数为0,准备下一次计算 *
**************************************************
_goertzel:
nop
pshm ST0
pshm ST1
pshm AR1
pshm AR6
pshm AR7
;--参数----
;(A)=指向DTMFDECOBJ
rsbx OVA
ssbx FRCT
stlm A,AR5 ;AR5 指向结构DTMFDECOBJ
;*AR5(0)=ptr to data
;*AR5(1)=ptr to taps
;*AR5(2)=ptr to energy template
;*AR5(3)=digitptr
;*AR5(4)=digitlast
;*AR5(5)=detectstat
;*AR5(6)=err_flags
;*****************************************
;Goertzel 滤波器计算
;vk(n)=2coef×vk(n-1)-vk(n-2)+x(n)
;系数按序排列在存储区COEF1st
;COEF1st .word xxxx ;coef1
; .word yyyy ;coef2
; ....
;数据vk(n-1),vk(n-2)如下排列
;v9(n-1)
;v9(n-2) 列的二次谐波
;v8(n-1)
;v8(n-2) 行的二次谐波
;v7(n-1)
;v7(n-2)
; .....
;v0(n-1)
;v0(n-2)<--AR2
;FRCT=1,SXM=1
;**********************************************
ld *AR5,A
stlm A,AR1 ;AR1指向数据缓冲区
ld *AR5(1),A
add #19,A
stlm A,AR6 ;AR6指向抽头的末尾
stm #(N-1),BRC
goer1 rptb goer2-1 ;for(n=0;n<N;n++) {
mvmm AR6,AR2 ;AR2指向抽头的末尾
stm #COEF1st,AR3 ;AR3指向系数
ld *AR1+,16,A ;(A)=x(n)
;-----滤波k=0----------
sub *AR2-,16,A,B ;(B)=-vk(n-2)+x(n) ;;#
mac *AR2,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
mac *AR2,*AR3+,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
delay *AR2 ;vk(n-1)-->vk(n-2)
sth B,*AR2- ;(B)--> vk(n-1)
;-----滤波k=1-----
sub *AR2-,16,A,B ;(B)=-vk(n-2)+x(n) ;;#
mac *AR2,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
mac *AR2,*AR3+,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
delay *AR2 ;vk(n-1)-->vk(n-2)
sth B,*AR2- ;(B)--> vk(n-1)
;----滤波k=2----
sub *AR2-,16,A,B ;(B)=-vk(n-2)+x(n) ;;#
mac *AR2,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
mac *AR2,*AR3+,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
delay *AR2 ;vk(n-1)-->vk(n-2)
sth B,*AR2- ;(B)--> vk(n-1)
;-----滤波k=3------
sub *AR2-,16,A,B ;(B)=-vk(n-2)+x(n) ;;#
mac *AR2,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
mac *AR2,*AR3+,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
delay *AR2 ;vk(n-1)-->vk(n-2)
sth B,*AR2- ;(B)--> vk(n-1)
;-----滤波k=4------
sub *AR2-,16,A,B ;(B)=-vk(n-2)+x(n) ;;#
mac *AR2,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
mac *AR2,*AR3+,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
delay *AR2 ;vk(n-1)-->vk(n-2)
sth B,*AR2- ;(B)--> vk(n-1)
;-----滤波k=5------
sub *AR2-,16,A,B ;(B)=-vk(n-2)+x(n) ;;#
mac *AR2,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
mac *AR2,*AR3+,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
delay *AR2 ;vk(n-1)-->vk(n-2)
sth B,*AR2- ;(B)--> vk(n-1)
;--------滤波k=6----
sub *AR2-,16,A,B ;(B)=-vk(n-2)+x(n) ;;#
mac *AR2,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
mac *AR2,*AR3+,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
delay *AR2 ;vk(n-1)-->vk(n-2)
sth B,*AR2- ;(B)--> vk(n-1)
;--------滤波k=7-------
sub *AR2-,16,A,B ;(B)=-vk(n-2)+x(n) ;;#
mac *AR2,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
mac *AR2,*AR3+,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
delay *AR2 ;vk(n-1)-->vk(n-2)
sth B,*AR2- ;(B)--> vk(n-1)
goer2 ;}
;-------------------------------------------
;基频能量计算(8个频率)
;y(N)×y(N)=vk(N)×vk(N)-2coef×vk(N)×vk(N-1)+vk(N-1)×vk(N-1)
;系数按序存放在COEF1st
;COEF1st .word xxxx ;coef0<--AR3
; .word yyyy ;coef1
; ....
; 数据vk(n-1),vk(n-2) 按序排列
; v9(n-1)
; v9(n-2) 列二次谐波
; v8(n-1)
; v8(n-2) 行二次谐波
; v7(n-1)
; v7(n-2)
; ....
; v0(n-1)
; v0(n-2) <-- AR2
;FRCT=1,SXM=1
;------------------------------------------
goer3 ld *AR5(1),A
add #19,A
stlm A,AR2 ;AR2 指向滤波器抽头块的末尾
stm #COEF1st,AR3 ;AR3 指向系数表的开始
ld *AR5(2),A
stlm A,AR4 ;AR4指向能量模块
stm #(8-1),BRC
rptb goer4-1 ;for(k=0;k<8;k++) {
ld *AR2,16,A ;(A)=vk(N-1),A(32:16)loaded
mpya *AR2- ;(B)=vk(N-1)×vk(N-1),(T)=vk(N-1)
mpy *AR2,A ;(A)=vk(N)×vk(N-1)
ld *AR3+,T ;(T)=coef
mpya A ;(A)=coef×vk(N)×vk(N-1)
sub A,1,B ;(B)=-2coef×vk(N)×vk(N-1)+vk(N-1)×vk(N-1)
ld *AR2,T ;(T)=vk(N)
mac *AR2-,B ;(B)=vk(N)×vk(N)-2coef×vk(N)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -