DSPDTMF信号的产生于检测_第1页
DSPDTMF信号的产生于检测_第2页
DSPDTMF信号的产生于检测_第3页
DSPDTMF信号的产生于检测_第4页
DSPDTMF信号的产生于检测_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、dsp课程设计实 验 报 告dtmf信号的产生及检测院(系):电子信息工程学院 设计人员:李国玮 学号:07211171设计人员:宋弘 学号:07211177成绩:工程设计50报告20答辩30总分评语: 指导教师签字: 日期:目 录一、设计任务书1二、设计内容5三、设计方案、算法原理说明10四、程序设计、调试与结果分析15 五、设计(安装)与调试的体会25 六、参考文献26一、 设计任务书要求完成的任务:(1)编写c语言程序,并在ccs集成开发环境下调试通过。(2)实现设计所要求的各项功能。(3)按要求撰写设计报告。要求达到的目的: (1) 熟悉ccs的编程环境和基本试验调试流程和方法; (2

2、) 熟悉并掌握使用c语言编写较为复杂的程序并用ccs实现; (3) 了解并掌握dtmf信号的产生和检测远离核试验流程; (4) 熟练使用软件ccs5000对程序的完整调试过程。二、设计内容基本部分:(1)使用c语言编写dtmf信号的发生程序,要求循环产生09、*、#、a、b、c、d对应的dtmf信号,并且符合ccitt对dtmf信号规定的指标。(2)使用c语言编写dtmf信号的检测程序,检测到的dtmf编码在屏幕上显示。发挥部分:通过修改程序模拟电话通讯的过程。三、设计方案、算法原理说明双音多频dtmf(dual tone multi frequency)是在按键式电话机上得到广泛应用的音频拨

3、号信令,一个dtmf 信号由两个频率的音频信号叠加构成。这两个音频信号的频率分别来自两组预定义的频率组:行频组和列频组。每组分别包括4 个频率,分别抽出一个频率进行组合就可以组成16 种dtmf 编码,分别记作09、*、#、a、b、c、d。如右图所示。要用dsp 产生dtmf 信号,只要产生两个正弦波叠加在一起即可;dtmf 检测时采用改进的goertzel 算法,从频域搜索两个正弦波的存在。(一)dtmf信号的产生dtmf编码器基于两个二阶数字正弦波振荡器,一个用于产生行频,一个用于产生列频。向dsp装入相应的系数和初始条件,就可以只用两个振荡器产生所需的八个音频信号。典型的dtmf信号频率

4、范围是7001700hz,选取8000hz作为采样频率,即可满足nyquist条件。正弦波是任何波形构成的基本单元,产生正弦波的方法一般有:采样回放法、查表法、泰勒级数展开法、数字正弦振荡器法。我们用的是sin函数产生离散的正弦值,因为这种方法我们比较熟悉而且通过查阅资料这种方法的也能达到误差要求,生成dtmf的公式为:buffert=sin(t*2*pi*f1/fs)+sin(t*2*pi*f1/fs),其中t为采样序数,由0开始递增;f1,f2为生成dtmf信号的两个正弦波的频率;fs为采样频率;buffert为序数t时的得出的采样值。将这些数据转换为q15格式然后通过codec发送出去。

5、ccitt对dtmf信号规定的指标是,传送/接收率为每秒10个数字,即每个数字100ms。代表数字的音频信号必须持续至少45ms,但不超过55ms。100ms内其他时间为静音,以便区别连续的两个按键信号。我们使用8000hz的采样频率,即1秒采样8000个点,则100ms采样800个点,我们设置800个点的缓存,其中用400个存产生的dtmf信号值,即音频信号必须持续50ms,另外400个存0值,即静音信号。 (二)dtmf信号的检测dtmf检测是对进入解码端的信号进行检测,并把双音频信号转换成对应的数字信息。它是一个比dtmf产生更加复杂过程。由于数据流是连续的,为了保证dtmf检测的实时性

6、,因此要求检测过程必须是实时连续的。在输入信号中检测dtmf 信号,需要在输入的数据信号流中连续地搜索dtmf 信号频谱的存在。整个检测过程分两步:首先采用goertzel 算法在输入信号中提取频谱信息;接着作检测结果的有效性检查。dtmf 解码时在输入信号中搜索出有效的行频和列频。计算数字信号的频谱可以采用dft 及其快速算法fft,而在实现dtmf 解码时,采用goertzel 算法要比fft 更快。通过fft 可以计算得到信号所有谱线,了解信号整个频域信息,而对于dtmf 信号只需关心其8 个行频/列频及其二次谐波信息即可,二次谐波的信息用于将dtmf 信号与声音信号区别开。此时goer

7、tzel 算法能更加快速的在输入信号中提取频谱信息。goertzel 算法实质是一个两极点的iir 滤波器。goertzel算法简介dtmf检测器的核心是goertzel算法。该算法利用二极点的iir滤波器计算离散傅立叶变换值,能够快速高效地提取输入信号的频谱信息。由于iir滤波器是一个递归结构,它利用只有一个实系数的差分方程进行操作,并不像dft或fft算法那样需要计算数据块,而是每输入一个样值就执行一次算法。 完成时域到频域的变换可以用离散傅立叶变换(dft)或快速傅立叶变(fft)fft计算出所有点频率,而dft可以只计算感兴趣的频率点如果要计算的频率点数少于log 2n(n为输入信号点

8、数),采用dft的计算速度比fft更快,matlab模拟的结果能很好地说明这个问题。直接计算dft,需要很多复系数,即使只计算一点的dft也需要n个复系数采用数字信号处理中的goertzel算法,则可明显地提高速度。利用二阶复共轭极点可以得到只有一个实系数的差分方程:(1)在实际的dtmf检测中,只需dft的幅度(本算法为平方幅度)信息就足够了,因此在goertzel滤波器中,当n点(相当于dft数据块的长度)样值输入滤波器后,滤波器输出伪dft值vk(n),由vk(n)即可确定频谱的平方幅度。(2)其中k的取值可由下表得到:1st harmonics(n = 205) fs = 8 ksps

9、2nd harmonics(n=201) fs = 8 kspskfrequency(k/n)fs/hzcoefficientcos(2pi k/n)kfrequency(k/n)fs/hzcoefficientcos(2pi k/n)187020.851623513930.45886207800.817933915520.34445228580.781154317110.22470249360.741424718710.101413112100.58157612428-0.329743413260.50442672667-0.500003814830.39505742945-0.676064

10、216390.27972823264-0.83740有效性检测一旦得到行/列频率的频谱平方幅度信息,就可以通过一系列的判决来确定音频及数字结果的有效性。首先,检测可能dtmf信号的强度是否足够大。行频率分量和列频率分量的平方幅度和应高于某一确定门限thr_sig。注意与dtmf频率相符的正弦波的能量集中在频域内一段很窄的范围当中,所以门限取值应占动态范围的大部分。第二,如果dtmf信号存在,由于构成dtmf信号的行频都低于列频,因此从小到大依次判断各个频率点的频谱幅度,得到的第一个达到门限要求的的频率点即为行频,第二个即为列频,综合行频和列频即可得出检测到的是哪个数据。四、程序设计、调试与结果

11、分析我们设计的程序是将dtmf信号的产生与检测分别建立工程,期望在两个dsk板可以实现通信。(一) dtmf信号的产生程序流程包含两个任务,即音频任务和静默任务。在一段时间间隔后两个任务需要进行互换。音频任务的作用是产生双音频采样值,静默任务的作用是产生静默采样值。每个任务被分配一定的持续时间。#include#include#include#include#includevoid delay(s16 period);handle hhandset; /codec句柄变量s16 data;s16 buffer400; /输出缓冲区,用于图形窗口观察输出信号#define pi 3.141592

12、6float fs=8000; /取样频率s16 tel_munber16=1,2,3,4,5,6,7,8,9,0,a,b,c,d,*,#;/dtmf按键缓冲区,为字符变量float dtmf_freq162= 941,1336, /键值1所对应的行频和列频 697,1209, /键值2所对应的行频和列频 697,1336, /键值3所对应的行频和列频 697,1477, /键值4所对应的行频和列频 770,1209, /键值5所对应的行频和列频 770,1336, /键值6所对应的行频和列频 770,1477, /键值7所对应的行频和列频 852,1209, /键值8所对应的行频和列频 85

13、2,1336, /键值9所对应的行频和列频 852,1477, /键值0所对应的行频和列频 697,1633, /键值a所对应的行频和列频 770,1633, /键值b所对应的行频和列频 852,1633, /键值c所对应的行频和列频 941,1633, /键值d所对应的行频和列频 941,1209, /键值*所对应的行频和列频 941,1477, /键值#所对应的行频和列频 ;f32 row_freq162=0;/0-9,*,#各键值的行频系数cos(2*pi*f0/fs)和初始条件sin(2*pi*f0/fs)f32 column_freq162=0;/0-9,*,#各键值的列频系数和初始

14、条件f32 ax1,ay1; /行频、列频的系数f32 xn,xn1,xn2; /行频的二阶差分方程x(n)=-ax1*x(n-1)-ax2*x(n-2)样点f32 yn,yn1,yn2; /列频的二阶差分方程y(n)=-ay1*y(n-1)-ay2*y(n-2)样点f32 zn; /双音多频样点/*/* dtmf发送程序 */*/void main() s16 cnt=2; f32 f0; /取各个行频和列频频率值 s16 num; s16 i=0,n=0; if(brd_init(100) /初始化dsp板 return; /* 发光二极管闪烁两次,表明程序正常运行 */ while(cn

15、t-) brd_led_toggle(brd_led0); delay(1000); brd_led_toggle(brd_led1); delay(1000); brd_led_toggle(brd_led2); delay(1000); /* 打开codec,获取句柄 */ hhandset=codec_open(handset_codec); /* 对d/a转换器进行初始化参数设置 */ codec_dac_mode(hhandset,codec_dac_15bit); /d/a工作在15bit模式 codec_aout_gain(hhandset,codec_aout_minus_6d

16、b); /模拟输出增益为-6db codec_sample_rate(hhandset,sr_8000); /d/a转换速率为8khz /* 计算各键值的行频系数cos(2*pi*f0/fs)和初始条件sin(2*pi*f0/fs) */ for(i=0;i16;i+) f0=dtmf_freqi0; row_freqi0=cos(2*pi*f0/fs); row_freqi1=sin(2*pi*f0/fs); /* 计算各键值的列频系数cos(2*pi*f0/fs)和初始条件sin(2*pi*f0/fs) */ for(i=0;i16;i+) f0=dtmf_freqi1; column_f

17、reqi0=cos(2*pi*f0/fs); column_freqi1=sin(2*pi*f0/fs); /*/* 循环发送dtmf按键缓冲区的键值 */*/ while(1) for(i=0;i16,i+) num=tel_munberi; /取出当前要发送的dtmf按键号码 /* 将dtmf按键号码转化为数组下标 */ switch(num) case0:num=0;break; case1:num=1;break; case2:num=2;break; case3:num=3;break; case4:num=4;break; case5:num=5;break; case6:num=

18、6;break; case7:num=7;break; case8:num=8;break; case9:num=9;break; casea:num=10;break; caseb:num=11;break; casec:num=12;break; cased:num=13;break; case*:num=14;break; case#:num=15;break; ax1=row_freqnum0; /行频系数 xn2=row_freqnum1; /行频初始条件,即x(-2) ay1=column_freqnum0; /列频系数 yn2=column_freqnum1; /列频初始条件,即

19、y(-2) xn1=0; /即x(n-1) yn1=0; /即y(n-1) /* 输出dtmf信号,持续时间为50ms */ n=0; cnt=400; /发送的dtmf样点数,400=50ms/(1/8000)*1000)ms while(cnt-) /* 计算本次输出的样点知z*/ xn=2*ax1*xn1-xn2; /行频样点值 yn=2*ay1*yn1-yn2; /列频样点值 zn=xn+yn; /dtmf样点值 /* 更新x(n-1),x(n-2)的值 */ xn2=xn1; xn1=xn; /* 更新y(n-1),y(n-2)的值 */ yn2=yn1; yn1=yn; data=

20、16384.0*zn; /将样点数据转换为整数数据 /* 等待d/a转换器准备好发送 */ while(!mcbsp_xrdy(handset_codec); *(volatile u16*)dxr1_addr(handset_codec)=data; buffern=data; n+; /* 输出静音信号,持续时间为50ms */ cnt=400; /发送静音信号样点数 while(cnt-) /* 等待d/a转换器准备好发送 */ while(!mcbsp_xrdy(handset_codec); *(volatile u16*)dxr1_addr(handset_codec)=0; vo

21、id delay(s16 period) int i,j; for(i=0;iperiod;i+) for(j=0;j1;j+); 窗口可以看到动态显示时域和频域波形:(二) dtmf信号的检测程序dtmf检测是对进入解码端的信号进行检测,并把双音频信号转换成对应的数字信息。它是一个比dtmf产生更加复杂过程。由于数据流是连续的,为了保证dtmf检测的实时性,因此要求检测过程必须是实时连续的。检测源程序为:/*/* dtmf信号检测程序 */*/#include#include#include#include#include#includehandle hhandset;float buffe

22、r125; /dtmf样点缓冲区float pi=3.1415926;s16 data;int k=0;/*/* w、a对应关系说明 */* vk(n)=2*coef*vk(n-1)-vk(n-2)+x(n) */* */* coef系数对应数组w8 */* x(n)对应数组buffer256 */* vk(n-2)对应数组ai0 */* vk(n-1)对应数组ai1 */* vk(n) 对应数组ai2 */*/float w8,a83;float amp8; /频谱的平方幅度int i,j,x,y;int dtmf_flag=0; /dtmf检测进程,=0检测到静音信号,=1检测到1次dtm

23、f信号int detect_result256=0; /缓存dtmf检测结果int l=0;void delay(int period);void dtmf_detect(void);/*/* 主程序 */*/void main() int cnt=2; /* 初始化各行频列频的系数 */ 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

24、/125); w7=2*cos(2*pi*26/125); /* 初始化vk(n-1)、vk(n-2) */ for(i=0;i8;i+) ai0; ai1; if(brd_init(100) /初始化dsp板 return; /* 发光二极管闪烁两次,表明程序正在正常运行 */ while(cnt-) brd_led_toggle(brd_led0); delay(1000); brd_led_toggle(brd_led1); delay(1000); brd_led_toggle(brd_led2); delay(1000); hhandset=codec_open(handset_co

25、dec); /打开codec,获取句柄 /* 对d/a转换器进行初始化参数设置 */ codec_adc_mode(hhandset,codec_adc_15bit); /adc为15bit模式 codec_ain_gain(hhandset,codec_ain_0db); /adc的模拟输入增益为0db codec_sample_rate(hhandset,sr_8000); /取样频率为8khz while(1) /* 等待a/d转换器输出数据准备好 */ while(!mcbsp_rrdy(handset_codec); data=*(volatile u16*)drr1_addr(ha

26、ndset_codec); bufferk=data/16384.0; /增益控制,防止后续运算溢出 /* 计算vk(n)-ai2,i=0-7 */ for(i=0;i8;i+) /* 计算vk(n),vk(n-1),vk(n-2) */ ai2=wi*ai1-ai0+bufferk; ai0=ai1; ai1=ai2; k+; if(k=125) /读取125个样点,约占15ms k=0; dtmf_detect(); /调用dtmf检测判决程序 /* 初始化vk(n-1),vk(n-2) */ for(i=0;i8;i+) ai0=0; ai1=0; /*/* goertzel算法程序 *

27、/*/void dtmf_detect(void) /* 计算|x(n)|频谱的平方幅度ampi,i=0-7 */ for(i=0;i8;i+) /* 计算|x(n)|频谱的平方幅度 */ ampi=ai1*ai1+ai0*ai0-wi*ai1*ai0; /printf(the amplitude %d is %f.rn,i,ampi); /用于程序调试 j=0; /* 搜索幅度大于门限的行频和列频,搜索结果存放在变量x y中 */ for(i=0;i1500) j+; if(j=1) x=i; else if(j=2) y=i; /*/* 如果在静音信号之后检测到两个幅度达到门限的频率, *

28、/* 则惊醒按键数字判决,判决结果存储在变量i中 */*/ i=-1; if(dtmf_flag=0) if(j=2) if(x=0&y=4) i=1; else if(x=0&y=5) i=2; else if(x=0&y=6) i=3; else if(x=1&y=4) i=4; else if(x=1&y=5) i=5; else if(x=1&y=6) i=6; else if(x=2&y=4) i=7; else if(x=2&y=5) i=8; else if(x=2&y=6) i=9; else if(x=3&y=5) i=0; else if(x=3&y=4) i=*; els

29、e if(x=3&y=6) i=#; else if(x=0&y=7) i=a; else if(x=1&y=7) i=b; else if(x=2&y=7) i=c; else if(x=3&y=7) i=d; if(i!=-1) detect_resultl=i; l+; if(l=256) for(l=0;l256;l+) /* 显示判决结果 */ printf(the dtmf signal is %c.rn,detect_resulti); dtmf_flag+; /已经检测到一次dtmf信号 else if(j=0) dtmf_flag=0; /检测到静音信号void delay(

30、int period) int i,j; for(i=0;iperiod,i+) for(j=0;j1;j+); (三)调试结果下图为输入和输出时的时域、频域波形对比。发送端:时域:频域:检测端:时域:频域:实现功能:1.基于ccs5000simulator环境下的dtmf产生及检测; 2.输入用信号源合成的dtmf信号,能够正确检测; 3.双机情况下连续产生特定的dtmf信号,接收端连续检测出相应的dtmf信号。五、设计(安装)与调试的体会dtmf信号的产生及检测在书上是有讲解和设计思路提示的,因此我们在编写程序的时候就没有遇到过多的麻烦,不过在字母拼写,小标点上我们吃了不少苦头,先是怀疑自

31、己的程序有问题,之后又检查整个程序,都不见成效,最后只改变了一个小的符号,就是程序能够运行了,可见,我们在学习中还需要更加细心与认真,才能不浪费时间,提高工作效率。在进行实验调试的过程中,我们老是得不到期望的结果,我们绞尽脑汁,检查程序是否错误,检查cmd文件,可就是找不到哪里错了,后来我就想是不是这板子有问题,于是我就向别的同学借来一块板子,一运行,终于得到了我们想要的结果。看来硬件的不足也会影响实验结果。经过这次的实验,我发现我们要学的其实还有很多,我们都以为自己掌握了的知识,在运用中才发现自己的不足,所以在以后的学习中,我们在理论学习时,本以为已经很清晰地掌握了原理,但在编程时才发现掌握得并不深入,很多地方又是重新学习了一遍,可见我们平时的学习还不够认真、深入,通过这次实验我们认识到了自身的不足,在今

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论