课程报告DTMF编码器的DSP实现.docx

上传人:b****6 文档编号:5725669 上传时间:2022-12-31 格式:DOCX 页数:21 大小:464.34KB
下载 相关 举报
课程报告DTMF编码器的DSP实现.docx_第1页
第1页 / 共21页
课程报告DTMF编码器的DSP实现.docx_第2页
第2页 / 共21页
课程报告DTMF编码器的DSP实现.docx_第3页
第3页 / 共21页
课程报告DTMF编码器的DSP实现.docx_第4页
第4页 / 共21页
课程报告DTMF编码器的DSP实现.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

课程报告DTMF编码器的DSP实现.docx

《课程报告DTMF编码器的DSP实现.docx》由会员分享,可在线阅读,更多相关《课程报告DTMF编码器的DSP实现.docx(21页珍藏版)》请在冰豆网上搜索。

课程报告DTMF编码器的DSP实现.docx

课程报告DTMF编码器的DSP实现

成都信息工程学院电子工程学院

 

DSP器件及应用

课程设计

题目:

DTMF信号的产生与识别告

专业:

电子信息工程

班级:

组员:

指导教师:

2013年05月15日

一、概述

随着DSP芯片及相关技术的发展,DSP得到了人们的日益关注和越来越广泛的应用。

德州仪器(TI)公司推出的TMS320VC54x系列具有高性能、低功耗等优良性能,受到用户的欢迎,已广泛地应用于有线和无线通讯、仪器仪表、雷达、图像处理、工业控制、语音处理等领域。

双音多频DTMF(DualToneMulti-Frequency)信令,逐渐在全世界范围内使用在按键式电话机上,因其提供更高的拨号速率,迅速取代了传统转盘式电话机使用的拨号脉冲信令。

近年来DTMF也应用在交互式控制中,诸如语言菜单、语言邮件、电话银行和ATM终端等。

将DTMF信令的产生与检测集成到任一含有数字信号处理器(DSP)的系统中是一项较有价值的工程应用。

DTMF(双音多频)技术是DSP技术中的一种。

DTMF信号是音频电话的拨号信号。

有美国ATT贝尔实验室开发。

这种拨号方法取代了脉冲拨号,每一个号码由两个音频信号组成,该双音频由按键所在的行和列对应的频率决定。

电话中的双音多频信号有两种作用:

一是用于双音多频信号的拨号,去控制交换机接同被叫的用户电话机;二是利用双音多频信号控制电话机各种动作。

这些功能的实现离不来DTMF信号的正确的产生和识别,专用数字处理信号芯片(DSP)的出现,使这个问题得到轻松的解决,这里给出的是基于TMS3205402产生和识别DTMF信号的方法。

DTMF信号的产生及识别都要以相关算法为基础。

在此我们提出采用Goertzel算法来实现DTMF信号的产生及检测,并详细推导了利用该算法实现滤波器组的方法及用仿真软件进行模拟设计的过程。

二、算法原理以及软件仿真

DTMF

DTMF(DoubleToneMultifrequency)技术主要用于在电话频段内传送简单的操作信号。

在DTMF通信系统中共有8个频率,分为4个高频音和4个低频音。

用1个高频音和1个低频音的组合来表示一个信号。

这样,共能提供16种组合,分别代表16种信号。

1.DTMF信号的产生

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

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

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

DTMF双音频信号由两个二阶数字正弦振荡器产生,一个用来产生行音频信号,另个一产生列音频信号。

其系统函数为:

其中,bAsinω0,a1=-2cosω0,a2=1,ω0=2πf0/fa,f0为正弦波频率,fa为抽样频率,ω0为归一化数字频率。

对应的差分方程为:

即给定脉冲输入时,二阶系统输出一个纯净的正弦波。

DTMF信号产生流程

CCITT规定每秒最多按10个键,即每个键时隙最短为100MS,其中音频实际持续时间至少为45MS,不大于55MS,时隙的其他时间内保持静默,因此按键产生双音频信号时,相继的两个信号间隔一段时间;解码器利用这个时间识别出双音频信号,并转换成对应的数字信息,而且要识别出间隙信息。

因此流程包含音频任务和静默任务,前者是产生双音频采样值,后者产生静默采样值,每个任务结束时,要重置定时器和下一个任务。

其中静默任务还要加上一个任务:

从数字缓冲区取出数字并解包。

解包就是将数字映射为对应的行列音频特性,装载指针指向振荡器特征表对应的正确位置。

两个任务轮流执行。

由CCITT(国际电报电话咨询委员会)的规定,数字之间必须有适当长度的静音,因此编码器有两个任务,其一是音频信号任务,产生双音样本,其二是静音任务,产生静音样本。

每个任务结束后,启动下一个任务前(音频信号任务或静音任务),都必须复位决定其持续时间的定时器变量。

在静音任务结束后,DSP从数字缓存中调出下一个数字,判决该数字。

信号所对应的行频和列频信号,并根据不同频率确定其初始化参数a=-2cosω与y(-2)=-Asinω。

我们这里A取213。

 

2.DTMF信号的识别

DTMF信号包含两组音频信号,解码器的任务是通过数学变换把它从时域转化到频域,然后得出对应的数字信息。

由于芯片处理的是数字信号,所以必须把输入信号数字化,再用DSP芯片处理。

频率检测时,检测出DTMF信号的基波及

由于在DTMF检测中,输入的信号是实数序列,并不需要检测出8个行频/列频的相位,只需要计算出其幅度平方即可。

对于实序列x(n),Goertzel算法所需的内部变量v(n)k化参数a=-2cosω与y(-2)=-Asinω。

也为实数。

因此计算如下:

采用算法检测DTMF信号,DSP使用十六个滤波器快速运算,与此同时在运算之前加上增益控制,使得Goertzel算法不用检查溢出,提供了效率。

其缺点是增加了存储需求,因为它不是一个一个的输入采样,而是达到一定的数量的采样后才进行处理。

 

三、硬件需求

算法所基于的硬件平台的特点,其运算能力能否满足算法的精度及时间要求及相应的分析。

软件部分完成了对DTMF信号的产生和识别。

采用CODEC的ADC和DAC实现数据的发送和接收。

将DSP产生的数字信号通过ADC发送,将产生的DTMF信号通过DAC送入DSP,进行检测。

TI公司的TMS320C5402系列的DSP芯片非常适合于快速运算,DTMF的产生和检测计算复杂程度不高,采用Goertzel算法使软件检测速度快、精度高,并可以灵活的修改参数。

能满足算法的精度及时间的要求。

 

四、程序说明

1.DTMF信号的产生

首先进行任务判决,判断任务标志是否为零,如果是零则进行静音任务。

程序设计如下:

for(j=0;j<12;j++)

{

n=m[j];

while(task==0)

{

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

{

buf1[i]=0;

buf2[i]=0;

data[i]=0;

}

i=0;

当持续时间没有完毕时,时间变量减1,然后产生静音样本再返回。

while(timer!

=0)

{

while

(1)

{

if(i>127)

break;

/*将data[i]输出到D/A*/

while(!

MCBSP_XRDY(HANDSET_CODEC)){};

/*writesampletohandsetcodec*/

*(volatileu16*)DXR1_ADDR(HANDSET_CODEC)=

data[i++];

}

timer=timer-1;}

当持续时间完毕时,持续时间变量复位,然后切换任务标志为1,装入下一个数字,初始化新数字的振荡器系数与初始化条件,最后返回。

while(timer==0)

{task=1;

a=find1(n);

b=find2(n);

y1=find3(n);

y2=find4(n);

timer=45;}

}

当进行任务判决时,如果任务标志不是零则进行双音任务。

设计程序如下:

while(task==1)

{buf1[0]=y1;

buf2[0]=y2;

buf1[1]=(a*y1)*2;

buf2[1]=(b*y2)*2;

data[0]=buf1[0]/2+buf2[0]/2;

data[1]=buf1[1]/2+buf2[1]/2;

for(i=2;i<128;i++)

{buf1[i]=(a*buf1[i-1])*2-buf1[i-2];

buf2[i]=(b*buf2[i-1])*2-buf2[i-2];

data[i]=buf1[i]/2+buf2[i]/2;

}

i=0;

当持续时间没有完毕时,时间变量减1,然后产生双音样本再返回

 

while(timer!

=0)

{while

(1)

{if(i>127)

break;

/*将dacdata[i]输出到D/A*/

while(!

MCBSP_XRDY(HANDSET_CODEC)){};

/*writesampletohandsetcodec*/

*(volatileu16*)DXR1_ADDR(HANDSET_CODEC)=

data[i++];

}

timer=timer-1;

}

当持续时间完毕时,持续时间变量复位,然后切换任务标志为0,然后返回。

while(timer==0)

{task=0;

timer=45;

}}

2.DTMF信号的识别

采样:

i=0;

while

(1)

{if(i>127)

break;/*采到128个样点后跳出采样*/

/*Waitforsamplefromhandset*/

while(!

MCBSP_RRDY(HANDSET_CODEC)){};

/*Readsamplefromandwritebacktohandsetcodec*/

data[i++]=*(volatileu16*)DRR1_ADDR(HANDSET_CODEC);/*采样

128个样点*/

}

对八个频谱分别计算

程序设计:

for(j=0;j<14;j++)

{y[1]=data[1]/1024+2*d[j]*y[0];

for(i=2;i<128;i++)

{

y[i]=data[i]/1024+2*d[j]*y[i-1]-y[i-2];

}

通过上述程序求出y[127]、y[126]。

利用公式算出幅度的平方

程序设计:

a[j]=(y[127]/2)*(y[127]/4)+(y[126]/2)*(y[126]/4)-2*d[j]*(y[127]/2)*(y[126]/4);

中间变量清零程序设计:

for(j=0;j<128;j++)

y[j]=0;/*清零*/

峰值检测程序设计:

for(m=0;m<3;m++)

{

for(n=0;n<4;n++)

{k1=2*n;

k2=k1+1;

k3=(m+4)*2;

k4=k3+1;

z[0]=a[k1]>3500;

z[1]=a[k2]<200;

z[2]=a[k3]>3500;

z[3]=a[k4]<200;/*峰值检测*/

if(z[0]==1&&z[1]==1&&z[2]==1&&z[3]==1)

{n1=c[n][m];

}

}/*如果满足上述条件则生成数字*/

五、程序调试及结果

程序运行的调试过程、结果以及结论。

1.DTMF信号的产生

启动ccs,载入工程tk.c,编译,并将.out载入试验板,下图为程序载入完毕时的情景,观察ccs。

通过gomain,并且运行后通过view—Graph—time/frequence,打开窗口把某些栏里的值改成如图所示:

点击OK,出现产生的两列频率不同的正弦波叠加出的波形。

以上调试基本上满足DTMF信号的产生要求,实验的第一部分比较成功。

2.DTMF信号的识别

重新载入工程tk2.c,移走tk.c,编译,并将.out载入试验板,下图为程序载入完毕时的情景,观察ccs。

通过gomain后,使之运行,再点击file—data—loaddata,出现下面的对话框。

1

2

任意的打开一个数据,这里我们打开的是dtmf8.dat。

出现对话框:

把蓝色部分改成DATA,点击OK。

检测出数据n=8。

由上述已检测出DTMF信号,实验的第二部分在CCS上检测成功!

六、程序清单

工程中的各个源文件的清单。

实验中我们将DTMF信号的产生与检测和成为一个C程序。

如下:

#include

#include

#include

#include

#include

voiddelay(s16period);

chartest(void);

floatfind1(charn);

floatfind2(charn);

intfind3(charn);

intfind4(charn);

HANDLEhHandset;

float

d0[7]={0.8538689,0.8226405,0.7843439,0.7391022,0.582052,0.498185,0.3993091};

intd1[7]={4264,4658,5082,5518,6661,7103,7510};

charc[4][3]={'1','2','3','4','5','6','7','8','9','*','0','#'};

inta[14];

s16data1[128];

s16data[128];

voidmain()

{floata,b;

intbuf1[128],buf2[128];

inti,j,task,timer,y1,y2,cnt;

charn1,n;

charm[12]={'1','2','3','4','5','6','7','8','9','*','0','#'};

cnt=2;

timer=45;

task=0;

if(brd_init(100))/*初始化DSK板*/

return;

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

}

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

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);/*-12dBgainonanalogoutputfromDAC*/

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

for(j=0;j<12;j++)

{

n=m[j];/*取数*/

while(task==0)

{for(i=0;i<128;i++)

{buf1[i]=0;

buf2[i]=0;

data[i]=0;}/*产生静音值*/

i=0;

while(timer!

=0)

{while

(1)

{if(i>127)

break;/*将data[i]输出到D/A*/

while(!

MCBSP_XRDY(HANDSET_CODEC)){};

/*writesampletohandsetcodec*/

*(volatileu16*)DXR1_ADDR(HANDSET_CODEC)=data[i++];

}

timer=timer-1;

}

while(timer==0)

{task=1;

a=find1(n);/*寻找产生DTMF的初始条件*/

b=find2(n);/*寻找产生DTMF的初始条件*/

y1=find3(n);/*寻找产生DTMF的初始条件*/

y2=find4(n);/*寻找产生DTMF的初始条件*/

timer=45;/*恢复初值*/

}

}

while(task==1)

{

buf1[0]=y1;

buf2[0]=y2;

buf1[1]=(a*y1)*2;

buf2[1]=(b*y2)*2;

data[0]=buf1[0]/2+buf2[0]/2;

data[1]=buf1[1]/2+buf2[1]/2;

for(i=2;i<128;i++)

{buf1[i]=(a*buf1[i-1])*2-buf1[i-2];

buf2[i]=(b*buf2[i-1])*2-buf2[i-2];

data[i]=buf1[i]/2+buf2[i]/2;/*产生DTMF*/}

i=0;

while(timer!

=0)

{for(i=0;i<128;i++)

{/*将dacdata[i]输出到D/A*/

while(!

MCBSP_XRDY(HANDSET_CODEC)){};/*writesampletohandsetcodec*/

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

if(timer<5)

{

while(!

MCBSP_RRDY(HANDSET_CODEC)){};

/*Readsamplefromandwritebacktohandsetcodec*/

data1[i]=*(volatileu16*)DRR1_ADDR(HANDSET_CODEC);

}

}

timer=timer-1;

}

n1=test();/*检测DTMF*/

printf("n=%c\n",n1);

while(timer==0)/*恢复初值*/

{task=0;

timer=45;

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

data1[i]=0;/*对采样值清零*/

}

}

}

}

floatfind1(charn)

{floata;

if(n=='1'||n=='2'||n=='3')

{a=d0[0];}

elseif(n=='4'||n=='5'||n=='6')

{a=d0[1];}

elseif(n=='7'||n=='8'||n=='9')

{a=d0[2];}

elseif(n=='0'||n=='#'||n=='*')

{a=d0[3];}

else

{printf("error\n");}

return(a);

}

intfind3(charn)

{inty1;

if(n=='1'||n=='2'||n=='3')

{y1=d1[0];}

elseif(n=='4'||n=='5'||n=='6')

{y1=d1[1];}

elseif(n=='7'||n=='8'||n=='9')

{y1=d1[2];}

elseif(n=='0'||n=='#'||n=='*')

{y1=d1[3];}

else

{printf("error\n");}

return(y1);

}

floatfind2(charn)

{floatb;

if(n=='1'||n=='4'||n=='7'||n=='*')

{b=d0[4];}

elseif(n=='2'||n=='5'||n=='8'||n=='0')

{b=d0[5];}

elseif(n=='3'||n=='6'||n=='9'||n=='#')

{b=d0[6];}

else

{printf("error\n");}

return(b);

}

intfind4(charn)

{inty2;

if(n=='1'||n=='4'||n=='7'||n=='*')

{y2=d1[4];}

elseif(n=='2'||n=='5'||n=='8'||n=='0')

{y2=d1[5];}

elseif(n=='3'||n=='6'||n=='9'||n=='#')

{y2=d1[6];}

else

{printf("error\n");}

return(y2);

}

voiddelay(s16period)

{inti,j;

for(i=0;i

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

}

chartest(void)

{inti,j,m,n,k1,k2,k3,k4,z[4];

charn1;

float

d[14]={0.8538689,0.458184,0.8226405,0.3534748,0.78434349,0.23038942,0.739102

2,0.09254437,0.582052,-0.32243,0.498185,-0.5036232,0.3993091,-0.68110433};

inty[128]={0};

y[0]=data[0]/1024;

for(j=0;j<14;j++)

{y[1]=data[1]/1024+2*d[j]*y[0];

for(i=2;i<128;i++)

{y[i]=data[i]/1024+2*d[j]*y[i-1]-y[i-2];}

a[j]=(y[127]/2)*(y[127]/4)+(y[126]/2)*(y[126]/4)-2*d[j]*(y[127]/2)*(y[126]/4);

/*运行

Goertze算法*/

}

for(m=0;m<3;m++)

{for(n=0;n<4;n++)

{k1=2*n;

k2=k1+1;

k3=(m+4)*2;

k4=k3+1;

z[0]=a[k1]>3500;/*峰值检测*/

z[1]=a[k2]<200;

z[2]=a[k3]>3500;

z[3]=a[k4]<200;

if(z[0]==1&&z[1]==1&&z[2]==1&&z[3]==1)/*判断是否有DTMF信号*/

{n1=c[n][m];}

}

}

return(n1);

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

当前位置:首页 > 外语学习 > 英语学习

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

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