DSPDTMF信号的产生于检测概述.docx
《DSPDTMF信号的产生于检测概述.docx》由会员分享,可在线阅读,更多相关《DSPDTMF信号的产生于检测概述.docx(25页珍藏版)》请在冰豆网上搜索。
![DSPDTMF信号的产生于检测概述.docx](https://file1.bdocx.com/fileroot1/2023-6/19/6e99d938-b2f2-45b1-9c25-f6e90194472e/6e99d938-b2f2-45b1-9c25-f6e90194472e1.gif)
DSPDTMF信号的产生于检测概述
DSP课程设计
实验报告
DTMF信号的产生及检测
院(系):
电子工程信息学院
设计人员:
黄炜学号:
07291039
曹磊07211193
成绩:
工程设计50
报告20
答辩30
总分
评语:
指导教师签字:
日期:
一、设计任务书…………………………………………………………1
二、设计内容……………………………………………………………5
三、设计方案、算法原理说明…………………………………………10
四、程序设计、调试与结果分析………………………………………15
五、设计(安装)与调试的体会………………………………………25
六、参考文献……………………………………………………………26
一、实验目的:
(1)熟悉CCS的编程环境和基本试验调试流程和方法;
(2)了解并掌握DTMF信号的产生和检测远离核试验流程;
(3)编写C语言程序,并在CCS集成开发环境下调试通过;
(4)熟练使用软件CCS5000对程序的完整调试过程。
二、实验内容:
1)利用DTMF信号产生的原理合成数字信号并分析其时域波形和频谱;
2)生成各个按键信号;
3)分析0~9,A~D,*、#几个拨号信息的频谱,观察频谱图中的峰值点的幅值以及它们出现的位置。
根据谱峰的幅值和位置,识别各DTMF信号所对应对应的数字;
4)编写Goertzel算法的程序,识别各DTMF信号所对应对应的数字。
5)生成一串拨号音,例如8位电话号码,进行识别;
三、实验原理及程序设计:
1、DTMF(双音多频)信号简介
双音多频DTMF(DualToneMulti—Frequency)信号在全世界范围内得到广泛应用,将DTMF信号的产生与检测集成到含有数字信号处理器(DSP)的系统中,是一项较有价值的工程应用。
双音多频DTMF(DualToneMulti—Frequency)信号,逐渐在全世界范围内使用在按键式电话机上,因其提供更高的拨号速率,迅速取代了传统转盘式电话机使用的拨号脉冲信号。
近年来DTMF也应用在交互式控制中,诸如语言菜单、语言邮件、电话银行和ATM终端等。
将DTMF信号的产生与检测集成到任一含有数字信号处理器(DSP)的系统中,是一项较有价值的工程应用。
CCITT(国际电报电话咨询委员会)建议,国际上采用697Hz、770Hz、852Hz、941Hz、1209Hz、1336Hz、1477Hz、1633Hz12个频率,并将其分成两个群,即低频群和高频群。
从低频群和高频群中任意抽出一个频率进行叠加组合,具有16种组合形式,让其代表数字和功率,如下图电话机键盘的频率矩阵所列。
本实验的目的是使用TMS320C52来制作DTMF发生器和检测器。
DTMF信号是音频电话的拨号信号,这种拨号方法取代了脉冲拨号,每一个号码由两个音频信号组成,该双音频由按键所在的行和列对应的频率决定(如图所示)。
电话中的双音多频信号(DTMF)有两种作用:
一是用于双音多频信号的拨号,去控制交换机接通被叫的用户电话机;二是利用双音多频信号控制电话机各种动作,如播放留言、语言信箱等。
这些功能的实现离不开DTMF信号的正确产生和检测,专用数字处理信号芯片(DSP)的出现,使这个问题得到轻松的解决。
2、DTMF的产生
DTMF的产生原理
DTMF发生器基于两个二阶数字正弦振荡器,一个用于产生行频,一个用于产生列频。
DSP只要装载相应的系数和初始条件,就可以只用两个振荡器产生所需的八种音频信号。
典型的DTMF信号频率范围是700~1700Hz,选取8000Hz作为采样频率,即可满足奈奎斯特定理。
设x[k]为DTMF信号,产生方式为:
x[k]=Asin(
k)+Bsin(
k)
式中
=2*pi*
/
和
=2*pi*
/
分别表示高频和低频频率,A、B分别为低频群和高频群样值的量化基线。
振荡器实现过程中,首先将每个频率的常数存在一个表中,用来初始化给定键的振荡器;再按照上式的算法迭代计算,就得到正弦序列的输出;将两个这样的输出叠加即可得到双音频的输出。
每一个数字抢出的样本数取决于数字速率与采样速率.双音频中的每一个音调之后是同样长度的无音周期,从而可以检测到按键的释放。
CCITT对DTMF信号规定的指标是,传送/接收率为每秒10个数字,即每个数字100ms。
代表数字的音频信号必须持续至少45ms,但不超过55ms。
100ms内其他时间为静音(无信号),以便区别连续的两个按键信号。
下图为DTMF频率及其对应的键值
3、DTMF信号的识别
常用的多频信号检测手段主要有FFT变换、滤波器组和线性滤波法三种。
DTMF解码即是在输入信号中搜索出有效的行频和列频。
计算数字信号的频谱可以采用DFT及其快速算法FFT,而在实现DTMF解码时,采用Goertzel算法要比FFT更快。
Goertzel算法属于线性滤波法,它可从DTFT和DFT中推导。
通过FFT可以计算得到信号所有谱线,了解信号整个频域信息,而对于DTMF信号只用关心其8个行频/列频及其二次谐波信息即可(二次谐波的信息用于将DTMF信号与声音信号区别开)。
此时Goertzel算法能更加快速的在输入信号中提取频谱信息。
Goertzel算法实质是一个两极点的IIR滤波器。
如图知,DFT计算可以等价为:
在实际的DTMF检测中,只需DFT的幅度(本算法为平方幅度)信息就足够了。
对于实序列x(n),Goertzel算法所需的内部变量vk(n)也为实数。
因此计算
如下
在识别DTMF信号时,要求确定抽样点数N,国际上通用N=205点或N=125点。
下表列出了N=205点时,各个频率所对应的DFT结果X[m]中的序号m。
N=205时频率对应的抽样信息
基频
准确值m
最近的整数m值
两点的绝对误差
697
17.861
18
0.139
770
19.731
20
0.269
852
21.833
22
0.167
941
24.113
24
0.113
1209
30.981
31
0.019
1336
34.235
34
0.235
1477
37.848
38
0.152
由于k的舍入误差反映的是频率的偏移,因此必须选择k舍入误差小的N值。
同时还要兼顾每个频率,每个频率k舍入误差都比较小,或者尽可能的都取“舍”或者都取“入”,这样就会使偏移比较小或者都向同一个方向偏移。
4、DTMF检测
C54x的MCBSP接收DTMF信号,每采到一个新样点,样点值代入式
,
迭代计算8个行频/列频的中间变量
(k为8个行频/列频分别对应的数字频率),直到采到N=205个样点(在8kHz采样频率下,约为25ms)。
此时再按式子计算8个行频/列频的幅度平方
。
接下来将
与门限作比较,判决出有效的音频信号。
四、实验程序及注释:
#include"stdio.h"//头文件
#include"math.h"
#include"type.h"
#include"board.h"
//函数原型
voiddelay(intperiod);//定义延时子程序
voidgenerate(floatdtmf[16*800],intstart,intnum[10],intm);//定义DTMF信号产生子程序
voiddetect(floatdtmf[16*800],intstart);//定义DTMF检测子程序
intdata;
floatfreq[16][2]={{941,1336},{697,1209},{697,1336},{697,1447},
{770,1209},{770,1336},{770,1447},{852,1209},
{852,1336},{852,1447},{697,1633},{770,1633},
{852,1633},{941,1633},{941,1209},{941,1477}};
//按顺序,每一行代表0~9,A~D,*,#对应的数字频率
floatpi=3.1415926;
intn;
intnum[10];
s16cnt=2;
//---------------------主程序-----------------------
voidmain()
{
inti;
intnum[10]={0,0,0,0,0,0,0,0,0,0};//初始化数组num[10]
floatdtmf[16*800];
charch[22];
//----------dsk板的初始化---------------------------------
if(brd_init(100))
return;
while(cnt--)//循环闪灯
{
brd_led_toggle(BRD_LED0);
delay(1000);
brd_led_toggle(BRD_LED1);
delay(1000);
brd_led_toggle(BRD_LED2);
delay(1000);
}
//-----------------------------------------------------
printf("请输入要输入字符的位数,要求小于等于8\r\n");
scanf("%d",&n);
printf("请输入n个字符,0-9或A、B、C或D,或*,或#\r\n");
n=2*n;
for(i=0;i{
scanf("%c",&ch[i]);
}
for(i=1;i{
if(ch[i]=='*')'
{
num[(i-1)/2]=14;'
}
elseif(ch[i]=='#')//14代表信号'*',15代表信号'#'
{
num[(i-1)/2]=15;
}
elseif(ch[i]<='9'&&ch[i]>='0')
{
num[(i-1)/2]=(int)(ch[i])-48;//0~9代表信号'0'~'9'
}
elseif(ch[i]<='D'&&ch[i]>='A')
{
num[(i-1)/2]=(int)(ch[i])-65+10;//10~13代表信号'A'~'D'
}
}
for(i=0;i<(n/2);i++)//循环产生所输入字符的双音信号
{
generate(dtmf,i*800,num,i);
}
for(i=0;i<(n/2);i++)
{
detect(dtmf,800*i);//信号的识别检测
}
return;
}
//---------------延迟子程序------------------
voiddelay(intperiod)
{
inti,j;
for(i=0;i{
for(j=0;j>1;j++);
}
}
//---------双音信号产生子程序---------
voidgenerate(floatdtmf[],intstart,intnum[],intm)
{
floatx=0,y=0,z=0;
intj;//模拟数字频率的转换。
x=freq[num[m]][0]/8000*2*pi;//低频音与采样频率之比。
y=freq[num[m]][1]/8000*2*pi;//高频音与采样频率之比。
for(j=1;j<=400;j++)//设产生信号的持续时间为100ms,所以j为400。
{
z=sin(x*j)+sin(y*j);//DTMF信号为一个高频音和一个低频音的组合。
dtmf[start+j-1]=z;//采样值的装入,前四百个点为双音信号采样值,
dtmf[start+j-1+400]=0;//后四百个点为0(即静音信号)。
}
}
//----------信号识别子程序------------------------
voiddetect(floatdtmf[],intstart)
{
inti,j,x,y;
charch;
floatw[8],b[8][3],result[8];
w[0]=2*cos(2*pi*18/205);
w[1]=2*cos(2*pi*20/205);
w[2]=2*cos(2*pi*22/205);
w[3]=2*cos(2*pi*24/205);
w[4]=2*cos(2*pi*31/205);
w[5]=2*cos(2*pi*34/205);
w[6]=2*cos(2*pi*37/205);
w[7]=2*cos(2*pi*42/205);
for(i=0;i<8;i++)//i表示有8个频率点。
{
b[i][0]=0;
b[i][1]=0;
for(j=1;j<=205;j++)
{
b[i][2]=w[i]*b[i][1]-b[i][0]+dtmf[start+j-1];//DFT在8个频率点的值
b[i][0]=b[i][1];//迭代算法
b[i][1]=b[i][2];
}
result[i]=b[i][1]*b[i][1]+b[i][0]*b[i][0]-w[i]*b[i][1]*b[i][0];//每一段的8个频率点
}的幅度平方值
j=0;
for(i=0;i<8;i++)
{
if(result[i]>300)//对result中的值进行检测,与300比较
{//当超过300时,判断此频率点上信号存在
j++;
printf("dtmf[%d]:
%f\r\n",i,result[i]);
if(j==1)//j=1时i的值赋给x,代表低频的信息
{
x=i;
}
elseif(j==2)//j=2时i的值赋给y,代表高频的信息
{
y=i;
}
}
}
ch='e';
if(j==2)
{
if(x==0&&y==4)//若x=0,y=4,则表示低频为697Hz,高频为1209Hz
{
ch='1';//这两个频率所对应的数为1
}
elseif(x==0&&y==5)//若x=0,y=5,则表示低频为697Hz,高频为1336Hz
{
ch='2';//这两个频率所对应的数为2
}
elseif(x==0&&y==6)//以下都依次类推
{
ch='3';
}
elseif(x==1&&y==4)
{
ch='4';
}
elseif(x==1&&y==5)
{
ch='5';
}
elseif(x==1&&y==6)
{
ch='6';
}
elseif(x==2&&y==4)
{
ch='7';
}
elseif(x==2&&y==5)
{
ch='8';
}
elseif(x==2&&y==6)
{
ch='9';
}
elseif(x==3&&y==5)
{
ch='0';
}
elseif(x==3&&y==4)
{
ch='*';
}
elseif(x==3&&y==6)
{
ch='#';
}
elseif(x==0&&y==7)
{
ch='A';
}
elseif(x==1&&y==7)
{
ch='B';
}
elseif(x==2&&y==7)
{
ch='C';
}
elseif(x==3&&y==7)
{
ch='D';
}
}
if(ch!
='e')//满足以上一种情况,则输出检测的信号
{
printf("TheDTMFsignalis\"%c\".\r\n",ch);
}
else//以上情况都不满足,则输出错误信息提示
{
printf("Thenumberinputtediniswrong!
\n");
}
}
五、CCS5000程序调试
1、编译过程、工程架构、编译环境设置
1)创建新的工程
2)向工程中添加文件
从Project/AddFilestoProject,分别选择DTMF.c,5402.cmd(这个文件将片段映射到存储器中),rts.lib(这个库提供目标DSP运行时间支持(runtime-support))等文件。
.h文件将出现在ProjectView窗中的Libraries文件夹。
头文件不能手动添加,自动到:
当前目录(源文件所在)或预编译器的“includeSearchPath
(-i)”option所指定的位置。
显示头文件:
Project—>showDependencies.
右击dtmf.pjt,选择ScanAllDependencies.
3)编译与运行程序
选择Project/RebuildAll或单击(RebuildAll)菜单条按钮,CCS重新进行编辑、汇编、连接工程里的所有文件。
得到结果:
选择File/LoadProgram.选中dtmf.out,并按Open。
CCS将程序装载到目标DSP上,打开显示程序仿汇编指令的Disassembly窗口。
选择Debug/GoMain。
从主程序开始执行
程序执行过程需输入数据
2、程序运行结果及图像:
观察信号时域图
观察信号频域图
信号检测输出
六、实验总结及感想:
通过此次DSP课程设计,使我对上课学过的知识有了进一步的认识。
DTMF信号是我们日常生活中经常接触到的,即电话拨号信令。
在做课程设计时,参考了图书馆的一些书籍以及网上查的资料,从而对双音多频的产生与检测机理有了初步的掌握,然后在CCS编程调试过程中不断实践,改进程序。
在调试程序的过程中,遇到了很多困难,请教了同学以及大四的学长,最后终于成功了。
本实验主要是DTMF双音多频信号的产生与识别,按键信号是由相应两个频率的正弦信号相加而成,通过公式x=freq[num][0]/8000*2*pi以及公式y=freq[num][1]/8000*2*pi,实现对模拟行频和列频向数字的转换,对产生的正弦信号进行400点抽样,存入dtmf数组中,以便检测时调用。
本实验是通过Goertzel算法实现对信号的检测。
通过对迭代方程的计算,得出信号幅值的平方,在八个频率点处与已知常数进行比较,检测出符合条件的频率组合,并输出数值,完成识别过程。
当然,在实验过程中,遇到了很多困难,比如说,程序文件5402.cmd文件,刚开始直接调用,编译时出现错误,根据提示,在一系列的修改尝试后,补加了段sysmem>SCRATCHPAGE1,产生了8个信号。
通过此次实验,我们对DTMF的基础知识有了较深刻的了解,掌握了DTMF的信号产生及信号检验的原理及方法,并熟悉了用C语言对DTMF的编程的方法,通过程序的调用及调式,我们熟悉了DSP5402的体系结构、指令系统等。
我们定会总结实验方法,掌握理论知识,汲取经验教训,为进一步掌握DSP的设计、CCS的使用打下基础。
参考文献
(1)高海林、钱满义.DSP技术及其应用讲义.
(2)TMS320C54xDSPReferenceSetVolume1:
CPUandPeripherals.SPRU131GTexasInstrumentInc,2001
(3)DTMFToneGenerationandDetection:
AnImplementationUsingtheTMS320C54x.SPRA096a,TI.Inc.2000
(4)基于TMS320LF2407A的DTMF产生与检测实验系统设计.pdf
(5)基于DSP的DTMF信号检测.nh
(6)在DSP上实现PCM_FSK_DTMF信号变换.kdh