基于 MATLAB 设计信号发生器
虚拟仪器可以充分利用现有的计算机资源,实现普通仪器的所有功能和一些普通仪器上无法实现的软件或程序。本设计的主要内容是基于 MATLAB 来实现一个信号发生器。
一、前言
目前,MATLAB 已广泛应用于电子、通信等工程设计领域,已成为世界上最受欢迎的计算机仿真软件设计工具。MATLAB 不再仅仅是矩阵实验室,而是一种功能强大的实用先进的计算机编程语言。
GUI是 MATLAB 自带的数据采集工具箱包含许多有用的函数供用户调用。这些函数大致可分为以下组:数据采集对象的结构、采集和设置参数、执行、模拟输入/输出函数、数字输入/输出函数。上述函数广泛应用于通用信号发生器的设计过程中, 并以两种不同的方式完成数/模转换。
二、设计和实现信号发生器
程序简介
程序参考 MATLAB 的 Data Acquisition Toolbox 实现。在 MATLAB 的 GUI 设计中有两种设计方法:使用 GUI 编辑和编写 M 文件。
GUI 它是用户的操作界面,是选择波形、设置和修改波形参数、设置采样率、输出通道和操作、停止程序的人机交互接口。在该程序的界面中,可选波形包括正余弦(sin),Sa 波(sinc),方波(square),三角波(triangle),锯齿波
(tooth),噪声波(random),频变波(chirp),以及自定义波形(读取图形和数据文件)。波形参数包括频率(frequency),幅度(amplitude),直流偏置
(offset),初相位(phase),占空比(duty cycle),频变方法(method),频 变时间(target time),初始频率(initial(F)),目标频率(target(F))等。
触发 start 按钮将使程序进入运行状态,包括计算波形(二维数组)和绘制波形(在 PC 界面坐标系中)和输出波形(在选定的输出板卡中)。 stop 按钮(运行时start 按钮变成 stop 按钮)将停止程序和数组数据输出到板卡上。
界面浏览
该信号发生器的界面大致由以下五个区域组成:菜单区和参数设置区
(output1,output二、波形绘制区(output1,output2),输出选择区和输出控制区。界面如图所示 1 所示。

信号生成
图 1 信号发生器界面图
信号生成是指根据采样率将选定的波形(连续信号)分散到数字序列,序列中的每个数字都是采样率一段时间间间隔内信号的采样值。然后将相邻的采样点连接到短直线上,以几乎恢复原始的波形。可以看出,在相同的情况下,采样率越高, 恢复信号越好。
正弦波(sin)
表 1 正弦波参数
参数名 | 频率frequency | 幅度amplitude | 直流偏置offset | 初相位phase |
默认值 | 500 | 1 | 0 | 0 |
正弦波参数如表所示 1 所示采样率:samp 数组表示:
t=0:(1/samp):1;
y= offset amplitude *sin(2*pi*frequency*t phase*pi/180);
说明:t 在 1 秒内有 samp 采样点均匀,y 做为 samp×1 一维数组输出到板卡的通道。
Sa 波(sinc)
表 2 Sa 波参数
参数名 | 频率frequency | 幅度amplitude | 直流偏置offset | 初相位phase |
默认值 | 500 | 1 | 0 | 0 |
Sa 波参数如表 2 所示采样率:samp 数组表示:
t=0:(1/samp):1; y=offset amplitude*sin(2*pi*frequency*t phase*pi/180 eps)./
(2*pi*frequency*t phase*pi/180 eps);
这 里 “ / ” 用 的 是 “ ./ ”, 表 示 数 组 中 对 应 元 素 运 算 。 为 了2*pi*frequency*t phase*pi/180=0 表达式仍然有效,添加无限小量
“eps”。
方波(square)
表 3 方波参数
参数名 | 频率frequency | 幅度amplitude | 直流偏置offset | 占空比duty cycle |
默认值 | 500 | 1 | 0 | 50 |
方波参数如表所示 3 所示采样率:samp 数组表示:
t=0:(1/samp):1;
y= offset amplitude* sign(duty/100/ frequency -mod(t, 1/frequency));
三角波(triangle)
表 4 三角波参数
参数名 | 频率frequency | 幅度amplitude | 直流偏置offset |
默认值 | 500 | 1 | 0 |
三角波参数如表所示 4 所示采样率:samp 数组表示:
t=0:(1/samp):1;
y=(4*amplitude*frequency*mod(t,1/frequency)-2*amplitude).*sign(mo d(t1,1/frequency)-1/frequency/2)-amplitude offset;
上升和下降的比例均为 50%。
锯齿波(tooth)
表 5 锯齿波参数
参数名 | 频率frequency | 幅度amplitude | 直流偏置offset |
默认值 | 500 | 1 | 0 |
锯齿波参数如表所示 5 所示采样率:samp
数 组 表 示 : t=0:(1/samp):1;
y1=2 *amplitude *frequency *mod(t,1/ frequency)- amplitude offset;
噪声波(random)
表 6 噪声波参数
参数名 | 种子seed | 幅度amplitude | 直流偏置offset |
默认值 | 500 | 1 | 0 |
噪声波参数如表 6 所示。设采样率:samp 数组表示:
t=0:(1/samp):1;
y=2* amplitude*(rand(1,length(t))-0.5)+ offset;
说明:seed 为每个周期内的采样点数,t 在 1 秒内有 samp 个均匀采样点,y 做为 samp×1 的一维数组输出到板卡的一个通道。
频变波(chirp)
表 7 频变波参数
参数名 | 频变方法method | 变化时间targetTime | 初始频率initial F | 目标频率target F |
默认值 | Linear | 1 | 50 | 100 |
频变波参数如表 7 所示。设采样率:samp 数组表示:
t=0:(1/samp):1;
method=linear 时y=sin(2*pi*mod(t,tTime).*(iF+mod(t,tTime)*(tF-iF)/tTime));
method=log 时y=sin(2*pi*mod(t,tTime).*mod(t,tTime)*exp(log(tF/iF))*iF/tTime)
说明:t 在 1 秒内有 samp 个均匀采样点,y 做为 samp×1 的一维数组输出到板卡的一个通道。频率变化的方式不同,输出表达式也不同。
注意:method 有两个选项:linear 和 log; 符号“./”用于数组间运算。
自定义波(self-define)
表 8 自定义波参数
参数名 | 频率frequency | 幅度amplitude | 文件名filename |
默认值 | 500 | 1 |
自定义波参数如表 8 所示。设采样率:samp
说明:本选项是信号发生器的扩展功能之一,通过菜单区操作可以读取保存为图像和数据的文件,输出信号到输出板卡上。
①读取图像文件(*.bmp) 源 程 序 段 : h1=imread(filename);
h2=rgb2gray(h1) [m,n]=size(h2); for i=1:n
x(i)=0;
end
for i=1:n
for j=1:m
if (h2(j,i)~=255)
x(i)=1-j/m; end
end
end
说明:imread 函数按象素读取图像文件的 RGB 值(24 位颜色时每个象素需要
3 个字节),存储为二维数组,rgb2gray 将彩色图转变为灰度图(每个象素 1 个字节)。读到一个不为白色(255)的象素既是画线所在,因为图像原点在左上角, 所以还要经过求反和归一化处理(x(i)=1-j/m)。
②读取数据文件(*.txt)
源程序段:
fid = fopen(filename);
x = fscanf(fid,'%g',[1 inf]) fclose(fid)
说明:fscanf 函数可以读取已打开文本文件中的数字,放到一维数组中。注意:数据文件格式―数据值在 0~1 之间,以空格,Tab 为间隔。
举例:0.1 0.2 0.4 0.9 0.3 0.5 0.7 0.6
③数组长度-插值
因为读取图像和数据文件得到的数组长度和采样率所需点数无关,所以涉及到数组长度的改变,进而引出了插值的问题。
源 代 码 段 : p1=round(samp/frequency); for k=2:p1
l1=(k-1)*(length(x)-1)/(p1-1)+1; l3=ceil(l1);
l2=l3-1;
y1(k)=(x(l3)*(l1-l2)+(l3-l1)*x(l2))*amplitude; y1(1)=x(1)* amplitude;
end
for i=1:(samp+1) y(i)=y1(mod(i-1,p1)+1);
end
说明:这里用到了线性插值的方法来重构采样值。所谓线性插值就是所重构的点的值与其所对应的在原数组中相邻的点的值成直线关系。
例如:y(i)对应 x(2.3),则有 y(i)=x(3)*0.3+x(2)*0.7
注意:源代码中如表 9 所示,
表 9 线性插值
l1 | l2 | l3 |
Y()所对的 x()的下标 | 比 l1 小的最大整数 | 比 l1 大的最小整数 |
第一个 for 循环将原数组延拓为一个周期的点数(samp/frequency);第二个 for 循环再将其延拓为 1 秒的点数 samp(此处为 samp+1)。