DTMF信号的产生与检测通信0802程志超-崔航_第1页
DTMF信号的产生与检测通信0802程志超-崔航_第2页
DTMF信号的产生与检测通信0802程志超-崔航_第3页
DTMF信号的产生与检测通信0802程志超-崔航_第4页
DTMF信号的产生与检测通信0802程志超-崔航_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

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

文档简介

1、DSP课程设计实 验 报 告DTMF信号的产生及检测学院:电子信息工程学院设计人员:程志超 学号:08211028崔航 08211029目 录一、设计任务书2二、设计内容3三、设计方案、算法原理说明3四、程序设计、调试与结果分析5 五、设计(安装)与调试的体会13 六、参考文献21一、 设计任务书简介双音多频 (DTMF)技术,是用两个特定的单音频组合信号来代表数字信号以实现其功能,已被广泛用于电话的音频拨号,实现电话号码快速可靠的传输。此外,DTMF拨号和解码也广泛应用在通信系统其他方面,如语言邮件、电话银行和ATM终端等。同时,随着数字信号处理芯片 (DSP)硬件结构和性能的不断完善,DS

2、P嵌入式系统已在工业控制、影像视频、宽带、无线通信、图像采集等方面得到了广泛而有效地应用,已成为电子产品更新换代的决定因素。因此,开发基于DSP的DTMF实验系统有其重大的现实意义,而DTMF的编解码方案无需过多的计算量 ,可以很容易在DSP系统中与其他任务并发执行。双音多频DTMF(Dual Tone Multi Frequency)是在按键式电话机上得到广泛应用的音频拨号信令,一个DTMF信号由两个频率的音频信号叠加构成。这两个音频信号的频率分别来自两组预定义的频率组:行频组和列频组。每组分别包括4个频率,分别抽出一个频率进行组合就可以组成16种DTMF编码,分别记作09、*、#、A、B、

3、C、D。如下图1所示。图1DTMF信令的编码要用DSP产生DTMF信号,只要产生两个正弦波叠加在一起即可;DTMF检测时采用改进的Goertzel算法,从频域搜索两个正弦波的存在。l 设计要求及目标Ø 基本部分:(1)使用C语言编写DTMF信号的发生程序,要求循环产生09、*、#、A、B、C、D对应的DTMF信号,并且符合CCITT对DTMF信号规定的指标。(2)使用C语言编写DTMF信号的检测程序,检测到的DTMF编码在屏幕上显示。Ø 发挥部分:利用DTMF信号完成数据通讯的功能,并试改进DTMF信号的规定指标,使每秒内传送的DTMF编码越多越好。 要求完成的任务(1)编

4、写C语言程序,并在CCS集成开发环境下调试通过。(2) 实现设计所要求的各项功能。(3)按要求撰写设计报告。二、设计内容使用C语言编写DTMF信号的发生程序,通过发送端实现0-9、*、#、A、B、C、D对应的DTMF信号的产生,并且符合CCITT对DTMF信号规定的指标,再由接收端接收到发送端所发送的相应信号,实现双机通信。三、设计方案、算法原理说明 DTMF信号的产生DTMF发生器基于两个二阶数字正弦振荡器,一个用于产生行频,一个用于产生列频。DSP只要装载相应的系数和初始条件,就可以只用两个振荡器产生所需的八种音频信号。典型的DTMF信号频率范围是7001700Hz,选取8000Hz作为采

5、样频率,即可满足奈奎斯特定理。在100ms内采样800个点,我们设置800个点的缓存,其中用400个存产生的DTMF信号值,即音频信号必须持续50ms,另外400个存0值,即静音信号。方案一:数字正弦振荡产生DTMF信号DTMF信号的数学表达式可写为:S(t) =Asin()+ Asin() (1)式中,A为低频信号振幅;为低频信号频率,选自低频组(697 Hz,770 Hz,852 Hz,941 Hz)中的任意一个频率;A为高频信号振幅; 为高频信号频率,选自高频组(1209 Hz,1366 Hz,1477 Hz,1633 Hz)中的任意一个频率,对该DTMF时域信号用8 kHz进行采样便可

6、以得到DTMF的数字序列。方案二: DTMF数字振荡器对的二阶系统函数的差分方程为:,其中, , , 为采样频率, 为输出正弦波的频率, 为输出正弦波的幅度。该式初值为 ,。得到振荡器系统的差分方程为: 。DTMF信号的接收在输入信号中检测DTMF信号,需要在输入的数据信号流中连续地搜索DTMF信号频谱的存在。整个检测过程分两步:首先采用Goertzel算法在输入信号中提取频谱信息;接着作检测结果的有效性检查。DTMF解码时在输入信号中搜索出有效的行频和列频。计算数字信号的频谱可以采用DFT及其快速算法FFT,而在实现DTMF解码时,采用Goertzel算法要比FFT更快。通过FFT可以计算得

7、到信号所有谱线,了解信号整个频域信息,而对于DTMF信号只需关心其8个行频/列频及其二次谐波信息即可,二次谐波的信息用于将DTMF信号与声音信号区别开。此时Goertzel算法能更加快速的在输入信号中提取频谱信息。Goertzel算法原理框图Goertzel算法实质是以一个二阶IIR带通滤波器为基础,利用该算法可以有效地计算DTMF信号的DFT值。以往实验已经表明该算法对于提取DTMF输入信号既有效又快速。该滤波器的直接型实现可以表述为以下差分方程 :在实际的DTMF检测中,只需DFT的幅度(本算法为平方幅度)信息就足够了,因此在Goertzel滤波器中,当N点(相当于DFT数据块的长度)样值

8、输入滤波器后,滤波器输出伪DFT值,由即可确定频谱的平方幅度。其中N的选取决定了频率分辨率以及捕捉N 个样值所需要的时间,对基于Goertzel算法的DTMF信号检测的有效性来说至关重要。频率分辨率被用来选择IIR滤波器中所需的DTMF信号的频率,这可以通过计算下式中的k来实现:,这样计算出的DTMF信号频率可能与实际的DTMF信号频率有一定的差别,但可以通过加大N的选取来减小这种频率差异。然而从另外一方面来考虑,虽然加大了N的选取会使频率的差异减小,但这势必会带来捕捉N个样值所需要的时间的增加,而这个时间的增加势必会对检测的效果造成一定的影响。因此,需要在频率分辨率和捕捉N个样值所需要的时间

9、这两个因素之间做出权衡。由DTMF信号频率所具有的特性不难发现要选取定的N值使得计算出的频率和真实的DTMF信号的频率相一致几乎不可能,而实际中也并不需要计算出来的频率值与其真实频率相一致,只需偏差保持在±1.5% 即可认为是DTMF信号的真实频率。在对DTMF信号采样以及确定N,k值之后就可以进行检测。如下表所示: 1st Harmonics(N = 205) fs = 8 ksps2nd Harmonics(N=201) fs = 8 kspskfrequency(k/N)fs/Hzcoefficientcos(2pi k/N)kfrequency(k/N)fs/Hzcoeffi

10、cientcos(2pi k/N)186970.851623513930.45886207700.817933915520.34445228520.781154317110.22470249410.741424718710.101413112090.58157612428-0.329743413360.50442672667-0.500003814770.39505742945-0.676064216330.27972823264-0.83740一旦得到行/列频率的频谱平方幅度信息,就可以通过一系列的判决来确定音频及数字结果的有效性。首先,检测可能DTMF信号的强度是否足够大。行频率分量和列频

11、率分量的平方幅度和应高于某一确定门限THR_SIG。注意与DTMF频率相符的正弦波的能量集中在频域内一段很窄的范围当中,所以门限取值应占动态范围的大部分。第二,如果DTMF信号存在,由于构成DTMF信号的行频都低于列频,因此从小到大依次判断各个频率点的频谱幅度,得到的第一个达到门限要求的的频率点即为行频,第二个即为列频,综合行频和列频即可得出检测到的是哪个数据。四、程序设计、调试与结果分析分别将DTMF信号的产生与接收建立工程,用两个DSK板可以实现双机通信。DTMF信号的发送程序:程序流程包含两个任务,即音频任务和静默任务。在一段时间间隔后两个任务需要进行互换。音频任务的作用是产生双音频采样

12、值,静默任务的作用是产生静默采样值。每个任务被分配一定的持续时间。发送程序代码: #include <stdio.h> /*程序用到的头文件*/#include <math.h>#include "type.h"#include "board.h"#include "codec.h"#include "mcbsp54.h"void delay(int period);void generate(int num);HANDLE hHandset;s16 out_buffer256; /*定义缓

13、冲区,其中S16为自定义类型名*/float buffer256;s16 num=0;int count=0;char num_112;float freq162= 941,1336, /0 697,1209, /1 697,1336, /2 697,1477, /3 770,1209, /4 770,1336, /5 770,1477, /6 852,1209, /7 852,1336, /8 852,1477, /9 697,1633, /A 770,1633, /B 852,1633, /C 941,1633, /D 941,1209, /* 941,1477 /# ;float pi=

14、3.1415926;void main() int cnt=2;/*控制亮灯次数*/ if(brd_init(100) return; /* blink the leds a couple times 通过观察LED指示灯的闪动频率来验证程序运行*/while ( cnt- )brd_led_toggle(BRD_LED0);/brd_delay_msec(1000); delay(1000);brd_led_toggle(BRD_LED1);/brd_delay_msec(1000); delay(1000);brd_led_toggle(BRD_LED2);/brd_delay_msec(

15、1000);delay(1000); / 获取设置DAC的句柄 hHandset = codec_open(HANDSET_CODEC); /* Acquire handle to codec获句柄 */ /设置DAC的工作参数/工作模式,15+1bit或16bit codec_dac_mode(hHandset, CODEC_DAC_15BIT); /* DAC in 15-bit mode */codec_adc_mode(hHandset, CODEC_ADC_15BIT); /* ADC in 15-bit mode */模拟输出增益 codec_ain_gain(hHandset,

16、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 */ gets(num_1); /*弹出输入框*/ generate(num); void generate(int num)f32 x,y;int k=0;int i;int j

17、;switch(num_10) /*先对第一个输入值进行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':

18、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=freqnum0/8000;y=freqnum1/8000;for(k=0;k<=255;k+) bufferk=(0.65*sin

19、(2*pi*y*k)+0.8*sin(2*pi*x*k)*16384;/*定点处理,将数扩大16384=214且规定为Q15格式*/ out_bufferk=bufferk; /强制类型转换 i=0;j=0;/发送 while(1)/ Wait for sample from handset while (!MCBSP_XRDY(HANDSET_CODEC) ; *(volatile u16*)DXR1_ADDR(HANDSET_CODEC)=bufferi; i+; if(i=256) /采足256个值点,完成第一次发送 i=0; count+; if(count=30) /控制发送30次

20、count=0; j+; if(j=12) return; switch(num_1j) 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'

21、;: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=freqnum0/8000; y=freqnum1/8000; for(k=0;k<=255;k+) bufferk=(0.65

22、*sin(2*pi*y*k)+0.8*sin(2*pi*x*k)*16384; out_bufferk=bufferk; void delay(int period) int i, j; for(i=0; i<period; i+) for(j=0; j<period>>1; j+); DTMF信号的接收程序: #include <stdio.h>#include <math.h>#include "type.h"#include "board.h"#include "codec.h"#

23、include "mcbsp54.h"HANDLE hHandset;float buffer256; float pi=3.1415926; s16 test256; s16 dacdata; 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

24、); delay(1000);brd_led_toggle(BRD_LED1);/brd_delay_msec(1000); delay(1000);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); /* DA

25、C in 15-bit mode */ codec_adc_mode(hHandset, CODEC_ADC_15BIT); /* ADC in 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); /* 8K

26、Hz sampling rate */ while(1) while (!MCBSP_RRDY(HANDSET_CODEC) ; dacdata = *(volatile u16*)DRR1_ADDR(HANDSET_CODEC);testk=dacdata;bufferk=dacdata/16384.0; k+;if(k=256) k=0; detect(); /delay(100); void detect() int i,j,x,y; float w8,a83,amp8; w0=2*cos(2*pi*18/205);w1=2*cos(2*pi*20/205);w2=2*cos(2*pi*

27、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*cos(2*pi*38/205);w7=2*cos(2*pi*42/205); for(i=0;i<8;i+)ai0=0;ai1=0;for(j=1;j<=205;j+)ai2=wi*ai1-ai0+bufferj-1;ai0=ai1;ai1=ai2;/计算频谱的幅度平方值ampi=ai1*ai1+ai0*ai0-wi*ai1*ai0;/printf("The amplitude %d is %f.rn",

28、i,ampi);j=0;for(i=0;i<8;i+) if(ampi>3000) /门限设为3000 /printf("The amplitude %d is %f.rn",i,ampi);j+;if(j=1) /第一个达到门限要求的的频率点为行频附给xx=i; else if(j=2)y=i; /第二个达到门限要求的的频率点为列频附给yi=-1;/printf("The available amplitude is %d.rn ",j);if(j=2)if(x=0 && y=4) i=1; else if(x=0 &

29、;& 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=0 &&a

30、mp; 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("The DTMF signal is Cn"); else if(x=3 && y=7) printf("The DTMF signal is Dn"); else if(x=3 && y=4) printf(&

31、quot;The DTMF signal is *n"); else if(x=3 && y=6) printf("The DTMF signal is #n"); if(i!=-1) printf("The DTMF signal is %d.rn ",i); /打印输出所收到的拨号void delay(int period) int i, j; for(i=0; i<period; i+) for(j=0; j<period>>1; j+); CMD程序(接口文件)-stack 400MEMORY P

32、AGE 0:VECS: origin=0080h,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 >PRAM PAGE 0 .stack >EXRAM PAGE 1 .trap >SCRATCH PAGE 1 .const >EXRAM PAGE 1 .data >EXRAM PAGE 1 .bss >EXRAM

温馨提示

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

评论

0/150

提交评论