张泽霖_08211049_通信0808_DTMF信号产生及检测_第1页
张泽霖_08211049_通信0808_DTMF信号产生及检测_第2页
张泽霖_08211049_通信0808_DTMF信号产生及检测_第3页
张泽霖_08211049_通信0808_DTMF信号产生及检测_第4页
张泽霖_08211049_通信0808_DTMF信号产生及检测_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

1、DSP课程设计实 验 报 告DTMF信号的产生及检测学院:电子信息工程学院设计人员:张泽霖 学号:08211049目 录一、设计任务书.2二、设计内容.3三、设计方案、算法原理说明3四、程序设计、调试与结果分析7 五、设计(安装)与调试的体会.15 六、参考文献.24一、 设计任务书简介双音多频DTMF(Dual Tone Multi Frequency)是在按键式电话机上得到广泛应用的音频拨号信令,一个DTMF信号由两个频率的音频信号叠加构成。这两个音频信号的频率分别来自两组预定义的频率组:行频组和列频组。每组分别包括4个频率,分别抽出一个频率进行组合就可以组成16种DTMF编码,分别记作0

2、9、*、#、A、B、C、D。如下图1所示。图1DTMF信令的编码要用DSP产生DTMF信号,只要产生两个正弦波叠加在一起即可;DTMF检测时采用改进的Goertzel算法,从频域搜索两个正弦波的存在。设计要求及目标基本部分:(1)使用C语言编写DTMF信号的产生程序,要求循环产生09、*、#、A、B、C、D对应的DTMF信号,并且符合CCITT对DTMF信号规定的指标。(2)使用C语言编写DTMF信号的检测程序,通过Goertzel算法在输入信号中提取频谱信息,通过对检测结果作有效性检查来识别各DTMF信号所对应的数字按键信息并在屏幕上显示。发挥部分:利用DTMF信号完成数据通讯的功能,并试改

3、进DTMF信号的规定指标,使每秒内传送的DTMF编码越多越好。要求完成的任务:(1)编写C语言程序,并在CCS集成开发环境下调试通过。(2)实现设计所要求的各项功能。 (3)按要求撰写设计报告。要求达到的目的: (1)熟悉CCS的编程环境和基本试验调试流程和方法; (2)熟悉并掌握使用C语言编写较为复杂的程序并用CCS实现; (3)了解并掌握DTMF信号的产生和检测远离核试验流程; (4)熟练使用软件CCS5000对程序的完整调试过程。 二、设计内容(1)使用C语言编写DTMF信号的产生程序,要求循环产生09、*、#、A、B、C、D对应的DTMF信号,并且符合CCITT对DTMF信号规定的指标

4、。(2)使用C语言编写DTMF信号的检测程序,再由接收端接收到发送端所发送的相应信号,通过Goertzel算法在输入信号中提取频谱信息,通过对检测结果作有效性检查来识别各DTMF信号所对应的数字按键信息,实现双机通信。三、设计方案、算法原理说明 DTMF信号的产生DTMF编码器基于两个二阶数字正弦波振荡器,一个用于产生行频,一个用于产生列频。向DSP装入相应的系数和初始条件,就可以只用两个振荡器产生所需的八个音频信号。典型的DTMF信号频率范围是7001700Hz,选取8000Hz作为采样频率,即可满足Nyquist条件(Nyquist定理:为了正确判定信号频率,信号在一个周期内至少被采样两次

5、。)正弦波是任何波形构成的基本单元,产生正弦波的方法一般有:采样回放法、查表法、泰勒级数展开法、数字正弦振荡器法。我们用的是sin函数产生离散的正弦值,因为这种方法我们比较熟悉而且通过查阅资料这种方法的也能达到误差要求,生成DTMF的公式为:buffert=sin(t*2*pi*f1/fs)+sin(t*2*pi*f2/fs),其中t为采样序数,由0开始递增;f1,f2为生成DTMF信号的两个正弦波的频率;fs为采样频率;buffert为序数t时的得出的采样值。将这些数据转换为Q15格式然后通过codec发送出去。CCITT对DTMF信号规定的指标是,传送/接收率为每秒10个数字,即每个数字1

6、00ms。代表数字的音频信号必须持续至少45ms,但不超过55ms。100ms内其他时间为静音,以便区别连续的两个按键信号。我们使用8000Hz的采样频率(电话信号的典型抽样频率为=8kHZ),即1秒采样8000个点,则100ms采样800个点,我们设置800个点的缓存,其中用400个存产生的DTMF信号值,即音频信号必须持续50ms,另外400个存0值,即静音信号。 DTMF信号的接收DTMF检测是对进入解码端的信号进行检测,并把双音频信号转换成对应的数字信息。它是一个比DTMF产生更加复杂过程。由于数据流是连续的,为了保证DTMF检测的实时性,因此要求检测过程必须是实时连续的。在输入信号中

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

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

9、FT,需要很多复系数,即使只计算一点的DFT也需要N个复系数采用数字信号处理中的Goertzel算法,则可明显地提高速度。图3.2 Goertzel算法原理框图利用二阶复共轭极点可以得到只有一个实系数的差分方程:(1)在实际的DTMF检测中,只需DFT的幅度(本算法为平方幅度)信息就足够了,因此在Goertzel滤波器中,当N点(相当于DFT数据块的长度)样值输入滤波器后,滤波器输出伪DFT值vk(n),由vk(n)即可确定频谱的平方幅度。(2)其中k=f*N/fs,当N取值为205时, k的取值经计算如下表所示:信号频率(Hz)取整值k信号频率(Hz)取整值k6971812093177020

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

11、调试与结果分析分别将DTMF信号的产生与接收建立工程,用两个DSK板可以实现双机通信。DTMF信号的发送程序:程序流程包含两个任务,即音频任务和静默任务。在一段时间间隔后两个任务需要进行互换。音频任务的作用是产生双音频采样值,静默任务的作用是产生静默采样值。每个任务被分配一定的持续时间。 发送程序代码:#include /*程序用到的头文件*/#include #include type.h#include board.h#include codec.h#include mcbsp54.hvoid delay(int period);void generate(int num);HANDLE

12、hHandset;s16 send_buffer400; /*定义缓冲区,其中S16为自定义类型名*/float buffer400;float pi=3.1415926;s16 num=0;int count=0;int m;char send_num12;float dtmf_freq162= 941,1336, /0对应的行频和列频 697,1209, /1对应的行频和列频 697,1336, /2对应的行频和列频 697,1477, /3对应的行频和列频 770,1209, /4对应的行频和列频 770,1336, /5对应的行频和列频 770,1477, /6对应的行频和列频 852

13、,1209, /7对应的行频和列频 852,1336, /8对应的行频和列频 852,1477, /9对应的行频和列频 697,1633, /A对应的行频和列频 770,1633, /B对应的行频和列频 852,1633, /C对应的行频和列频 941,1633, /D对应的行频和列频 941,1209, /*对应的行频和列频 941,1477 /#对应的行频和列频 ;void main() int cnt=2;/*控制亮灯次数*/ if(brd_init(100) return; /* LED灯闪两次程序正常运行*/while ( cnt- )brd_led_toggle(BRD_LED0)

14、; delay(1000); /*灯延时*/brd_led_toggle(BRD_LED1); delay(1000);/*灯延时*/brd_led_toggle(BRD_LED2);delay(1000);/*灯延时*/ hHandset = codec_open(HANDSET_CODEC); /*获取设置DAC的句柄*/ codec_dac_mode(hHandset, CODEC_DAC_15BIT); /*设置DAC的工作参数15-bit*/ codec_adc_mode(hHandset, CODEC_ADC_15BIT); /* ADC in 15-bit mode */ cod

15、ec_ain_gain(hHandset, CODEC_AIN_6dB); /*模拟输出增益6dB gain on analog input to ADC */ codec_aout_gain(hHandset, CODEC_AOUT_MINUS_12dB); /*转换速率-12dB gain on analog output from DAC */ codec_sample_rate(hHandset,SR_8000); /* 8KHz sampling rate */ printf(输入12位号码:rn);gets(send_num); /*弹出输入框*/ generate(num); v

16、oid generate(int num)f32 x,y;int k=0;int i=0;int j=0;switch(send_num0) /*对num_10进行数值化转换*/ case 1:num=1;break; case 2:num=2;break; case 3:num=3;break; case 4:num=4;break; case 5:num=5;break; case 6:num=6;break; case 7:num=7;break; case 8:num=8;break; case 9:num=9;break; case A:num=10;break; case B:nu

17、m=11;break; case C:num=12;break; case 0:num=0 ;break; case D:num=13;break; case *:num=14;break; case #:num=15;break; x=dtmf_freqnum0/8000;y=dtmf_freqnum1/8000;for(k=0;k=399;k+) bufferk=(0.65*sin(2*pi*y*k)+0.8*sin(2*pi*x*k)*16384; /*将样点数据转换为整数数据*/ send_bufferk=bufferk; /*强制类型转换*/ /发送 while(1)/ Wait f

18、or sample from handset while (!MCBSP_XRDY(HANDSET_CODEC) ; *(volatile u16*)DXR1_ADDR(HANDSET_CODEC)=bufferi; i+; if(i=400) /*一次发送400个点*/ i=0; count+; if(count=30) /*控制发送30次*/ count=0; j+; if(j=12) return; switch(send_numj) case 1:num=1;break; case 2:num=2;break; case 3:num=3;break; case 4:num=4;brea

19、k; case 5:num=5;break; case 6:num=6;break; case 7:num=7;break; case 8:num=8;break; case 9:num=9;break; case A:num=10;break; case B:num=11;break; case C:num=12;break; case 0:num=0;break; case D:num=13;break; case *:num=14;break; case #:num=15;break; x=dtmf_freqnum0/8000; y=dtmf_freqnum1/8000; for(k=0

20、;k=399;k+) bufferk=(0.65*sin(2*pi*y*k)+0.8*sin(2*pi*x*k)*16384;/*将样点数据转换为整数数据*/ send_bufferk=bufferk; void delay(int period) int i, j; for(i=0; iperiod; i+) for(j=0; j1; j+); DTMF信号的接收程序:#include #include #include type.h#include board.h#include codec.h#include mcbsp54.hHANDLE hHandset; float in_buff

21、er256; float pi=3.1415926; s16 data; int k=0;void delay(int period);void detect();void main() int cnt=2; /*控制亮灯次数*/if(brd_init(100) return;/ blink the leds a couple timeswhile ( cnt- )brd_led_toggle(BRD_LED0);/brd_delay_msec(1000); delay(1000);brd_led_toggle(BRD_LED1);/brd_delay_msec(1000); delay(10

22、00);brd_led_toggle(BRD_LED2);/brd_delay_msec(1000);delay(1000);/* Open Handset Codec */ hHandset = codec_open(HANDSET_CODEC); /* Acquire handle to codec */* Set codec parameters */ codec_dac_mode(hHandset, CODEC_DAC_15BIT); /* DAC in 15-bit mode */ codec_adc_mode(hHandset, CODEC_ADC_15BIT); /* ADC i

23、n 15-bit mode */ codec_ain_gain(hHandset, CODEC_AIN_6dB); /* 6dB gain on analog input to ADC */ codec_aout_gain(hHandset, CODEC_AOUT_MINUS_6dB); /* -6dB gain on analog output from DAC */ codec_sample_rate(hHandset,SR_8000); /* 8KHz sampling rate */ while(1) while (!MCBSP_RRDY(HANDSET_CODEC) ; data =

24、 *(volatile u16*)DRR1_ADDR(HANDSET_CODEC);in_bufferk+=data/16384.0;if(k=256) k=0; detect(); void detect() int i,j,x,y; int m=0; float w8; float a83; float amp8; w0=2*cos(2*pi*18/205);w1=2*cos(2*pi*20/205);w2=2*cos(2*pi*22/205);w3=2*cos(2*pi*24/205);w4=2*cos(2*pi*31/205);w5=2*cos(2*pi*34/205);w6=2*co

25、s(2*pi*38/205);w7=2*cos(2*pi*42/205); for(i=0;i8;i+)ai0=0;ai1=0;for(j=1;j=205;j+)ai2=wi*ai1-ai0+in_bufferj-1;ai0=ai1;ai1=ai2; /*计算频谱的幅度平方值*/ampi=ai1*ai1+ai0*ai0-wi*ai1*ai0; for(i=0;i3000) /*门限设为3000*/ m+;if(m=1) /*第一个达到门限要求的的频率点为行频给x*/x=i; else if(m=2)y=i; /*第二个达到门限要求的的频率点为列频给y*/if(m=2) if(x=0 & y=4

26、) printf(The DTMF signal is 1n);else if(x=0 & y=5) printf(The DTMF signal is 2n);else if(x=0 & y=6) printf(The DTMF signal is 3n);else if(x=1 & y=4) printf(The DTMF signal is 4n);else if(x=1 & y=5) printf(The DTMF signal is 5n);else if(x=1 & y=6) printf(The DTMF signal is 6n);else if(x=2 & y=4) prin

27、tf(The DTMF signal is 7n);else if(x=2 & y=5) printf(The DTMF signal is 8n); else if(x=2 & y=6) printf(The DTMF signal is 9n);else if(x=3 & y=5) printf(The DTMF signal is 0n); else if(x=0 & y=7) printf(The DTMF signal is An);else if(x=1 & y=7) printf(The DTMF signal is Bn); else if(x=2 & y=7) printf(

28、The DTMF signal is Cn); else if(x=3 & y=7) printf(The DTMF signal is Dn); else if(x=3 & y=4) printf(The DTMF signal is *n); else if(x=3 & y=6) printf(The DTMF signal is #n); void delay(int period) int i, j; for(i=0; iperiod; i+) for(j=0; j1; j+); CMD程序(接口文件)-stack 400MEMORY PAGE 0:VECS: origin=0080h

29、,length=0080h /*中断向量表*/ PRAM: origin=0100h,length=3700h /*内部程序RAM*/ PAGE 1:SCRATCH: origin=0060h,length=0020h /*便笺式数据RAM*/ EXRAM: origin=3200h,length=4000h /*外部数据RAM*/SECTIONS .cinit PRAM PAGE 0 .text PRAM PAGE 0 .vectors VECS PAGE 0 init_var PRAM PAGE 0 detect PRAM PAGE 0 vrcprg PRAM PAGE 0 matprg

30、PRAM PAGE 0 .stack EXRAM PAGE 1 .trap SCRATCH PAGE 1 .const EXRAM PAGE 1 .data EXRAM PAGE 1 .bss EXRAM PAGE 1 .cio EXRAM PAGE 1 .switch EXRAM PAGE 1五、设计(安装)与调试的体会软件调试安装完驱动后打开setup CCS设置参数:创建工程创建一个新工程.pjt,并保存在英文路径下:ProjectNew 添加库文件:将编好的链接命令文件DTMF.cmd 添加到工程编译与运行程序将编好的.c源程序添加到工程:添加头文件路径:选择编辑、汇编、连接工程里的所有文件。选择File-Load Program。双击DSP5.out,将程序装载到目标DSP上,点Run运行程序。可以看见目标DSP板上LED灯的闪烁。实验图像调试发送过程调试:运行程序

温馨提示

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

评论

0/150

提交评论