DTMF信号地产生及检测.docx

上传人:b****6 文档编号:8016169 上传时间:2023-01-28 格式:DOCX 页数:21 大小:148.34KB
下载 相关 举报
DTMF信号地产生及检测.docx_第1页
第1页 / 共21页
DTMF信号地产生及检测.docx_第2页
第2页 / 共21页
DTMF信号地产生及检测.docx_第3页
第3页 / 共21页
DTMF信号地产生及检测.docx_第4页
第4页 / 共21页
DTMF信号地产生及检测.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

DTMF信号地产生及检测.docx

《DTMF信号地产生及检测.docx》由会员分享,可在线阅读,更多相关《DTMF信号地产生及检测.docx(21页珍藏版)》请在冰豆网上搜索。

DTMF信号地产生及检测.docx

DTMF信号地产生及检测

 

DSP课程设计

实验报告

 

DTMF信号的产生及检测

 

院(系):

电子信息工程学院-通信工程

设计人员:

周钰哲学号:

08211052

苗祚雨08212075

 

一、设计任务书……………………………………………………………2

二、设计内容………………………………………………………………2

三、设计方案、算法原理说明……………………………………………3

四、程序设计、调试与结果分析…………………………………………6

五、设计(安装)与调试的体会…………………………………………16

六、参考文献………………………………………………………………16

 

一设计任务要求

双音多频DTMF(DualToneMultiFrequency)是在按键式电话机上得到广泛应用的音频拨号信令,一个DTMF信号由两个频率的音频信号叠加构成。

这两个音频信号的频率分别来自两组预定义的频率组:

行频组和列频组。

每组分别包括4个频率,分别抽出一个频率进行组合就可以组成16种DTMF编码,分别记作0~9、*、#、A、B、C、D。

如下图1所示。

图1DTMF信令的编码

要用DSP产生DTMF信号,只要产生两个正弦波叠加在一起即可;DTMF检测时采用改进的Goertzel算法,从频域搜索两个正弦波的存在。

1、基本部分:

(1)使用C语言编写DTMF信号的发生程序,要求循环产生0~9、*、#、A、B、C、D对应的DTMF信号,并且符合CCITT对DTMF信号规定的指标。

(2)使用C语言编写DTMF信号的检测程序,检测到的DTMF编码在屏幕上显示。

2、发挥部分:

利用DTMF信号完成数据通讯的功能,并试改进DTMF信号的规定指标,使每秒内传送的DTMF编码越多越好。

3、要求完成的任务

(1)编写C语言程序,并在CCS集成开发环境下调试通过。

(2)实现设计所要求的各项功能。

(3)按要求撰写设计报告。

二、设计内容

DTMF发生器基于两个二阶数字正弦振荡器,一个用于产生行频,一个用于产生列频。

在输入信号中检测DTMF信号,需要在输入的数据信号流中连续地搜索DTMF信号频谱的存在。

整个检测过程分两步:

首先采用Goertzel算法在输入信号中提取频谱信息;接着作检测结果的有效性检查。

Goertzel算法实质是一个两极点的IIR滤波器。

三、设计方案、算法原理说明

要用DSP产生DTMF信号,只要通过两个正弦波叠加在一起即可;DTMF检测时采用改进的Goertzel算法,从频域搜索两个正弦波的存在。

(1)DTMF信号的产生

DTMF编码器基于两个二阶数字正弦波振荡器,一个用于产生行频,一个用于产生列频。

向DSP装入相应的系数和初始条件,就可以只用两个振荡器产生所需的八个音频信号。

典型的DTMF信号频率范围是700~1700Hz,选取8000Hz作为采样频率,即可满足Nyquist条件。

DTMF数字振荡器对的二阶系统函数的差分方程为:

 

其中

为采样频率,

为输出正弦波的频率,

为输出正弦波的幅度。

该式初值为

用sin函数产生离散的正弦值,生成DTMF的公式为:

buffer[t]=sin(t*2*pi*f1/fs)+sin(t*2*pi*f2/fs)

其中t为采样序数,由0开始递增;f1,f2为生成DTMF信号的两个正弦波的频率;fs为采样频率;buffer[t]为序数t时的得出的采样值。

将这些数据转换为Q15格式然后通过codec发送出去。

CCITT对DTMF信号规定的指标是,传送/接收率为每秒10个数字,即每个数字100ms。

代表数字的音频信号必须持续至少45ms,但不超过55ms。

100ms内其他时间为静音,以便区别连续的两个按键信号。

我们使用8000Hz的采样频率(电话信号的典型抽样频率为

=8kHZ),即1秒采样8000个点,则100ms采样800个点,我们设置800个点的缓存,其中用400个存产生的DTMF信号值,即音频信号必须持续50ms,另外400个存0值,即静音信号。

(2)DTMF信号的检测

DTMF检测是对进入解码端的信号进行检测,并把双音频信号转换成对应的数字信息。

它是一个比DTMF产生更加复杂过程。

由于数据流是连续的,为了保证DTMF检测的实时性,因此要求检测过程必须是实时连续的。

在输入信号中检测DTMF信号,需要在输入的数据信号流中连续地搜索DTMF信号频谱的存在。

整个检测过程分两步:

首先采用Goertzel算法在输入信号中提取频谱信息;接着作检测结果的有效性检查。

DTMF解码时在输入信号中搜索出有效的行频和列频。

计算数字信号的频谱可以采用DFT及其快速算法FFT,而在实现DTMF解码时,采用Goertzel算法要比FFT更快。

通过FFT可以计算得到信号所有谱线,了解信号整个频域信息,而对于DTMF信号只需关心其8个行频/列频及其二次谐波信息即可,二次谐波的信息用于将DTMF信号与声音信号区别开。

此时Goertzel算法能更加快速的在输入信号中提取频谱信息。

Goertzel算法实质是一个两极点的IIR滤波器。

Goertzel算法原理:

DTMF检测器的核心是Goertzel算法。

该算法利用二极点的IIR滤波器计算离散傅立叶变换值,能够快速高效地提取输入信号的频谱信息。

由于IIR滤波器是一个递归结构,它利用只有一个实系数的差分方程进行操作,并不像DFT或FFT算法那样需要计算数据块,而是每输入一个样值就执行一次算法。

完成时域到频域的变换可以用离散傅立叶变换(DFT)或快速傅立叶变(FFT).FFT计算出所有点频率,而DFT可以只计算感兴趣的频率点.如果要计算的频率点数少于log2N(N为输入信号点数),采用DFT的计算速度比FFT更快。

直接计算DFT,需要很多复系数,即使只计算一点的DFT也需要N个复系数.采用数字信号处理中的Goertzel算法,如图2,则可明显地提高速度。

图2Goertzel算法原理框图

在实际的DTMF检测中,只需DFT的幅度(本算法为平方幅度)信息就足够了,因此在Goertzel滤波器中,当N点(相当于DFT数据块的长度)样值输入滤波器后,滤波器输出伪DFT值vk(n),由vk(n)即可确定频谱的平方幅度。

其中k=f*N/fs,当N取值为125时,k的取值经计算如表1所示:

信号频率(Hz)

计算值k

取整值k

绝对误差

相对误差

697

10.890625

11

0.109375

1.00430%

770

12.03125

12

0.03125

0.25974%

852

13.3125

13

0.3125

2.34741%

941

14.703125

15

0.296875

2.01912%

1209

18.890625

19

0.109375

0.57899%

1336

20.875

21

0.125

0.59880%

1477

23.078125

23

0.078125

0.33852%

1633

25.515625

25

0.515625

2.02082%

表1

一旦得到行/列频率的频谱平方幅度信息,就可以通过一系列的判决来确定音频及数字结果的有效性。

首先,检测可能DTMF信号的强度是否足够大。

行频率分量和列频率分量的平方幅度和应高于某一确定门限。

注意与DTMF频率相符的正弦波的能量集中在频域内一段很窄的范围当中,所以门限取值应占动态范围的大部分。

第二,如果DTMF信号存在,由于构成DTMF信号的行频都低于列频,因此从小到大依次判断各个频率点的频谱幅度,得到的第一个达到门限要求的的频率点即为行频,第二个即为列频,综合行频和列频即可得出检测到的按键信息。

检测流程图:

图3检测流程图

四、程序设计、调试与结果分析

(1)发送源程序代码如下:

/*****************************************************************/

/*DTMFsignal发送程序send.c*/

/*****************************************************************/

#include

#include

#include

#include

#include

#include

voiddelay(intperiod);

voidgenerate(intnum);

HANDLEhHandset;

floatbuffer[800];

s16num=0;

intcount=0;

floatfreq[16][2]={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//#

};

floatpi=3.1415926;

voidmain()

{

intcnt=2;

if(brd_init(100))

{

return;

}

/*blinktheledsacoupletimes*/

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(1000);

delay(1000);

}

/*OpenHandsetCodec*/

hHandset=codec_open(HANDSET_CODEC);/*Acquirehandletocodec*/

/*Setcodecparameters*/

codec_dac_mode(hHandset,CODEC_DAC_15BIT);/*DACin15-bitmode*/

codec_adc_mode(hHandset,CODEC_ADC_15BIT);/*ADCin15-bitmode*/

codec_ain_gain(hHandset,CODEC_AIN_6dB);/*6dBgainonanaloginputtoADC*/

codec_aout_gain(hHandset,CODEC_AOUT_MINUS_12dB);/*-12dBgainonanalog*/

/*outputfromDAC*/

codec_sample_rate(hHandset,SR_8000);/*8KHzsamplingrate*/

generate(num);

}

voidgenerate(intnum)

{

f32x,y;

intk=0;

inti;

i=0;

while

(1)

{

//Waitforsamplefromhandset

while(!

MCBSP_XRDY(HANDSET_CODEC)){};

*(volatileu16*)DXR1_ADDR(HANDSET_CODEC)=buffer[i];

i++;

if(i==800)

{

i=0;

num++;

if(num==16)

num=0;

x=freq[num][0]/8000;

y=freq[num][1]/8000;

for(k=0;k<400;k++)

{buffer[k]=(0.65*sin(2*pi*y*k)+0.8*sin(2*pi*x*k))*16384;

buffer[k+400]=0;

}

}

}

}

voiddelay(intperiod)/*延时子程序*/

{

inti,j;

for(i=0;i

{

for(j=0;j>1;j++);

}

}

(2)检测源程序代码如下:

/*****************************************************************/

/*DTMFsignal检测程序receive.c*/

/*****************************************************************/

#include

#include

#include

#include

#include

#include

HANDLEhHandset;

floatbuffer[125];

floatpi=3.1415926;

s16receive[125];

s16dacdata;

intk=0;

intdetect_result[100]={0};

intl=0;

intflag=0;

voiddelay(intperiod);

voiddetect();

voidmain()

{

intcnt=2;

/********************************************

Description:

*vk(n)=2*coef*vk(n-1)-vk(n-2)+x(n)

*

*Coefficientsareinw[8]

*x(n)isinbuffer[256]

*vk(n-2)isa[i][0]

*vk(n-1)isa[i][1]....

*vk(n)isa[i][2]

*********************************************/

if(brd_init(100))

{return;}

//blinktheledsacoupletimes

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(1000);

delay(1000);

}

/*OpenHandsetCodec*/

hHandset=codec_open(HANDSET_CODEC);/*Acquirehandletocodec*/

/*Setcodecparameters*/

codec_dac_mode(hHandset,CODEC_DAC_15BIT);/*DACin15-bitmode*/

codec_adc_mode(hHandset,CODEC_ADC_15BIT);/*ADCin15-bitmode*/

codec_ain_gain(hHandset,CODEC_AIN_6dB);/*6dBgainonanaloginputtoADC*/

codec_aout_gain(hHandset,CODEC_AOUT_MINUS_6dB);

/*-6dBgainonanalogoutputfromDAC*/

codec_sample_rate(hHandset,SR_8000);/*8KHzsamplingrate*/

while

(1)

{

while(!

MCBSP_RRDY(HANDSET_CODEC)){};

dacdata=*(volatileu16*)DRR1_ADDR(HANDSET_CODEC);

receive[k]=dacdata;

buffer[k]=dacdata/16384.0;

k++;

if(k==125)

{

k=0;

detect();

}

}

}

voiddetect()

{inti,j,x,y;

floatw[8],a[8][3],amp[8];

w[0]=2*cos(2*pi*11/125);

w[1]=2*cos(2*pi*12/125);

w[2]=2*cos(2*pi*13/125);

w[3]=2*cos(2*pi*15/125);

w[4]=2*cos(2*pi*19/125);

w[5]=2*cos(2*pi*21/125);

w[6]=2*cos(2*pi*23/125);

w[7]=2*cos(2*pi*26/125);

for(i=0;i<8;i++)

{

a[i][0]=0;

a[i][1]=0;

for(j=1;j<=125;j++)

{

a[i][2]=w[i]*a[i][1]-a[i][0]+buffer[j-1];

a[i][0]=a[i][1];

a[i][1]=a[i][2];

}

//计算频谱的幅度平方值

amp[i]=a[i][1]*a[i][1]+a[i][0]*a[i][0]-w[i]*a[i][1]*a[i][0];}

j=0;

for(i=0;i<8;i++)

{

if(amp[i]>500)//门限设为500

{//printf("Theamplitude%dis%f.\r\n",i,amp[i]);

j++;

if(j==1)

{

x=i;

}

elseif(j==2)

{

y=i;

}

}

}

i=-1;

if(flag==0)

{

if(j==2)

{

if(x==0&&y==4)

{i='1';}

elseif(x==0&&y==5)

{i='2';}

elseif(x==0&&y==6)

{i='3';}

elseif(x==1&&y==4)

{i='4';}

elseif(x==1&&y==5)

{i='5';}

elseif(x==1&&y==6)

{i='6';}

elseif(x==2&&y==4)

{i='7';}

elseif(x==2&&y==5)

{i='8';}

elseif(x==2&&y==6)

{i='9';}

elseif(x==3&&y==5)

{i='0';}

elseif(x==0&&y==7)

{i='A';}

elseif(x==1&&y==7)

{i='B';}

elseif(x==2&&y==7)

{i='C';}

elseif(x==3&&y==7)

{i='D';}

elseif(x==3&&y==4)

{i='*';}

elseif(x==3&&y==6)

{i='#';}

}

if(i!

=-1)

{

detect_result[l]=i;

l++;

if(l==100)

{

for(l=0;l<100;l++)

printf("TheDTMFsignalis%c.\r\n",detect_result[l]);

}

flag++;

}

}

elseif(j==0)

flag=0;

}

voiddelay(intperiod)

{

inti,j;

for(i=0;i

{

for(j=0;j>1;j++);

}

}

(3)cmd源代码如下:

/*#############################################################################

##$Id:

$

##

###############################################################################

##Copyright(c)1999DNAEnterprises,Inc.

###############################################################################

##RevisionHistory

##----------------

##$Log:

$

##

###############################################################################

###############################################################################

##XFERMAKE.CMD

##------------

##C54xLinkerCommandFilefor5402DSKMemoryTransferModule

##

#############################################################################*/

/******************************************************

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

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1