双音多频拨号系统DTMF的实验报告.docx
《双音多频拨号系统DTMF的实验报告.docx》由会员分享,可在线阅读,更多相关《双音多频拨号系统DTMF的实验报告.docx(14页珍藏版)》请在冰豆网上搜索。
双音多频拨号系统DTMF的实验报告
双音多频拨号系统DTMF的实验报告
双音多频拨号系统DTMF的实验设计报告
所谓双音多频(DTMF),就是用两个频率——行频和列频来表示电话机键盘上的一个数字。
DTMF电话的指令正在迅速的取代脉冲指令。
除了在电话呼叫信号中使用外,DTMF还广泛的使用在交互式控制应用,例如电话银行、电子邮件甚至家电远程控制等,用户可以从电话机发送DTMF信号来做菜单选择。
本文基于MATLAB的双音多频拨号系统的仿真实现。
主要涉及到电话拨号音合成的基本原理及识别的主要方法,利用MATLAB软件以及DFT算法实现对电话通信系统中拨号音的合成与识别。
并进一步利用MATLAB中的图形用户界面GUI制作简单直观的模拟界面。
还能够利用矩阵不同的基频合成0-9不同按键的拨号音,并能够对不同的拨号音加以正确的识别,实现由拨号音解析出电话号码的过程,进一步利用GUI做出了简单的图形操作界面。
本文具有界面清楚,画面简洁,易于理解,操作简单的优点,从而实现对电话拨号音系统的简单的信号仿真。
关键词:
双音多频(DTMF) MATLAB GUI 信号仿真
在电话中,数字0~9的中每一个都用两个不同的单音频传输,所用的8个频率分成高频带和低频带两组,低频带有四个频率:
679Hz,770Hz,852Hz和941Hz;高频带也有四个频率:
1209Hz,1336Hz,1477Hz和1633Hz.。
每一个数字均由高、低频带中各一个频率构成,例如1用697Hz和1209Hz两个频率,信号用表示,其中,。
这样8个频率形成16种不同的双频信号。
一,利用GUI作图(简单的电话界面)如下:
利用GUI图形用户界面设计工具制作电话拨号面板,把DTMF信号和电话机的键盘矩阵对应起来。
其中选用我们熟悉的10个数字键0—9,3个功能键“回删”、“拨号”,“解码”。
按照图电话机键盘矩阵的排列方式制作五行三列的按键控件。
每个按键可用 (PushButton)添加。
静态文本框可用 (StaticText)添加,如图再加个解码键(PushButton)
二,再点
运行,得出与上图对应的m文件,再用鼠标右击上图的每个键,点callback导入每个键的编译程序如下:
1,按键1的程序:
%---Executesonbuttonpressinpushbutton4.
functionpushbutton4_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点
y=sin(0.5345*n)+sin(0.9272*n);%对应行频列频时域叠加,数字1的低频697Hz和高频1209Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'1'];
set(handles.text1,'string',[NoCtrl]);
end
2,按键2的程序:
functionpushbutton5_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点
y=sin(0.5345*n)+sin(1.0247*n);%对应行频列频时域叠加,数字2的低频697Hz和高频1336Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'2'];
set(handles.text1,'string',[NoCtrl]);
end
3.按键3的程序:
%---Executesonbuttonpressinpushbutton6.
functionpushbutton6_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点
y=sin(0.5345*n)+sin(1.1328*n);%对应行频列频时域叠加,数字3的低频697Hz和高频1477Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'3'];
set(handles.text1,'string',[NoCtrl]);
end
4,按键4的程序:
%---Executesonbuttonpressinpushbutton10.
functionpushbutton10_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点
y=sin(0.5905*n)+sin(0.9272*n);%对应行频列频时域叠加,数字4的低频770Hz和高频1209Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'4'];
set(handles.text1,'string',[NoCtrl]);
end
5,按键5的程序:
%---Executesonbuttonpressinpushbutton9.
functionpushbutton9_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点v
y=sin(0.5905*n)+sin(1.0247*n);%对应行频列频时域叠加,数字5的低频770Hz和高频1336Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'5'];
set(handles.text1,'string',[NoCtrl]);
end
6,按键6的程序:
%---Executesonbuttonpressinpushbutton8.
functionpushbutton8_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点
y=sin(0.5905*n)+sin(1.1328*n);%对应行频列频时域叠加,数字6的低频770Hz和高频1477Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'6'];
set(handles.text1,'string',[NoCtrl]);
end
7,按键7的程序:
%---Executesonbuttonpressinpushbutton13.
functionpushbutton13_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点
y=sin(0.6534*n)+sin(0.9272*n);%对应行频列频时域叠加,数字7的低频852Hz和高频1209Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'7'];
set(handles.text1,'string',[NoCtrl]);
end
8,按键8的程序:
%---Executesonbuttonpressinpushbutton12.
functionpushbutton12_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点
y=sin(0.6534*n)+sin(1.0247*n);%对应行频列频时域叠加,数字8的低频852Hz和高频1336Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'8'];
set(handles.text1,'string',[NoCtrl]);
end
9,按键9的程序:
%---Executesonbuttonpressinpushbutton14.
functionpushbutton14_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];%每个数字1000个采样点
y=sin(0.6534*n)+sin(1.1328*n);%对应行频列频时域叠加,数字9的低频852Hz和高频1477Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'9'];
set(handles.text1,'string',[NoCtrl]);
end
10,按键0的程序:
%---Executesonbuttonpressinpushbutton17.
functionpushbutton17_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(length(x)>15)
errordlg('Sorry.Thenumberyouhaveinputistoolong!
','InputError','modal')
else
n=[1:
1000];每个数字1000个采样点
y=sin(0.7217*n)+sin(1.0247*n);%对应行频列频时域叠加,数字0的低频941Hz和高频1336Hz叠加
wavplay(y,8192)%产生拨号音
space=zeros(1,100);%100个0模拟静音信号
globalNUM
phone=[NUM,y];%循环储存
NUM=[phone,space];%储存连续的拨号音信号
NoCtrl=x;
NoCtrl=[NoCtrl,'0'];
set(handles.text1,'string',[NoCtrl]);
end
11,按键#号程序:
%---Executesonbuttonpressinpushbutton16.
functionpushbutton16_Callback(hObject,eventdata,handles)
set(handles.text1,'string',['']);
set(handles.tbutton,'visible',['off']);
set(handles.tbutton,'value',[0]);
clearall
12,按键*的程序:
%---Executesonbuttonpressinpushbutton18.
functionpushbutton18_Callback(hObject,eventdata,handles)
set(handles.text1,'string',['']);
set(handles.tbutton,'visible',['off']);
set(handles.tbutton,'value',[0]);
clearall
13,回删键的程序:
%---Executesonbuttonpressinpushbutton20.
functionpushbutton20_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
if(isempty(x))
errordlg('PleaseinputthephoneNo.','Inputerror','modal')
else
xll=length(x);
x(xll)=[];%去掉末尾号在面板上的显示
set(handles.text1,'string',[x]);
globalNUM
ll=length(NUM);%删除末尾号码在拨号音信号中的储存
fori=ll-1100+1:
ll
NUM(ll)=[];
ll=length(NUM);
end
end
14,拨号键的程序:
%---Executesonbuttonpressinpushbutton21.
functionpushbutton21_Callback(hObject,eventdata,handles)
x=get(handles.text1,'string');%把数字显示在屏幕上
xx=str2num(x);
globalNUM
if(isempty(NUM))
errordlg('PleaseinputthephoneNo.','Inputerror','modal')
else
wavplay(NUM,8192);
msgbox('拨号成功!
若需再次拨号请按#号复位!
','Done','help')
set(handles.tbutton,'visible',['on']);
set(handles.text1,'string',['DielingDone.']);
end
14,关闭键的程序:
%---Executesonbuttonpressinpushbutton22.
functionpushbutton22_Callback(hObject,eventdata,handles)
clearall
closeall
15,解码的程序:
%---Executesonbuttonpressintbotton.
functiontbotton_Callback(hObject,eventdata,handles)
globalNUM
L=length(NUM);
n=L/1100;
number='';
fori=1:
n
j=(i-1)*1100+1;
d=NUM(j:
j+999);%截取出每个数字
f=fft(d,2048);%以N=2048作FFT变换
a=abs(f);
p=a.*a/10000;%计算功率谱
num
(1)=find(p(1:
250)==max(p(1:
250)));%找行频通过计算得出数值范围
num
(2)=300+find(p(300:
380)==max(p(300:
380)));%找列频通过计算得出数值范围
if(num
(1)<180)row=1;%确定行数
elseif(num
(1)<200)row=2;
elseif(num
(1)<220)row=3;
elserow=4;
end
if(num
(2)<320)column=1;%确定列数
elseif(num
(2)<340)column=2;
elsecolumn=3;
end
z=[row,column];%确定数字
ifz==[4,2]tel=0;%0在4行2列
elseifz==[1,1]tel=1;%1在1行1列
elseifz==[1,2]tel=2;%2在1行2列
elseifz==[1,3]tel=3;%3在1行3列
elseifz==[2,1]tel=4;%4在2行1列
elseifz==[2,2]tel=5;%5在2行2列
elseifz==[2,3]tel=6;%6在2行3列
elseifz==[3,1]tel=7;%7在3行1列
elseifz==[3,2]tel=8;%8在3行2列
elseifz==[3,3]tel=9;%9在3行3列
end
t(i)=tel;
c=strcat(number,int2str(tel));
number=c;
i=i+1;
end
set(handles.text1,'string',['解码中...']);
h=waitbar(0,'Decoding...Pleasewait...');
steps=1500;
forstep=1:
steps
%computationstakeplacehere
waitbar(step/steps)
end
close(h);
set(handles.text1,'string',number);
%hObjecthandletotbotton(seeGCBO)
%eventdatareserved-tobedefinedinafutureversionofMATLAB
%handlesstructurewithhandlesanduserdata(seeGUIDATA)
三,运行以上程序调出如下图界面:
即可以进行仿真拨号。
四,程序具体说明:
1.按下任意0~9键就可以实现仿真拨号:
这里每个数字信号取1000个采样点模拟按键信号,并且每两个数字之间用100个0来表示间隔模拟静音,间隔也是在按键时产生的。
如:
按键1y=sin(0.5345*n)+sin(0.9272*n)算法,sin([低频*2pi/采样频率8192]*采样点n)+sin([高频*2pi/采样频率8192]*采样点n);
2.*号和#号功能一样,清空文本框确定保留号码,实现从新拨号;即将前面拨过的号码进行确认保留,意味着此时连续拨号音信息的储存单元NUM中的信号即为最后用于识别的连续拨号音DTMF信号,并在显示窗口中显示“#”号作为标记
3.回删键的作用:
是将前面拨错的号码删除退回,表现为将显示窗口已