编辑: f19970615123fa | 2019-12-26 |
DTMF信号的产生: 根据CCITT的建议,国际上采用的多种频率为687Hz、770Hz、852Hz、941Hz、1209Hz、1336Hz、1477Hz和1633Hz等8种.用这8种频率可形成16种不同的组合,从而代表16种不同的数字或功能键,具体组合见下表1: ??????? 行频/Hz ???? 列频/Hz 5:1209 6:1336 7:1477 8:1633 1:697
1 2
3 A 2:770
4 5
6 B 3:852
7 8
9 C 4:941 *
0 # D 设按键产生的信号被采样后是一个正弦序列,正弦序列的Z变换为: 其中 反变换得二阶差分方程,它的单位冲击响应就是 根据AT&T(美国电话电报公司)技术规范: (1)数字号码最大传输速度为每秒10个,即一个号码占100ms时间片. (2)在100ms时间片内双音多频信号持续不少于45ms且不多于55ms的时间. 典型的DTMF信号频率范围是700~1700Hz,根据Nyquist条件,采样频率fs=|f(max)*2+Δf|, f(max)=1700,所以fs>3400.为了减少码元间干扰,因此我们选取8000Hz作为采样频率. 由wT=2*pi*fk/fs,设采样频率fs=8000HZ,则8个频率的系数为 A=[1.7077;
1.6453;
1.5687;
1.4782;
1.1641;
0.9964;
0.7986;
0.5685];
C=[0.52047;
0.56857;
0.62033;
0.67358;
0.81314;
0.86706;
0.91680;
0.95874];
然后,由两个不同频率的正弦信号叠加而成来模拟双音频信号,有上面的式子可得: y(n)=h1(n)+h2(n). ( h1(n)为具有行频的正弦信号,h2(n)为具有列频的正弦信号) 二.DTMF信号的检测: 我采用的DTMF信号检测的原理是分析信号的频谱特性来分辨不同信息 .整个检测过程分两步:首先采用Goertzel算法在输入信号中提取频谱信息;
接着分析频谱信息,提取输入的DTMF信号码. Goertzel算法具体推导如下: DFT公式: 由欧拉公式得: 所以 令n=m,则这样变成了熟悉的卷积公式. 所以对序列x(n)的DFT变成了与系统传递函数的卷积值即: 对进行Z变换可得: 由于为复数,继续变换: 因此, H(z)可看作是级联型网络: 因此X(n)过第一级后: (1-4) 其中V(-1)=V(-2)=0.过第二级后: . 所以,避免复数运算,用x(n)过系统后的功率: (n = N) (1-5) 算法的描述如下: 实际操作中,由于有声音等信号的干扰,所以还要同时检测DTMF信号的二次谐波是否同时存在,如果同时存在,才能判定结果是正确的,这样提高了抗干扰性能. DFT的频率采样点频率为(k为周期数,k=0,1,2,---,N-1),K=,相应的模拟域采样点频率为(k=0,1,2,---,N-1),希望选择一个合适的N,使用该公式算出的能接近要检测的频率,或者用8个频率中的任一个频率代入公式中时,得到的k值最接近整数值,这样虽然用幅度最大点检测的频率有误差,但可以准确判断所对应的DTMF频率,即可以准确判断所对应的数字或符号.经过分析研究认为N=205是最好的.按照=8KHz,N=205,算出8个频率及其二次谐波对应k值,和k取整数时的频率误差见表10.6.2. 表10.6.2 8个基频 Hz 最近的整数k值DFT的 k值 绝对误差 二次谐波 Hz 对应的 k值 最近的 整数k值 绝对误差
697 17.861
18 0.139
1394 35.024
35 0.024
770 19.531
20 0.269
1540 38.692
39 0.308
852 21.833
22 0.167
1704 42.813
43 0.187
941 24.113
24 0.113
1882 47.285
47 0.285
1209 30.981
31 0.019
2418 60.752
61 0.248
1336 34.235
34 0.235
2672 67.134
67 0.134
1477 37.848
38 0.152
2954 74.219
74 0.219
1633 41.846
42 0.154
3266 82.058
82 0.058 通过以上分析,确定=8KHz,N=205,. 每N个数字信号的输入就获得8个点的功率频谱,相当于让信号分别通过8种滤波器,每种滤波器滤出一个点的频谱信息.然后给出一个功率的阀值,大于该值为有效值,找出该值的位置,即可计算出相应的字符.如: 经过判决得到: s=[1 5] (表示8位数组的第1,5位.) 由此可知信号对应的频率为:697
1209 通过关系式: str='123A456B789C*0#DX';
q=(s(1)-1)*4+s(2)-4 result=str(q);
result中的字符便为输入的符号信息.