📄 dtmf.asm
字号:
***************************************************
*文件名:tables.inc *
*描述:常数表 *
***************************************************
********************************
*** 解码器常数
********************************
N .set 102 ;采样点数
THR_SIG1 .set 1900*32768/10000
THR_SIG2 .set 2150*32768/10000
THR_PAU .set 458*32768/10000 ;停顿下的能量门限
THR_STDTWI .set 2512*32768/10000 ;-5db
THR_REVTWI .set 1259*32768/10000 ;-9db
THR_ROWREL .set 2000*32768/10000 ;
THR_ROW2nd .set 2000*32768/10000
THR_COLREL .set 2000*32768/10000
THR_COL2nd .set 2000*32768/10000
sqrt_iterations set 16 ;;#
.set "tables"
***************************************************
***解码器表
***************************************************
*****************************************************************
*16个Goertzel 滤波器的系数 ,按如下计算 *
* .word cos(2*pi*k/N)32768 ;系数 *
*其中,N=102 (一次、二次谐波) *
* k=9,10,11,12,15,17,19,21 (一次谐波) *
* k=18,20,22,24,31,34,38,42 (二次谐波) *
*****************************************************************
COEF1st .word 27980 ;一次谐波
.word 26956
.word 25701
.word 24219
.word 19073
.word 16325
.word 13805
.word 9315
COEF2nd .word 14739 ;二次谐波
.word 11414
.word 7549
.word 3032
.word -10565
.word -16503
.word -22318
.word -27472
*****************************************************
* 数字映射表 *
* 低字节:列数 *
* 高字节:行数 *
*****************************************************
KEYS
.word 0301h ;'0'
.word 0000h ;'1'
.word 0001h ;'2'
.word 0002h ;'3'
.word 0100h ;'4'
.word 0101h ;'5'
.word 0102h ;'6'
.word 0200h ;'7'
.word 0201h ;'8'
.word 0202h ;'9'
.word 0003h ;'A'
.word 0103h ;'B'
.word 0203h ;'C'
.word 0303h ;'D'
.word 0300h ;'E'='*'
.word 0302h ;'F'='#'
************************************************
**** 编码器表
************************************************
************************************************
**COEFFS表包含数字正旋振荡器的系数 *
**通常: *
** DEQ: y(n)=2cos(2*pi*f/fs)y(n-1)-y(n-2) *
** I.C.: y(-1)=0 *
** y(-2)=-Asin(2*pi*f/fs) *
**其中 A= 正旋波幅度 *
** f=正旋波频率 *
** fs=抽样率 *
************************************************
COEFFS
.word 27980 ;row1
.word 26965 ;row2
.word 25701 ;row3
.word 24219 ;row4
.word 19073 ;col1
.word 16325 ;col2
.word 13085 ;col3
.word 9315 ;col4
***********************************************
**OSCIS 表包含数字正旋振荡器的初始条件 *
** 通常: *
** DEQ: y(n)=2cos(2*pi*f/fs)y(n-1)-y(n-2) *
** I.C.: y(-1)=0 *
** y(-2)=Asin(2*pi*f/fs) *
** 其中 A=正旋波幅度 *
** f=正旋波频率 *
** fs=抽样率 *
**************************************************
OSCIS
.word 0 ;row1 y(n-1) ;;#
.word -1024*5204/10000 ;y(n-2)
.word 0 ;row2 y(n-1)
.word -1024*5686/10000 ;y(n-2)
.word 0 ;row3 y(n-1)
.word -1024*6203/10000 ;y(n-2)
.word 0 ;row4 y(n-1)
.word -1024*6736/10000 ;y(n-2)
.word 0 ;col1 y(n-1)
.word -1024*8132/10000 ;y(n-2)
.word 0 ;col2 y(n-1)
.word -1024*8671/10000 ;y(n-2)
.word 0 ;col3 y(n-1)
.word -1024*9168/10000 ;y(n-2)
.word 0 ;col4 y(n-1)
.word -1024*9587/10000 ;y(n-2)
*********************************************************
**程序名称 :DTMF双音频检测 *
*********************************************************
.mmregs
.include "globals.inc" ; 全局标号
.include "tables.inc" ; 变量表
.text
*********************************************************
** 子程序:initoscis *
** 输入:指向结构DTMFENCOBJ 的指针 *
** 输出:无 *
** 描述:初始化数字正旋振荡器状态 *
** 它将指定状态集的状态复制到对应的振荡器状态缓冲区中 *
*********************************************************
_initoscis
nop
pshm ST0
pshm ST1
pshm AR1
pshm AR6
pshm AR7
nop
;(A)=指向结构DTMFENCOBJ
;*SP(6)=数字
stlm A,AR6 ;AR6用做指向结构元素的指针
;*AR6(0)= 指向数据
;*AR6(1)=指向振荡器状态
ld #0,ASM ;ASM=0
stm #OSCIS,AR2 ;AR2指向振荡器状态表
ld *AR6(1),A
stlm A,AR3 ;AR3 指向通道振荡器状态表
ld *AR2+,16,A ;装入第一个值
rpt #(16-1) ;for (k=0;k<16;k++) {
st A,*AR3+ ;store (AH)
ld *AR2+,A ;load (AH) ;;;;;#
;}
popm AR7
popm AR6
popm AR1
popm ST1
popm ST0
ret
*************************************************
*子程序:dtmftone *
*输入:指向结构DTMFENCOBJ的指针 *
*输出:无 *
*描述:计算DTMF 双音频的102个采样值 *
*子程序根据指针值取出数字, 并将其送入堆栈进行编码 *
**************************************************
_dtmftone
nop
pshm ST0
pshm ST1
pshm AR1
pshm AR6
pshm AR7
nop
frame #-2 ;---局部变量---
;*SP(0)=衰减值
;----参数----
;(A)指向结构DTMFENCOBJ
;*SP(8)=数字
stlm A,AR6 ;AR6 用做指针指向结构元素
;*AR6(0)=指向数据
;*AR6(1)=指向振荡器
;*AR6(2)=音频衰减值
ssbx FRCT ; 设置分频模式
;---数字解包 ,指针指向振荡器抽头系数---
ld *SP(8),A
stlm A,AR0 ;AR0 为映射表的偏移量
stm #KEYS,AR2 ;AR2 指向映射表首地址
nop
mar *AR2+0 ;AR2 指向映射表中对应的数字
ld *AR2,A ;数字装入A
ld A,B ;(A)-->(B)
and #0f00h,A ;取行部分
sftl A,-8 ;(A)右移8位
stlm A,AR2 ;AR2包含行音频的系数表偏移量
sftl A,1 ;(A)<<1
stlm A,AR4 ;AR4包含行音频振荡器表偏移量
and #000fh,B ;取列部分
add #4,B ;B+4=列音频的系数表偏移量
stlm B,AR3 ;AR3包含列音频的系数表偏移量
sftl B,1 ;(B)<<1
stm #COEFFS,AR0 ;AR0指向系数表
stlm B,AR5 ;AR5 包含列音频振荡器表偏移量
mar *AR2+0 ;AR2指向行音频系数
mar *AR3+0 ;AR3 指向列音频系数
ld *AR6(1),A ;装入指向数据的指针
stlm A,AR0 ;AR0 指向振荡器表
ld *AR6(2),B ;装入衰减值
stl B,*SP(0) ;存储到局部变量区
mar *AR4+0 ;AR4 指向行音频振荡器
mar *AR5+0 ;AR5 指向列音频振荡器
mar *AR4+ ;AR4 指向行音频y(n-2)
mar *AR5+ ;AR5 指向列音频y(n-2)
;--产生DTMF音频-------------
ld *AR6(0),A
stlm A,AR1 ;AR1指向数据
stm #(N-1),BRC
rptb oscil-1 ;for(n=0;n<N;n++) {
ld #0,A ;--产生行音频采样值--
sub *AR4-,16,A ;(A)=-y(n-2)
mac *AR4,*AR2,A ;(A)=coef×y(n-1)-y(n-2)
mac *AR4,*AR2,A ;(A)=2coef×y(n-1)-y(n-2)
delay *AR4,*AR2,A ;y(n-1)-->y(n-2)
sth A,*AR4 ;(A)-->y(n-1)
ld #0,A ;--产生列音频采样值--
sub *AR5-,16,A ;(A)=-y(n-2)
mac *AR5,*AR3,A ;(A)=coef×y(n-1)-y(n-2)
mac *AR5,*AR3,A ;(A)=2coef×y(n-1)-y(n-2)
delay *AR5 ;y(n-1)-->y(n-2)
sth A,*AR5+ ;(A)-->y(n-2)
add *AR4+,16,A ;(A)=row-tone+col-tone
mpya *SP(0) ;(A)=attn×(AH)
sth B,*AR1+ ;(A) -->x(n) }
oscil:
frame #2
nop
popm AR7
popm AR6
popm AR1
popm ST1
popm ST0
ret
******************************************************************
**子程序:gaincntrl *
**输入:指向结构DTMFDECOBJ的指针 *
**输出:无 *
**描述:定标数据块,确保执行goertzel算法时无溢出 *
** gain_power=(1/64)×SUM{0,N-1}[x(n)×x(n)] *
** =(1/64)×N×signalpower *
** gain_lim =(1/64)×(1/N) *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -