《dsp_dtmf信号产生与识别_设计报告》由会员分享,可在线阅读,更多相关《dsp_dtmf信号产生与识别_设计报告(23页珍藏版)》请在金锄头文库上搜索。
1、课程设计报告 课程名称: 基于 DSP 的系统设计 设计名称: 双音多频信号发生与检测 实验人员: 刘鹏飞、孙臻、苏莹 验收状态: 已验收 报告人: 孙臻 班级: 无 21 学号: 2012011241 时间: 2015/11/22 一、 介绍 双音多频 DTMF(Dual Tone Multi-Frequency)信令在全世界范围内得到广泛应用,因其提供更高的拨号速率,迅速取代了传统转盘式电话机使用的拨号脉冲信令。根据 CCITT(国际电报电话咨询委员会的简称,它是国际电信联盟(ITU)的常设机构之一)的建议,国际采用的频率为 687Hz、770 Hz 、852 Hz、941 Hz 、120
2、9 Hz、1336 Hz 、1477 Hz 和 1633 Hz 等 8 种。用这 8 种频率可形成 16 种不同的组合,从而代表 16种不同的数字或功能键,组合表如下: 表表1 DTFM频率分配表频率分配表 Hz 频率频率 1209 1336 1447 1663 697 1 2 3 A 770 4 5 6 B 852 7 8 9 C 941 * 0 # D DTMF用 2个特定的单音频组合信号代表数字信号,以实现其功能。2个单音频的频率不同,代表的数字或实现的功能也不同。一个 DTMF 信号由两个频率的音频/波形信号叠加构成。这两个音频信号的频率来自两组预分配的频率组:行频组或列频组(分别对应
3、低频组和高频组)。每一对这样的音频信号唯一表示一个数字或符号。 本次实验完成了双音多频信号的发生,即通过小键盘的拨号能够输出对应DTMF 信号;以及完成双音多频信号的解码,即确定 DTFM 信号的主频,并确定按键数字。 二、 任务分工 孙臻:DTMF 信号产生模块 苏莹:DTMF 信号检测模块 刘鹏飞:按键输入模块 三、 实验原理 1. DTFM 信号的产生信号的产生 DTMF 信号的产生基于两个二阶数字正弦波振荡器,一个用于产生行频,一个用于产生列频。典型的 DTMF 信号频率范围是 7001700Hz(见表 1),选取8000Hz 作为采样频率。产生 DTMF 信号的数字振荡器对的框图如下
4、图所示: 图图 1 DTMF 信号产生示意图信号产生示意图 单频信号的产生可以用 IIR 系统设计数字余弦振荡发生器,其差分方程为: y(n) = -a1 y(n - 1) - a2 y(n - 2),a1 = 2cos(w0 ),a2 = 1,w0 = 2 f0 / fs , 其中, fs 是采样频率,f0 是输出正弦波的频率度,初值: y(-1) = 0 ,y(-2) = Asin(w0 ) ,A 为输出正弦波的幅值。输入不同的系数与初始条件(含高、低频组共两组),就可以一个振荡器对产生所需的八个音频信号。 2. DTMF 信号的检测信号的检测 DTMF检测器的核心是 Goertzel算法
5、。该算法利用二极点的 IIR滤波器计算离散傅里叶变换值,能够快速高效地提取输入信号的频域信息。由于 IIR 滤波器是一个递归结构,它利用只有一个实系数的差分方程进行操作,并不像 DFT 或 FFT算法那样需要计算数据块,而是每输入一个样值就执行一次算法。 完成时域到频域的变换可以用离散傅里叶变换(DFT)或快速傅里叶变换(FFT)。FFT 计算出所有点频率,而 DFT 可以只计算感兴趣的频率点。如果要计算的频率点数少于 log2N(N为输入信号点数),采用 DFT的计算速度比 FFT 要快。 直接计算 DFT,需要很多复系数,即使只计算一点的 DFT 也需要 N 个复系数,采用数字信号处理中的
6、 Goertzel 算法,可以明显地提高速度。对于 DTMF 信号只需关心其 8 个行频/列频,Goertzel 算法能更快地提取频谱信息,Goertzel 算法的实质是一个两极点的 IIR滤波器,其算法原理框图如下: 图图 2 Goertzel 算法示意图算法示意图 传递函数如下: () =1 /1 2cos(2 )1+ 2式中,fi 表示 DTMF 频率,fs 表示采样频率。信号流图中,左边为递归部分,右边为非递归部分,由于只需要求出 N 点时刻的(),只需要在 N 次递归之后,计算非递归部分的一次即可,即X() = () = () 2 ( 1)。 由于只需要得到 X(f)的幅度,可以进一
7、步简化计算: |()|2= |()|2 22 S(N)S(N 1) + |( 1)|2 可以避免复数计算,且对应每个频点只需存出一个系数即2cos2。其中k = f N/fs,当 N取值为 125时,k 的取值经计算如表所示: 表表 2 k 的取值的取值 信 号 频 率信 号 频 率(HZ) 计算值计算值 K 取整值取整值 K 绝对误差绝对误差 相对误差相对误差 697 10.891 11 0.109 1.00% 770 12.031 12 0.031 0.260% 852 13.313 13 0.313 2.347% 941 14.703 15 0.297 2.019% 1209 18.89
8、1 19 0.109 0.579% 1336 20.875 21 0.125 0.599% 1477 23.078 23 0.078 0.339% 1633 25.516 25 0.516 2.021% 得到行列频率的频谱平方幅度信息之后,就可以通过一系列的判决来确定音频及数字结果的有效性。 得到 DFT 后进行门限判决。首先,检测可能 DTMF 信号的强度是否足够大。行频率分量和列频率分量的平方幅度和应高于某一确定门限。注意与 DTMF 频率相符的正弦波的能量集中在频域内一段很窄的范围当中,所以门限取值应占动态范围的大部分。第二,如果 DTMF 信号存在,由于构成 DTMF 信号的行频都低于
9、列频,因此从小到大依次判断各个频率点的频谱幅度,得到的第一个到达门限要求的频率点即为行频,第二个即为列频,综合行频和列频即可得出检测到的按键信息。 3. 按键输入按键输入 按键输入原理: PA3PA0 为行线输入端,PA7PA4 为列线输出端, PA0-PA7 全部接上拉电 阻。PA7PA4 向所有的列线分别且循环输出低电平即0111,1011,1101,1110; 读取各行线PA3PA0 的状态,若行线状态全为高电平,则表明无键按下,若行线 状态中有低电平,则表明有键按下。即:PA7PA4 四条列扫描线在每次输出低电 平期间,同时读取各行线PA3PA0的状态,确定键值。例如:PA7PA4 输
10、出 “1011“,此时若读取PA3PA0 的状态为“1110“,则表明按键S2 被按下。 将键盘 8 条扫描线与BF533 地址空间的0x203E0000 相连接,对应如下表 (逻辑1 表示高电平,逻辑0 表示低电平)。 在程序中不断向该地址循环写入 0xfe,0xfd,0xfb,0xf7,经短暂延时后,在读取该地址的值。最后根据得到的值,判断被按下的键。 四、 实验结果 输入一种 DTFM信号(输入“4” ) ,产生的波形如图所示 扫描线 PA0 PA1 PA2 PA3 PA4 PA5 PA6 PA7 地址位 7 6 5 4 3 2 1 0 图图 3 DTMF 信号波形信号波形 用 matl
11、ab分析产生的 DTFT信号得下图 两个频点分别约为: 经 detect()检测,得到的该信号各频率信号强度为 因此判定的结果为 为确定检测结果的正确性,用 visualDSP对产生的 DTFM 信号做频谱分析如下: 图图 4 DTMF 信号的信号的 fft 频谱在 770Hz 左右和 1210Hz 左右处出现两个峰,说明判定结果正确。 (试验其余数据也正确) 关于按键部分,由于验收的时候被助教告知按键板有问题,因此此部分没能调试成功。 按键部分核心代码为: unsigned char scanfkb() int keypressflag ; unsigned char oldkbdat,kb
12、dat; unsigned char output = NULL; int i; unsigned char row=0x1; for(i = 0;i 0; i-); static void mdelay(volatile int ms) while(ms-) udelay(300); “receive.c” (信号检测信号检测) #include “DTMF_generating.h“ float buffer125; float pi=3.1415926; /fract16 receive125; int k=0; int flag=0; void detect(float buffer
13、) int i,j,x,y; float w8,a83,amp8; w0=2*cos(2*pi*11/125); w1=2*cos(2*pi*12/125); w2=2*cos(2*pi*13/125); w3=2*cos(2*pi*15/125); w4=2*cos(2*pi*19/125); w5=2*cos(2*pi*21/125); w6=2*cos(2*pi*23/125); w7=2*cos(2*pi*26/125); for(i=0;i500)/门限值 j+; if(j=1) x=i; else if(j=2) y=i; i=-1; if(flag=0) if(j=2)/双音频检测 if(x=0 else if(x=0 else if(x=0 else if(x=1 else if(x=1 else if(x=1 else if(x=2 else if(x=2 else if(x=2 else if(x=3 else if(x=0 else if(x=1 else if(x=2 else if(x=3 else if(x=3 else if(x=3 if(i!=-1) printf(“The DTMF signal %c.rn“,i); flag+; else if(j=0) flag=0;