📄 dtmfgai.asm
字号:
SFTA A,15 ;移位商->AH
SUB #THR_REVTWI,16,A;
BC err_revtwi,ALEQ ;if((COLMAX/ROWMAX)<<THR_REVTWI,跳到err_revtwi
B rel_check
;else
twist2:
LD *AR3,16,A ;(AH)=ROWMAX
RPT #(16-1)
SUBC *AR4,A ;计算(ROWMAX/COLMAX)
AND #0ffffh,A ;保存商(AL),屏蔽余数
SFTA A,15 ;移位商->AH
SUB #THR_STDTWI,16,A;
BC err_stdtwi,ALEQ ;if((COLMAX/ROWMAX)<<THR_REVTWI,跳到err_stdtwi
B rel_check
err_revtwi: ;***记录COLMAX/ROWMAX误差***
ORM 0002h,*AR5(6) ;设置COLMAX/ROWMAX误差信号(b1)
B ende ;中断检测
err_stdtwi:
ORM #0004h,*AR5(6) ;设置COLMAX/ROWMAX误差(b2)
B ende ;中断检测
;---------------------------------------------------
; 相对峰值检测
; 找出相对行峰值->RELPEAK
; if(RELPEAK/ROWMAX<THR_ROWREL) 继续
; else 中断所有检测
; 找出列相对峰值-->RELPEAK
; if(RELPEAK/COLMAX<THR_ROWREL) 继续
; else 中断所有检测
; AR3 指向 ROWMAX
; AR4 指向 COLMAX
;---------------------------------------------------
;----相对行峰值比率检测----
rel_check:
LD *AR5(2),A
STLM A,AR0 ;AR0指向ENERGY表(行频率)
LD #0,B ;(BH)=0
STM #(4-1),BRC
RPTB REL12-1 ;for(k=0;k<4;k++)
LD *AR0,16,A ;(AH)=E[k]
CMPR 0,AR3
BC REL11,TC ;if(AR0==AR3)
MAX B ;(B)=newmax=max(oldmax,E[k])
rel11:
MAR *AR0+
rel12:
RPT #(16-1)
SUBC *AR3,B ;计算(RELPEAK/ROWMAX)
AND #0FFFFh,B ;保存商(BL),屏蔽剩下位
SFTA B,15 ;商移位-->BH
SUB #THR_ROWREL,16,B
BC ERR_ROWREL,BGEQ
;if((RELPEAK/ROWMAX)>=THR_ROWREL)
;跳转到err_rowrel
;----相对列峰值比率检测----
rel2:
LD #0,B ;(BH)=0
STM #(4-1),BRC
RPTB REL22-1 ;for(k=4;k<8;k++)
LD *AR0,16,A ;(AH)=E[k]
CMPR 0,AR4
BC REL21,TC ;if(AR0==AR4)
MAX B ;(B)=newmax=max(oldmax,E[k])
rel21:
MAR *AR0+
rel22:
RPT #(16-1)
SUBC *AR4,B ;计算(RELPEAK/COLMAX)
AND #0ffffh,B ;保存商(BL),屏蔽其余位
SFTA B,15 ;移位商->BH
SUB #THR_COLREL,16,B;
BC err_colrel,BGEQ
;if((RELPEAK/COLMAX)>=THR_COLREL)
;跳转到err_colrel
B sec_check
err_rowrel: ;******记录行相对峰值错误**********
ORM #0008h,*AR5(6) ;设置行相对峰值错误(b3)
B ende ;终止检测
;*******记录列相对峰值错误*********
err_colrel:
ORM #0010h,*AR5(6) ;设置列相对峰值误差信号(b4)
B ende ;终止检测
;---------------------------------------------------
; 二次谐波检测
; if ((ROW2nd/ROWMAX)<THR_ROW2nd) 继续
; else终止所有检测
; if ((COL2nd/COLMAX)<THR_COL2nd) 继续
; else终止所有检测
; AR3指向ROWMAX
; AR4指向COLMAX
;---------------------------------------------------
sec_check:
MVMM AR3,AR6 ;备份AR3
MVMM AR4,AR7 ;备份AR4
;=============行音频的二次谐波检测==============
;----定义指向系数表的指针(AR3)----
LD *AR5(2),A ;从结构装入指向系数的指针
STLM A,AR0 ;AR0指向能量模块
NOP
NOP ;流水线延迟
MAR *AR3-0 ;AR3 包含能量模块中的偏移
MVMM AR3,AR1 ;AR3->AR1
STM #COEF2nd,AR0 ;AR0指向二次谐波系数
MAR *AR3+0 ;AR3指向需要的系数
;----定义指向抽头的指针(AR4)----
LD *AR5(1),A ;从结构中装入指向抽头的指针
ADD #3,A
STLM A,AR4 ;AR4指向行音频二次谐波抽头
;----定义指向能量的指针(AR1)----
LD *AR5(2),A
ADD #8,A
STLM A,AR1 ;AR1指向行二次谐波能量模块
;----计算goertzel滤波----
LD #0,ASM ;ASM=0
LD *AR5(0),A
STLM A,AR2 ;AR2指向数据
STLM #(N-1),BRC
LD *AR2+,16,A ;(AH)=x(n)
RPTB sec1-1 ;for(n=0;n<N;n++) {
SUB *AR4-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR4,*AR3,B ;(B)=coef×vk(n-1)-vk(n-2)+x(n)
MAC *AR4,*AR3,B ;(B)=2coef×vk(n-1)-vk(n-2)+x(n)
DELAY *AR4 ;vk(n-1)->vk(n-2)
ST B,*AR4+ ;(B)->vk(n-1)
||LD *AR2+,A ;(AH)=x(n)
sec1: ;}
;----计算能量----
LD *AR4,16,A ;(A)=vk(N-1),A(32:16)loaded
MPYA *AR4- ;(B)=vk(N-1)×vk(N-1),(T)=vk(N-1)
MPY *AR4,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 *AR4,T ;(T)=vk(N)
MAC *AR4,B ;(B)=vk(N)×vk(N)-2coef×vk(N)×vk(N-1)+vk(N-1)×vk(N-1)
STH B,*AR1 ;存储结果E[k]到能量模块
;----检查门限条件----
LD *AR1,16,A ;(AH)=ROW2nd
SUB *AR6,16,A,B ;(BH)=ROW2nd-ROWMAX
BC err_row2nd,BGEQ ;if(ROW2nd<ROWMAX)
RPT #(16-1)
SUBC *AR6,A ;计算(ROW2nd/ROWMAX)
AND #0ffffh,A ;取商(AL),屏蔽余数
SFTA A,15 ;商<<15->AH
SUB #THR_ROW2nd,16,A
BC err_row2nd,AGEQ
;if ((ROW2nd/ROWMAX)>=THR_ROW2nd)
;跳转到err_row2nd
;=======列音频的二次谐波检测==========================
;----定义指向系数表的指针(AR3)----
MVMM AR7,AR3 ;AR3指向COLMAX
LD *AR5(2),A ;从结构中装入指向系数的指针
STLM A,AR0 ;AR0指向能量模块
NOP
NOP ;流水线延迟
MAR *AR3-0 ;AR3包含能量模块的偏移量
MVMM AR3,AR1 ;存储偏移量到AR1
STM #COEF2nd,AR0 ;AR0指向二次谐波系数
MAR *AR3+0 ;AR3指向需要的系数
;----定义指向抽头的指针(AR4)----
LD *AR5(1),A ;从结构中装入指针指向抽头
ADD #1,A ;
STLM A,AR4 ;AR4指向列音频二次谐波抽头
;----定义指向能量的指针(AR1)----
LD *AR5(2),A
ADD #9,A
STLM A,AR1 ;AR1指向能量模块的列音频二次谐波
;----计算goertzel滤波----
LD #0,ASM ;ASM=0
LD *AR5(0),A
STLM A,AR2 ;AR2指向数据
STM #(N-1),BRC
LD *AR2+,16,A ;(AH)=x(n)
RPTB sec2-1 ;for(n=0;n<N;n++){
SUB *AR4-,16,A,B ;(B)=-vk(n-2)+x(n)
MAC *AR4,*AR3,B ;(B)=coef*vk(n-1)-vk(n-2)+x(n)
MAC *AR4,*AR3,B ;(B)=2coef*vk(n-1)-vk(n-2)+x(n)
DELAY *AR4 ;vk(n-1)->vk(n-2)
ST B,*AR4+ ;(B)->vk(n-1)
||LD *AR2+,A ;(AH)=x(n)
sec2 ;}
;----计算能量----------------
LD *AR4,16,A ;(A)=vk(N-1),A(32:16)loaded
MPYA *AR4- ;(B)=vk(N-1)*vk(N-1),(T)=vk(N-1)
MPY *AR4,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 *AR4,T ;(T)=vk(N)
MAC *AR4,B ;(B)=vk(N)*vk(N)-2coef*vk(N)*vk(N-1)+vk(N-1)*vk(N-1)
STH B,*AR1 ;存储结果E[k]到能量模块
;----检测门限条件----
LD *AR1,16,A ;(AH)=COL2nd
SUB *AR7,16,A,B ;(BH)=COL2nd-COLMAX
BC err_col2nd,BGEQ ;if(COL2nd<COLMAX)
RPT #(16-1)
SUBC *AR7,A ;计算(COL2nd/COLMAX)
AND #0ffffh,A ;取商(AL),屏蔽系数
SFTA A,15 ;商<<15->AH
SUB #THR_COL2nd,16,A
BC err_col2nd,AGEQ ;if((COL2nd/COLMAX)≥THR_COL2nd)
;跳转到err_col2nd
MVMM AR6,AR3 ;恢复AR3
MVMM AR7,AR4 ;恢复AR4
B digit_map
ERR_ROW2ND: ;****记录行音频二次谐波系数****
ORM #0020h,*AR5(6) ;设置行二次谐波错误标志(b5)
B ende ;终止检测
err_col2nd: ;****记录列音频二次谐波系数****
ORM #0040h,*AR5(6) ;设置列二次谐波错误标志(b6)
B ende ;终止检测
;----------------------------------------------------
; 映射双音频为数字
; AR3指向ROWMAX
; AR4指向COLMAX
;----------------------------------------------------
digit_map:
;--------找出行和列的位置----------------------
LD *AR5(2),A
STLM A,AR0 ;装入偏移量
NOP
NOP
MAR *AR3-0 ;AR3包含行号
MAR *+AR0(4)
MAR *AR4-0 ;AR4包含列号
;-------映射行列的位置到实际数字---------------
LD *(AR3),8,A ;行号放入累加器AL的高字节
add *(AR4),A ;列号放入累加器AL的高字节
STM #KEYS,AR2 ;AR2指向键盘映射表
STM #0,AR3 ;AR3用作计数器
STM #(16-1),BRC
RPTB digit3-1 ;for(k=0;k<16;k++) {
SUB *AR2+,A,B
BC digit31,bneq ;if(A==KEYS[k]) 插入延迟
B digit4 ;调转到ende
digit31:
MAR *AR3+ ;增加计数器值
digit3: ;}
;-----------------------------------------------
; 和上次数字比较,判断当前数字是否有效?
;-----------------------------------------------
digit4:
NOP ;AR3包含解码的数字
LD *AR5(3),A
STLM A,AR4 ;AR4用作数字指针
ORM #0100h,*AR5(5) ;设置"持续计数器"忍?
LDM AR3,A ;装入当前数字
SUB *AR5(4),A,B ;和上次数字比较
BC digit5,bneq ;if当前数字和上次数字一致
STL A,*AR4+ ;存储VALID DIGIT到DIGITS
LDM AR4,A
STL A,*AR5(3) ;更新指针
ST #0,*AR5(5) ;屏蔽检测器,等待停顿
ST #-1,*AR5(4) ;上次数字复位
B ende ;else
digit5:
LDM AR3,A ;存储解码数字为上次数字digitlast
STL A,*AR5(4)
ende:
BITF *AR5(5),#0400h ;测试持续计数器
BC endl,NTC ;if(持续计数器=1)
ST #0,*AR5(5) ;屏蔽检测器,等待停顿
ST #-1,*AR5(4) ;上次数字复位
endl:
FRAME #0
POPM AR7
POPM AR6
POPM AR1
POPM ST1
POPM ST0
NOP
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -