数字信号处理课设报告

燕山大学

课 程 设 计 说 明 书

  题     目: 虚拟电子琴设计

学院(系):  电气工程学院 

年级专业:

学    号:

学生姓名:

指导教师:

职称: 

电气工程学院《课程设计》任务书

院(系):电气工程学院          基层教学单位:自动化仪表系

说明:1、此表一式四份,系、指导教师、学生各一份,报送院教务科一份。

      2、学生那份任务书要求装订到课程设计报告前面。

目  录

目  录  ………………………………………………………2

第一章 摘要 …………………………………………………3

第二章 系统总体设计方案 ………………………………4

第三章 信号处理模块基本原理 …………………………5

第四章 matlab软件实现 …………………………………7

       4.1图形界面设计………………………………………7

4.2 matlab编程…………………………………………8

4.3存在的问题…………………………………………13

第五章 课设心得及总结……………………………………14

参考文献 ………………………………………………………15

附录………………………………………………………………16

第一章 

目前,音频信号处理技术发展迅猛,其中数字信号处理已成为主流。数字信号适合计算机处理,数字信号的处理速度非常快,发展前景非常广阔。

Matlab是矩阵实验室的简称,用于算法开发、数据可视化、数据分析以及数值计算的高级计数计算语言和交互式环境。

本次“单片机原理及其应用——数字信号处理”课程设计的题目为虚拟电子琴设计。要求上位机和下位机通过串行通讯技术共同控制并实现。本文着重介绍了上位机利用matlab产生虚拟信号发生器,产生不同频率的信号对应不用琴键的音调,通过串行口传给下位机实现功能。在matlab中利用GUI界面设计软件分析界面,对产生的虚拟信号做时域和频域的分析。

关键词:matlab,虚拟电子琴,数字信号

第二章 系统总体设计方案

根据课程设计任务书要求,设计7个音符信号,利用matlab设计对应7个虚拟琴键,没按下一次琴键,通过串口通讯技术,对单片机传送,单片机对接收到的信号进行识别,启动蜂鸣器发出相应频率的音调,同时控制LED显示琴键音节数字和16*16LED点阵显示琴键音节字符。扩展部分:编制一段简单旋律自动输出。

下面具体介绍上位机控制实现部分。下位机控制和实现部分见单片机课程设计报告。

在matlab中主要涉及的问题是:第一,设计7种不同频率的信号发生器对应七种不同的音调;第二,对这七种不同频率的信号进行时域和频域分析,计算一些参数值进行对比;第三,学会使用GUI界面,设计虚拟电子琴界面,其中包括时域和频域图形显示模块,频率,幅值等参数显示模块,虚拟琴键模块等。

第三章 信号处理模块基本原理

一、常用的虚拟信号发生器一般可产生正弦信号,方波新号,三角波信号,锯齿波信号,脉冲信号,阶跃信号,斜坡信号等。对应的数字信号又可称为离散信号,即时间为离散变量的信号。它只是在离散时间上给出的函数值,是时间上不连续的序列。离散时间的间隔是均匀的,以表示。的值是由信号的采样频率决定。为保证采样后信号能真实地保留原始模拟信号信息,信号采样频率必须至少为原信号中最高频率成份为2倍。这是采样的基本法则,成为采样定理。

Matlab程序提供了常用的各种基本信号的生成函数。本设计中主要应用正弦信号,直接调用matlab提供的函数。

二、正弦信号的实现

  正弦信号的数学表达式如下(2.1)所示

           (2.1)

其中:A为幅值;为频率;为相位。

      在matlab中,将时间变量离散化并构成一个一维数组,如下式(2.2)所示

       (2.2)

其中:为采样频率。

相应的正弦波信号的数字信号表达式如下(2.3)

        (2.3)

三、虚拟电子琴的功能是基于虚拟信号发生器的。通过调用虚拟信号发生器产生一系列指定的频率的正弦信号,对应相应的虚拟琴键,通过按键和串口通讯使单片机的各个模块实现功能。虚拟电子琴界面上设计了七个虚拟琴键1—7,每个按键对应一个频率的正弦波新号,各按键对应的信号频率分别为:440Hz,494Hz,554Hz,587Hz,659Hz,740Hz,831Hz。当用鼠标按下对应的键时,就可发出相应频率的声音。

四、当载入一段简单音频信号(“music.Txt”)时,通过在matlab中编程,实现for循环,相当于连续自动按下虚拟琴键,并通过串口发送到单片机部分连续接收,识别,做出连续的响应,产生一段连续的音频信号,形成一段旋律。、

五、一些重要参数指标

标准差:也称均方差,是个数据偏离平均数的距离的平均数,它是离均差平方和平均后的方根,用表示。标准差是方差的算术平方根。标准差能反映一个数据集的离散程度。

方差:是各个数据与平均数之差的平方和的平均数。用来度量随机变量和数学期望之间的偏离程度。

峰峰值:在规定的时间范围内,正向与负向峰值之差。

第四章 matlab软件实现

Matlab是美国mathworks公司出品的商业数学软件,用于算法开发,数据可视化,数据分析以及数值计算的高级计数计算语言和交互式环境。

matlab开发环境是一套方便用户使用的matlab函数和文件工具集,其中许多工具是图形化用户接口。它是一个集成的用户工作空间,允许用户输入输出数据,并提供了m文件的集成编译和调试环境,包括matlab桌面,命令窗口,m文件编辑调试器,matlab工作空间和在线帮助文档。

4.1        图形界面设计

主要分成三部分:第一为波形显示区,显示相应音频信号的时域和频域波形;第二为按键区,用于虚拟琴键实际操作;第三为参数显示区,通过调用matlab中函数,计算相应的参数值,进行分析和对比。

打开matlab,进入GUI图形设计界面。在新建一个空白的图形界面文件,添加如下控件并设计布局。

(1)    添加2个axes控件,用于显示时域和频域波形;

(2)    添加8个static text,用于标题及参数名称的标注;

(3)    添加7个edit text,用于各参数值的显示;

(4)    添加9个push button,用于七个虚拟琴键,音乐载入和关闭界面功能。

(5)    添加2个panel,将相关的控件框在一起。

双击各个控件,打开其属性编辑窗,即可改变其名称,大小,颜色等属性,最终设计好的界面如下:

4.2        matlab编程

当GUI界面创建完成之后,点击运行即可自动生成包含各个控件回调函数在内的m文件。Matlab对于编辑文本,按钮等空间的相应都是通过自动调用相应的回调函数来实现的。回调函数即在一定的操作下自动执行的指令代码。

4.2.1        matlab环境下PC机和单片机串口通讯模块

在matlab环境下,实现串口通讯的方式有两种——查询和中断。在本次设计中用的是查询方式。

matlab对串行口编程控制主要分为四个步骤。

1)创建串口设备对象并设置其属性

2)打开串口设备对象

3)读/写串口操作

4)关闭并清除设备对象

function []=dtmf_series(Key)

ss=serial('com1'); %创建串口1设备对象ss

ss.BaudRate=2400;%波特率为2400b/s

ss.DataBits=8;%通讯数据格式为8位数据位

ss.Parity='none';%无奇偶校验位

ss.StopBits=1;%1位停止位

ss.TimeOut=60;%设置一次读或写操作最大完成时间60s

ss.DataTerminalReady='off';%数据终端准备

ss.RequestToSend='off';%请求发送

ss.FlowControl='none';%流量控制

ss.InputBufferSize=1000;%输入缓冲区

fopen(ss);%打开串口设备对象

fwrite(ss,Key);%写串口,发送握手信号key

%释放串口设备对象

fclose(ss);%关闭串口设备对象

delete(ss);%删除内存中串口设备对象

clear ss%清除工作空间中串口设备对象

 end

4.2.2        虚拟琴键模块

1)设计方案中设计了七个虚拟琴键,对应的频率值为440Hz,494Hz,554Hz,587Hz,659Hz,740Hz,831Hz。

对1-7这七个虚拟按键进行回调函数设计。虚拟键盘模块的设计实在GUI界面上,把键设计出来后,激活后自动生成m文件。程序内容包括:对应频率正弦信号的载入,通过串口传输给单片机,时域频域波形分析,一些参数计算值。

例如对按键1的回调函数:

function pushbutton1_Callback(hObject, eventdata, handles)

根据回调函数找到琴键1的主函数位置,在对应下面编写。

global ss;

 r=1;

 dtmf_series(r);

 t=0:0.0001:0.01;

 A=3;

 f=440;

 p=0;

 y=A*sin(2*pi*f*t+p);

 set(gcf,'CurrentAxes',handles.axesTime);

 plot(t,y)

 axis([0 0.01 -5 5])

 xlabel('time(s)');

 ylabel('amplitude');

 title('时域波形');

 grid on;

 fs=1000;

frequency_domain(handles,y,fs);

[A,B,C,D,E,F]=index_calculation(y);

set(handles.textMean,'string',num2str(A));%平均值

set(handles.textStd,'string',num2str(B));%标准差

set(handles.textVar,'string',num2str(C));%方差

set(handles.textMax,'string',num2str(D));%最大值

set(handles.textMin,'string',num2str(E));%最小值

set(handles.textPeak,'string',num2str(F));%峰峰值

set(handles.text23,'string',440); %频率值

其余六个琴键对应回调函数同上。

2)音频信号载入(music)

【115566544332215544332554433211556654433221】

function pushbutton10_Callback(hObject, eventdata, handles)

global d;

d=load('music.txt');

%时域

time_domain(handles,d);

fs=1000; %采样频率

%频域

frequency_domain(handles,d,fs);

[A,B,C,D,E,F]=index_calculation(d);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

%for循环语句实现音频信号自动每隔0.3s传输一个频率的音节

global i;

for i=1:42

    dtmf_series(d(i,1));

    pause(0.3);

end

4.3 存在的问题

1)在用matlab语言进行程序设计的过程中,由于语法的不熟悉,总是出错。例如,matlab中的数组元素标号是从1开始,而不是从0开始;for语句与C语言不同。

2)第一次接触GUI界面,不熟悉界面和控件含义,总是重复操作,效率很低。

3)由于自己对Matlab的语法以及函数不熟悉,导致自己的想法无法用matlab来实现,进度很慢。

第五章课设心得体会

本学期的数字信号处理课程设计,内容丰富,形式多样。不但丰富了我们的知识面,把书本上的理论知识相应的结合到了课设实践中,与实际问题相联系,让我们对数字信号处理这个课程有了进一步的了解,而且在matlab软件中编程,设计GUI界面,强化训练了我们实际操作动手的能力。又学习到了更多关于matlab软件的功能实现。

本次课程设计主题思想是模块化实现系统。每个模块完成他的子功能,把一个大的复杂的问题分解成了几个较为容易的小问题,减轻了工作负担,提高了效率,并且使做出的东西效果更好!这种思想对我们今后的学习和工作都有很大的帮助,在设计思路上有很好的作用,值得我们反复学习,反复实践。

在这两周的课程设计中,除了及时翻阅资料解决问题,还积极与小组成员不断进行交流沟通,使课题能顺利进行,遇到一些大家都无从下手的问题,就虚心请教研究生学长,一起探讨,和大家的合作都非常愉快,很感谢小组成员的团结协作,也很感谢老师和研究生学长提供这么多强有力的帮助。

此次课程设计中也暴露出我的很多不足,平时积累的知识太少,虽然作业都及时完成,但是还是缺乏课余时间的训练。编程能力有待提高,平时应该多翻阅相关的书籍资料,自己应该充分利用时间,来多做些软件编程的练习,多思考,多与实际问题相联系,为今后的学习和工作打下坚实的基础。

参考文献

[1] 谢平 林洪彬 信号处理原理及应用 机械工业出版社 2008

[2] 刘敏 魏玲 Matlab通信仿真与应用 国防工业出版社 2007

[3]楼顺天 基于Matlab7.x的系统分析与设计-信号处理  2005

附录

主程序部分:

function varargout = dzq(varargin)

gui_Singleton = 1;

gui_State = struct('gui_Name',       mfilename, ...

                   'gui_Singleton',  gui_Singleton, ...

                   'gui_OpeningFcn', @dzq_OpeningFcn, ...

                   'gui_OutputFcn',  @dzq_OutputFcn, ...

                   'gui_LayoutFcn',  [] , ...

                   'gui_Callback',   []);

if nargin && ischar(varargin{1})

    gui_State.gui_Callback = str2func(varargin{1});

end

if nargout

    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});

else

    gui_mainfcn(gui_State, varargin{:});

end

function dzq_OpeningFcn(hObject, eventdata, handles, varargin)

handles.output = hObject;

guidata(hObject, handles);

function varargout = dzq_OutputFcn(hObject, eventdata, handles)

varargout{1} = handles.output;

%虚拟琴键

% --- Executes on button press in pushbutton1.

function pushbutton1_Callback(hObject, eventdata, handles)

t=0:0.0001:0.01;

 A=3;

 f=440;

 p=0;

 y=A*sin(2*pi*f*t+p);

 set(gcf,'CurrentAxes',handles.axesTime);

 plot(t,y)

 axis([0 0.01 -5 5])

 xlabel('time(s)');

 ylabel('amplitude');

 title('ʱÓò²¨ÐÎ');

 grid on;

 fs=2000;

frequency_domain(handles,y,fs);

 [A,B,C,D,E,F]=index_calculation(y);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

set(handles.text23,'string',440);

% --- Executes on button press in pushbutton2.

function pushbutton2_Callback(hObject, eventdata, handles)

global ss;

r=2;

dtmf_series(r);

t=0:0.0001:0.01;

 A=3;

 f=494;

 p=0;

 y=A*sin(2*pi*f*t+p);

 set(gcf,'CurrentAxes',handles.axesTime);

 plot(t,y)

axis([0 0.01 -5 5])

xlabel('time(s)');

 ylabel('amplitude');

 title('ʱÓò²¨ÐÎ');

grid on;

fs=1000;

frequency_domain(handles,y,fs);

[A,B,C,D,E,F]=index_calculation(y);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

set(handles.text23,'string',494);

% --- Executes on button press in pushbutton3.

function pushbutton3_Callback(hObject, eventdata, handles)

global ss;

r=3;

dtmf_series(r);

t=0:0.0001:0.01;

 A=3;

 f=554;

 p=0;

 y=A*sin(2*pi*f*t+p);

 set(gcf,'CurrentAxes',handles.axesTime);

 plot(t,y)

axis([0 0.01 -5 5])

xlabel('time(s)');

 ylabel('amplitude');

 title('ʱÓò²¨ÐÎ');

grid on;

fs=1000;

frequency_domain(handles,y,fs);

[A,B,C,D,E,F]=index_calculation(y);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

set(handles.text23,'string',554);

% --- Executes on button press in pushbutton4.

function pushbutton4_Callback(hObject, eventdata, handles)

global ss;

r=4;

dtmf_series(r);

t=0:0.0001:0.01;

 A=3;

 f=587;

 p=0;

 y=A*sin(2*pi*f*t+p);

 set(gcf,'CurrentAxes',handles.axesTime);

 plot(t,y)

axis([0 0.01 -5 5])

xlabel('time(s)');

 ylabel('amplitude');

 title('ʱÓò²¨ÐÎ');

grid on;

fs=1000;

frequency_domain(handles,y,fs);

[A,B,C,D,E,F]=index_calculation(y);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

set(handles.text23,'string',587);

% --- Executes on button press in pushbutton5.

function pushbutton5_Callback(hObject, eventdata, handles)

global ss;

r=5;

dtmf_series(r);

t=0:0.0001:0.01;

 A=3;

 f=659;

 p=0;

 y=A*sin(2*pi*f*t+p);

 set(gcf,'CurrentAxes',handles.axesTime);

 plot(t,y)

axis([0 0.01 -5 5])

xlabel('time(s)');

 ylabel('amplitude');

 title('ʱÓò²¨ÐÎ');

grid on;

fs=1000;

 frequency_domain(handles,y,fs);

[A,B,C,D,E,F]=index_calculation(y);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

set(handles.text23,'string',659);

% --- Executes on button press in pushbutton6.

function pushbutton6_Callback(hObject, eventdata, handles)

global ss;

r=6;

dtmf_series(r);

t=0:0.0001:0.01;

 A=3;

 f=740;

 p=0;

 y=A*sin(2*pi*f*t+p);

 set(gcf,'CurrentAxes',handles.axesTime);

 plot(t,y)

axis([0 0.01 -5 5])

xlabel('time(s)');

 ylabel('amplitude');

 title('ʱÓò²¨ÐÎ');

grid on;

fs=1000;

frequency_domain(handles,y,fs);

[A,B,C,D,E,F]=index_calculation(y);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

set(handles.text23,'string',740);

% --- Executes on button press in pushbutton7.

function pushbutton7_Callback(hObject, eventdata, handles)

global ss;

 r=7;

 dtmf_series(r);

 t=0:0.0001:0.01;

 A=3;

 f=831;

 p=0;

 y=A*sin(2*pi*f*t+p);

 set(gcf,'CurrentAxes',handles.axesTime);

 plot(t,y)

 axis([0 0.01 -5 5])

 xlabel('time(s)');

 ylabel('amplitude');

 title('ʱÓò²¨ÐÎ');

 grid on;

 fs=1000;

frequency_domain(handles,y,fs);

 [A,B,C,D,E,F]=index_calculation(y);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

set(handles.text23,'string',831);

%载入音频信号

% --- Executes on button press in pushbutton10.

function pushbutton10_Callback(hObject, eventdata, handles)

global d;

d=load('music.txt');

time_domain(handles,d);

fs=20000;

frequency_domain(handles,d,fs);

[A,B,C,D,E,F]=index_calculation(d);

set(handles.textMean,'string',num2str(A));

set(handles.textStd,'string',num2str(B));

set(handles.textVar,'string',num2str(C));

set(handles.textMax,'string',num2str(D));

set(handles.textMin,'string',num2str(E));

set(handles.textPeak,'string',num2str(F));

global i;

for i=1:42

    dtmf_series(d(i,1));

    pause(0.3);

end

function textMean_Callback(hObject, eventdata, handles)

function textMean_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function edit3_Callback(hObject, eventdata, handles)

function edit3_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function edit4_Callback(hObject, eventdata, handles)

function edit4_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function edit5_Callback(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function edit6_Callback(hObject, eventdata, handles)

function edit6_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function edit7_Callback(hObject, eventdata, handles)

function edit7_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function textStd_Callback(hObject, eventdata, handles)

function textStd_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function textVar_Callback(hObject, eventdata, handles)

function textVar_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function textMax_Callback(hObject, eventdata, handles)

function textMax_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function textMin_Callback(hObject, eventdata, handles)

function textMin_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

function textPeak_Callback(hObject, eventdata, handles)

function textPeak_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

    set(hObject,'BackgroundColor','white');

end

% --- Executes on button press in Close.

function Close_Callback(hObject, eventdata, handles)

close(gcf);

 串口通讯部分:

function []=dtmf_series(Key)

ss=serial('com1');

ss.BaudRate=2400;

ss.DataBits=8;

ss.Parity='none';

ss.StopBits=1;

ss.TimeOut=60;

ss.DataTerminalReady='off';

ss.RequestToSend='off';

ss.FlowControl='none';

ss.InputBufferSize=1000;

fopen(ss);

fwrite(ss,Key);

fclose(ss);

delete(ss);

clear ss

end

参数计算部分:

function [A,B,C,D,E,F]=index_calculation(data)

A=mean(data); % 平均值

B=std(data); % 标准差

C=Var(data); % 方差

D=max(data); % 最大值

E=min(data); % 最小值µ

F=D-E; % 峰峰值

End

频域算法

function frequency_domain(handles,data,fs)

nfft= 2^nextpow2(length(data));找出大于y的个数的最大的2的指数值

ff=fs*(0:nfft/2-1)/nfft;%FFT变换后对应的频率的序列 fftx=fft(data,nfft);%求fft变换

set(gcf,'CurrentAxes',handles.axesFrequency);

plot(ff,abs(fftx(1:nfft/2))*2/nfft);

xlabel('Frequency');ylabel('Amplitude');title('频域波形’)

end

时域部分

function time_domain(handles,data)

set(gcf,'CurrentAxes',handles.axesTime);

plot(data);

xlabel('Data Points');ylabel('Amplitude');

end

燕山大学专业综合训练评审意见表

相关推荐