DTMF通信系统设计—基于MATLAB和STM32

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 双音多频(DTMF)信号具有抗干扰能力强、传输速率高的优点,其首先应用于电话的拨号系统。随着时代的发展,DTMF 信号的应用也更加广泛,现今已被应用在诸如语言菜单、语音邮件、电话银行和ATM 终端中。本系统分别基于MATLAB 和单片机完成了DTMF 通信系统的设计,可实现基于DTMF信号的MATLAB 双机通信、单片机双机通信以及MATLAB 与单片机的相互通信等功能,并且能输出相关波形及声音。为了操作更加简便,结果观察更加直观,系统设计有相应的GUI 界面。


🎀 文章作者:二土电子
🐸 期待大家一起学习交流!


1 摘要

双音多频(DTMF)信号具有抗干扰能力强、传输速率高的优点,其首先应用于电话的拨号系统。随着时代的发展,DTMF 信号的应用也更加广泛,现今已被应用在诸如语言菜单、语音邮件、电话银行和ATM 终端中。

本系统分别基于MATLAB 和单片机完成了DTMF 通信系统的设计,可实现基于DTMF信号的MATLAB 双机通信、单片机双机通信以及MATLAB 与单片机的相互通信等功能,并且能输出相关波形及声音。为了操作更加简便,结果观察更加直观,系统设计有相应的GUI 界面。此外,为了保护系统的隐私性,本系统还增加了登录功能,可实现用户注册、修改密码。

关键词:双音多频;MATLAB;单片机;双机通信

2 设计任务

  1. 利用MATLAB 设计一个DTMF 通信系统;
  2. 输出DTMF 波形及声音;
  3. 利用单片机设计一个DTMF 通信系统

3 课程设计主要解决的问题

  1. 六位电话号码输出到MATLAB GUI 的文本框中时,显示不完全。
    错误原因:起初获取输入号码时利用str2num()函数,将字符串转换成了数字,号码检测完成后,输出结果仍为数字变量,由于数值较大,显示时自动采用了科学计数法来表示,导致输出结果出现错误。
    解决办法:在输出检测结果前,先利用num2str()函数将数字转换成字符串,然后再输出。

  2. 利用单片机根据时序图进行DTMF 编码时出现编码错误,0~9 只有两种DTMF 信号。
    错误原因:控制DTMF 编码数据位的单片机引脚被复用。
    解决办法:选择其他没被复用的GPIO 口。

  3. 利用录音进行六位号码检测时,检测出的结果出现错误。
    错误原因:利用audiowrite()函数将录音存储为.wav 文件时,audiowrite 要求信号幅度位于[-1,1]区间,但是产生的DTMF 信号幅度位于[-2,2]区间,所以在存储时信号被裁剪。而译码时信号幅度又是重要参量,所以导致译码错误。
    解决办法:在利用audiowrite()函数将录音存储为.wav 文件前先将DTMF 信号幅度缩小两倍再进行存储,读取出来后再放大两倍,恢复成原来的幅度。

  4. 实现MATLAB 双机通信时,误码率较高。
    错误原因:DTMF 信号的幅度偏低,而噪声较大,导致信噪比较低,接收时误码率偏高。
    解决办法:提高DTMF 信号的幅度。

4 设计内容

4.1 整体设计方案

  1. MATLAB部分
    由一个高频信号和一个低频信号叠加生成一个DTMF 信号,发送端利用sound()函数将数字信号转换成模拟语音信号,接收端利用audiorecorder()函数对模拟语音信号进行采样将其转换为数字信号,做出译码并显示结果,二者通过音频线连接,也可直接将声音外放,译码利采用戈泽尔算法。

042e16deffb81546bab0accd1bc1f90c_15e452a9a3e3447fad3632dbbfd2c51e.png

这个图容易引发歧义,图中“产生DTMF信号”实际指的是MATLAB配置好频率,实际发出声音产生还是要DAC。

  1. 单片机部分
    主要流程与MATLAB 实现相同,以STM32F103ZET6 为主控核心,利用AE11A04模块产生DTMF 信号,MT8870 芯片及其外部电路实现DTMF 信号的接收,声音信号通过音频线传输。

  2. 输出DTMF 波形及声音
    MATLAB 中利用plot()函数绘出DTMF 时域波形,利用stem()函数绘出频谱图,利用sound()函数输出DTMF 拨号音;单片机部分利用扬声器输出DTMF 拨号音,将声音传输给MATLAB 并利用MATLAB 显示出波形;

4.2 详细设计内容

  1. 基于MATLAB 的DTMF 通信系统
    实现了利用MATLAB 对DTMF 信号的产生和检测,并且能够实现两台PC 机间的任意位电话号码传输和接收。

  2. 基于单片机的DTMF 通信系统
    以STM32F103ZET6 为主控核心,实现了DTMF 信号的产生以及接收,可实现两台单片机间的六位电话号码传输和接收。也可以由一台单片机自发自收。

  3. MATLAB 与单片机间的DTMF 通信
    实现了由MATLAB 产生六位电话号码,通过音频线发送给单片机,单片机进行接收并正确显示接收结果。

  4. 输出DTMF 波形及声音
    在MATLAB 中实现了输出DTMF 时域波形、频谱以及声音。单片机也可输出DTMF声音,波形显示需借助于示波器或者MATLAB。

  5. MATLAB 登录系统设计
    设计了一个MATLAB 登陆系统,可实现用户注册、修改密码等功能。

  6. MATLAB 和单片机均设计了相应的GUI 界面,操作简便,便于观察检测结果和相关
    波形。

5 结果与分析

5.1 基于MATLAB 的DTMF 通信系统

  1. DTMF 信号波形显示声音输出以及六位电话号码检测

eb57d1b3a60a32f4497a87ed12acfd31_2c50da191b9542108ec00f2d4eb17d0b.png

上图右侧可以设置信噪比,选择是否引入高斯白噪声。每按下一个按键就会检测按下键值。左侧可以进行6位电话号码检测。可以显示检测结果,查看每一位DTMF信号的波形和频谱。当不引入噪声时结果均正确;引入噪声且信噪比较低时会出现接收错误。

5.2 双机通信模拟

此时需要两台电脑和一根音频线,一台电脑做发送端,另一台电脑做接收端。

首先在主页选择双机通信

4d5934a3c4d0ee1e830956195fd3b34b_468d60e7ccc54c259048c89202b0aa97.png

进入双机通信仿真页面,发送端发送125869。

21bc60796155d76589c47f38cee1bfec_9ea941df98e440abbdd7694e60b5bc24.png

接收端首先点击开始检测,会弹出一个窗,提示准备开始录音。

ed054fa2394fa770cf9d5f0cf861fa55_ce79d695473b4a6e8d29bdc7b085a8a6.png

接收端按下确定后,发送端点击拨号。此时接收端开始录音,录音完成后会显示检测结果,点击声音波形或者短时能量可以看到接收信号的声音波形和短时能量波形。

ba949c4b6073a28aa2d67e6e65e92265_a7e37a4785594ec6bcce723db6a7f444.png

5.2 基于单片机的DTMF 通信系统

由于资源有限,所以这里只用一台单片机自发自收,模拟双机通信,二者原理相同。仿真结果可以看出发送接收,误码率较低。

8f42b1b1f77d18ab22774840e3d32dd2_2bbdb8927d214028854b4e622afe6a7b.png

5.3 MATLAB 与单片机间的DTMF 通信

由MATLAB 随机发送六位电话号码,单片机进行接收,能正确判断发送的号码以及号
码位数,二者通过音频线相互连接。

电脑端选择单片机通信,输入号码,通过音频线发送给单片机,单片机解析并显示。

8d24b69b7611a28574d3737a094dc045_ca232e4f0b7f4185ba79fe967bfcfe96.png

749e1d8df189601d320eaf6b26f168f3_db0a811d45ee4c45975b3f82a44ecf35.png

可以看出,MATLAB 发送的六位号码为“106337”,单片机检测的号码位数为六位,检测结果为“006337”,第一位出现错误。但是在大量的仿真实验中发现,单片机接收的误码率还是很低的。

6 总结与展望

本次课程设计基于MATLAB 和单片机设计了一个DTMF 通信系统,系统操作简单,误码率较低,不仅满足了题目要求,还做出了相应的拓展,总体来看较为满意。通过本次课程设计强化了我的MATLA 编程、C 语言编程和GUI 界面设计的能力,加深了我对DTMF 通信系统的了解,学习到了一些用于DTMF 编、译码的模块和芯片,了解了戈泽尔算法的原理。由于单片机部分资料较少,所有程序都只能根据芯片资料编写,甚至有些芯片的资料为英文。这不仅锻炼了我的英文水平,还让我学习了如何根据芯片时序图独立编写程序。

当然,本次设计也有不足之处,由单片机产生DTMF 信号时,两个音频输出口同时只能一个具有有效输出,所以无法在发送DTMF 信号时产生拨号音。此外,在由于课程设计时间有限,所以系统还有许多可以改进的地方。比如利用DMA 使得编码、译码分别独立进行,以提高系统运行效率,甚至利用红外遥控或者蓝牙实现远程控制DTMF 编码等功能。

至此课程设计报告的内容已经介绍完成,接下来针对程序设计时的核心部分做一个简单介绍,后续博主也会将程序代码上传到资源,感兴趣的友友可以关注一下哟。

7 关键程序设计

7.1 MATLAB程序设计

7.1.1 产生DTMF信号

MATLAB产生DTMF信号较为简单,生成两个固定频率的正弦信号,将二者叠加(相加)起来即可。

599b01f646755c9d28450e788ecbfba5_64e9aacdb1924c8cad63f5dd66b24e01.png

以“1”为例,介绍一下MATLAB生成DTMF信号的程序设计

%按键1
A=10;%振幅
fs=44100;   %采样频率
N=8820;    % 信号样点数,每个音频播放时长
f = [697,1209;697,1336;697,1477;770,1209;770,1336;770,1477;852 1209;852 1336;852 1477;

global y;
y = [y A*sin(2*pi*f(1,1)*(0:N-1)/fs)+A*sin(2*pi*f(1,2)*(0:N-1)/fs) zeros(1,4410) ];
n=strcat(get(handles.edit1,'String'),'1');
set(handles.edit1,'String',n);   % 显示按下的按键

值得注意的是,如果信号幅值太小会导致译码时错误概率升高。

7.1.2 DTMF信号译码

以单个DTMF信号解析为例,介绍一下译码过程。

%单个按键检测程序 
    %DAC生成DTMF信号音
    filename = ('chen.wav'); %给文件取名
    audiowrite(filename,z1,8000) %存储.wav音频文件,在这里文件名为dtmf.wav

    %ADC解析录音文件
    [r1,~]=audioread('chen.wav');
    r1=r1.*2;   %程序里audiowrite要求sum_x位于[-1,1]区间,译码时信号幅度是重要参量,所以读取完之后要把幅度变为原来的幅度

    X=goertzel(r1(1:N),K+1);   %利用戈泽尔算法进行译码
        val=abs(X);

    limit=80;
   for s=5:8
       if val(s)>limit,break,end   %查找列号
   end
   for r=1:4
       if val(r)>limit,break,end   %查找行号
   end
   TNr=tm(r,s-4);   %译码结果

7.2 单片机程序设计

7.2.1 产生DTMA信号

单片机利用AE11A04芯片产生DTMF信号,具体的资料找不到了,有兴趣的友友可以到某宝搜索一下。这里凭借之前的程序,简单介绍一下产生DTMF信号的原理。

实际原理比较简单,当时买的一个集成的硬件模块,一共五根线,分别是STD,AD0,AD1,AD2,AD3。需要产生DTMA信号时先拉高STD引脚,配置AD0~AD3,组成一个二进制数,实际DTMF信号就是由二进制数控制,4位二进制数,16种组合,每一种代表一个DTMF信号。延时500ms后再将STD引脚拉低,就输出了一个DTMF信号。具体的对应表格有些找不到了,大家也可以根据下面每一个DTMF信号的程序看一下对应关系。

void AE11A04_Init(void)
{
   
   
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);     //使能PB,PE端口时钟

    GPIO_InitStructure.GPIO_Pin = STD | AD0 | AD1 | AD2 | AD3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
    GPIO_Init(GPIOB, &GPIO_InitStructure);                     //根据设定参数初始化GPIOB.5
    GPIO_ResetBits(GPIOB,STD | AD0 | AD1 | AD2 | AD3);
}

// 接下来是每一个DTMF信号对应的IO配置,这里只用到了数字

    // 数字1
    GPIO_SetBits(GPIOB,STD | AD0);
    GPIO_ResetBits(GPIOB,AD1 | AD2 | AD3);   //对DTMF信号做二进制编码
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字2
    GPIO_SetBits(GPIOB,STD | AD1);
    GPIO_ResetBits(GPIOB,AD0 | AD2 | AD3);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字3
    GPIO_SetBits(GPIOB,STD | AD0 | AD1);
    GPIO_ResetBits(GPIOB,AD2 | AD3);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字4
    GPIO_SetBits(GPIOB,STD | AD2);
    GPIO_ResetBits(GPIOB,AD0 | AD1 | AD3);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字5
    GPIO_SetBits(GPIOB,STD | AD0 | AD2);
    GPIO_ResetBits(GPIOB,AD1 | AD3);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字6
    GPIO_SetBits(GPIOB,STD | AD1 | AD2);
    GPIO_ResetBits(GPIOB,AD0 | AD3);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字7
    GPIO_SetBits(GPIOB,STD | AD0 | AD1 | AD2);
    GPIO_ResetBits(GPIOB,AD3);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字8
    GPIO_SetBits(GPIOB,STD | AD3);
    GPIO_ResetBits(GPIOB,AD0 | AD1 | AD2);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字9
    GPIO_SetBits(GPIOB,STD | AD0 | AD3);
    GPIO_ResetBits(GPIOB,AD1 | AD2);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

    // 数字0
    GPIO_SetBits(GPIOB,STD | AD1 | AD3);
    GPIO_ResetBits(GPIOB,AD0 | AD2);
    delay_ms(500);
    GPIO_ResetBits(GPIOB,STD);

7.2.2 单片机接收

单片机接收使用的是MT8870芯片,也是直接买的集成好的模块。跟生成DTMF信号的原理相同,他也是通过四根信号线接收到的4位二进制数来判断是哪个DTMF信号。这里只贴一下MT8870的初始化函数,具体解析时信号的对应关系可以看一下7.2.1小节。

void MT8870_Init(void)
{
   
   
    GPIO_InitTypeDef GPIO_InitStructure;    
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); // 使能PC端口时钟

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |GPIO_Pin_4 | GPIO_Pin_5;    //选择对应的引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//配置GPIO模式,输入上拉       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PC端口    
}
相关文章
|
7月前
|
算法 Shell
通信系统中ZF,ML,MRC以及MMSE四种信号检测算法误码率matlab对比仿真
通信系统中ZF,ML,MRC以及MMSE四种信号检测算法误码率matlab对比仿真
|
7月前
|
算法
基于DF模式的协作通信技术matlab性能仿真
基于DF模式的协作通信技术matlab性能仿真
|
7月前
|
机器学习/深度学习 算法 Windows
m基于深度学习的OFDM通信系统频偏估计算法matlab仿真
m基于深度学习的OFDM通信系统频偏估计算法matlab仿真
98 1
基于OFDM的水下图像传输通信系统matlab仿真
基于OFDM的水下图像传输通信系统matlab仿真
|
3月前
|
算法 5G 数据安全/隐私保护
大规模MIMO通信系统信道估计matlab性能仿真,对比LS,OMP,MOMP以及CoSaMP
本文介绍了大规模MIMO系统中的信道估计方法,包括最小二乘法(LS)、正交匹配追踪(OMP)、多正交匹配追踪(MOMP)和压缩感知算法CoSaMP。展示了MATLAB 2022a仿真的结果,验证了不同算法在信道估计中的表现。最小二乘法适用于非稀疏信道,而OMP、MOMP和CoSaMP更适合稀疏信道。MATLAB核心程序实现了这些算法并进行了性能对比。以下是部分
260 84
|
8天前
|
算法 数据安全/隐私保护
数字通信中不同信道类型对通信系统性能影响matlab仿真分析,对比AWGN,BEC,BSC以及多径信道
本项目展示了数字通信系统中几种典型信道模型(AWGN、BEC、BSC及多径信道)的算法实现与分析。使用Matlab2022a开发,提供无水印运行效果预览图、部分核心代码及完整版带中文注释的源码和操作视频。通过数学公式深入解析各信道特性及其对系统性能的影响。
|
2月前
|
固态存储
螺旋卫星通信天线设计与有限元分析matlab仿真
本课题研究了尺寸为10cm*10cm*30cm的卫星上搭载的螺旋型天线,工作于UHF频段(1-3GHz)。通过MATLAB2022a进行系统仿真,展示了天线的辐射特性。螺旋天线因其低轴比、宽带宽和紧凑结构而适用于卫星通信。采用有限元法分析天线的电磁性能,计算了天线的关键性能指标,包括S参数、增益、轴比等。
|
5月前
|
算法
基于VLC可见光通信的室内光通信信道信噪比分析matlab仿真
**算法演示展示了一段VLC通信,使用MATLAB2022a。核心代码片段涉及LED光强度调制。VLC系统由发射器、空气介质和接收器组成,利用OOK等调制技术。图像展示了系统模型。信噪比分析对于理解和提升室内通信的性能至关重要,影响数据速率和系统可靠性。** (Markdown格式) ```
|
7月前
|
机器学习/深度学习 算法
基于Volterra级数的DFE判决反馈均衡器可见光通信系统误码率matlab仿真
该内容是关于使用Volterra级数和判决反馈均衡器(DFE)改进可见光通信(VLC)系统的一段描述。展示了算法在matlab2022a中的应用,包括Volterra级数的非线性系统模型和DFE的结构,用于抵消非线性失真和码间干扰。还给出了部分核心MATLAB代码,涉及信号调制、滤波、噪声处理和均衡器权重计算等步骤。
|
7月前
|
算法
m基于log-MPA检测算法的SCMA通信链路matlab误码率仿真
MATLAB 2022a仿真实现了稀疏码多址接入(SCMA)算法,该算法利用码本稀疏性实现多用户高效接入。每个用户从码本中选取码字发送,接收端采用Log-MPA算法进行多用户检测。由于MAP检测计算复杂度高,故采用Log-MPA降低复杂性。仿真展示了不同迭代次数(1, 5, 10, 30)对误码率(BER)的影响,通过比较各次迭代的BER曲线,研究算法性能与迭代次数的关系。
95 0