DSPDTMF信号的产生于检测.doc

上传人:仙人指路1688 文档编号:4140867 上传时间:2023-04-07 格式:DOC 页数:22 大小:710KB
返回 下载 相关 举报
DSPDTMF信号的产生于检测.doc_第1页
第1页 / 共22页
DSPDTMF信号的产生于检测.doc_第2页
第2页 / 共22页
DSPDTMF信号的产生于检测.doc_第3页
第3页 / 共22页
DSPDTMF信号的产生于检测.doc_第4页
第4页 / 共22页
DSPDTMF信号的产生于检测.doc_第5页
第5页 / 共22页
点击查看更多>>
资源描述

《DSPDTMF信号的产生于检测.doc》由会员分享,可在线阅读,更多相关《DSPDTMF信号的产生于检测.doc(22页珍藏版)》请在三一办公上搜索。

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(int period) int i,j; for(i=0;iperiod,i+) for(j=0;j1;j+); (三)调试结果下图为输入和输出时的时域、频域波形对比。发送端:时域:频域:检测端:时域:频域:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 办公文档 > 其他范文


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号