要开发一个基于 matlab gui 从文本文件读入信号数据 并显示信号和频谱
点击一个按钮来 选择一个文本文件读入两个信号 如下
851531 1337831
851505 1337801
851539 1337838
用两个Axes 动态的显示这个两个信号 , 数据采样频率是 120 Hz, 长度是 3分钟 共计 21600 条数据
用两个Axes 动态显示这个信号频谱 就是 fft 变换
还需两个按钮 start 和 stop 来开始或者停止显示信号 和频谱
最好用到定时器
感兴趣朋友可以来索取 文本数据文件 我的邮箱 如下 或者留下您的联系方式,谢谢。
mbdbk@qq.com
参考GPT和自己的思路,下面是一个简单的 Matlab GUI 程序实现你的需求。该程序包括一个主窗口,其中有两个按钮 "Select File" 和 "Stop",以及四个 axes 组件分别用于显示两个信号的时域波形和频谱。
程序实现步骤如下:
1 创建 GUI 窗口并定义需要用到的变量
function myGUI
% 创建 GUI 窗口并定义需要用到的变量
% 创建主窗口
f = figure('Visible','off','Position',[360,500,600,400]);
% 定义需要用到的变量
fs = 120; % 采样频率
T = 3*60; % 信号长度(秒)
N = fs*T; % 信号长度(采样点数)
t = (0:N-1)/fs; % 时间向量
data = []; % 存储读入的信号数据
timer_interval = 0.05; % 定时器触发间隔
timer1 = timer('ExecutionMode', 'fixedRate', 'Period', timer_interval, 'TimerFcn', @updatePlot); % 定义定时器1
timer2 = timer('ExecutionMode', 'fixedRate', 'Period', timer_interval, 'TimerFcn', @updateFFT); % 定义定时器2
isRunning = false; % 用于判断程序是否在运行
stopFlag = false; % 用于停止定时器
% 定义 UI 控件
btn_select_file = uicontrol('Style', 'pushbutton', 'String', 'Select File', 'Position', [10 350 80 30], 'Callback', @selectFile);
btn_stop = uicontrol('Style', 'pushbutton', 'String', 'Stop', 'Position', [100 350 80 30], 'Callback', @stopTimer);
ax1 = axes('Units','pixels','Position',[60,60,250,250]);
ax2 = axes('Units','pixels','Position',[350,60,250,250]);
% 显示 GUI 窗口
f.Visible = 'on';
end
2 创建回调函数
% 回调函数1:读入文件并显示时域波形
function selectFile(~,~)
% 选择文本文件
[filename, path] = uigetfile('*.txt', 'Select a text file');
if isequal(filename,0)
return;
end
% 读入文件
fid = fopen(fullfile(path,filename),'r');
data = fscanf(fid,'%f %f\n',[2 inf]);
fclose(fid);
% 在 axes1 中显示信号1
axes(ax1);
plot(t, data(1,:), 'r');
xlim([0 max(t)]);
xlabel('Time (s)');
ylabel('Amplitude');
title('Signal 1');
% 在 axes2 中显示信号2
axes(ax2);
plot(t, data(2,:), 'b');
xlim([0 max(t)]);
xlabel('Time (s)');
ylabel('Amplitude');
title('Signal 2');
% 启动定时器
if ~isRunning
startTimer();
end
end
% 回调函数2:定时器1触发,更新时域波形
function updatePlot(~,~)
if stopFlag
stopTimer();
return;
end
% 更新时域波形
axes(ax1);
xlim([max(0, t(end)-T), t(end)]);
plot(t, data(1,:), 'r');
xlabel('Time (s)');
ylabel('Amplitude');
title('Signal 1');
axes(ax2);
xlim([max(0, t(end)-T), t(end)]);
plot(t, data(2,:), 'b');
xlabel('Time (s)');
ylabel('Amplitude');
title('Signal 2');
end
% 回调函数3:定时器2触发,更新频谱
function updateFFT(,)
if stopFlag
stopTimer();
return;
end
% 计算频谱
S1 = fft(data(1,:));
S2 = fft(data(2,:));
f = (0:N-1)*(fs/N);
% 更新频谱
axes(ax1);
plot(f, abs(S1), 'r');
xlim([0 fs/2]);
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title('Spectrum of Signal 1');
axes(ax2);
plot(f, abs(S2), 'b');
xlim([0 fs/2]);
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title('Spectrum of Signal 2');
end
% 回调函数4:启动定时器
function startTimer(,)
if isempty(data)
return;
end
isRunning = true;
start(timer1);
start(timer2);
end
% 回调函数5:停止定时器
function stopTimer(,)
stopFlag = true;
stop(timer1);
stop(timer2);
isRunning = false;
end
3 运行程序
将上面的代码保存为一个 Matlab 脚本文件,运行该文件即可启动 GUI 程序。在 GUI 窗口中点击 "Select File" 按钮,选择文本文件并加载数据。然后点击 "Stop" 按钮即可停止程序运行。
该回答引用ChatGPT
代码中,
signal_viewer_gui()
函数创建了一个 GUI 窗口,并定义了一些回调函数,包括:
1. select_data_file_callback()
:用于选择数据文件,并将数据读入到 data
变量中。
2. start_stop_callback()
:用于开始或停止数据可视化。
3. update_visualization_callback()
:用于更新波形和频谱显示。
4. close_figure_callback()
:用于关闭窗口时停止定时器。
signal_viewer_gui()
函数还创建了两个uiaxes
对象用于显示波形和频谱,以及一个timer
对象用于定时更新显示。create_timer()
函数创建了timer
对象,并定义了其属性。每次timer
对象触发时,会调用update_visualization_callback()
函数来更新显示。
当用户单击开始按钮时,
start_stop_callback()
函数会启动timer
对象并更新按钮文本,而当用户单击停止按钮时,start_stop_callback()
函数会停止timer
对象并更新按钮文本。
function signal_viewer_gui()
% 创建 GUI 窗口并设置其大小和标题
fig = uifigure('Position', [100 100 800 600], 'Name', 'Signal Viewer');
% 创建一个按钮用于选择数据文件
uibutton(fig, 'Position', [10 540 100 30], 'Text', 'Select Data', ...
'ButtonPushedFcn', @select_data_file_callback);
% 创建一个按钮用于开始/停止数据可视化
start_stop_button = uibutton(fig, 'Position', [120 540 100 30], 'Text', 'Start', ...
'ButtonPushedFcn', @start_stop_callback);
% 创建两个 Axes 用于显示波形和频谱
wave_axes = uiaxes(fig, 'Position', [10 200 600 300]);
wave_axes.XLabel.String = 'Time (s)';
wave_axes.YLabel.String = 'Amplitude';
spec_axes = uiaxes(fig, 'Position', [10 10 600 180]);
spec_axes.XLabel.String = 'Frequency (Hz)';
spec_axes.YLabel.String = 'Magnitude';
% 初始化一些变量
data_file_path = '';
data = [];
fs = 120;
duration = 180; % 3 minutes
n_samples = duration * fs;
t = (0:n_samples-1) / fs;
stop_visualization = true;
timer_obj = [];
% 创建定时器对象用于更新图形
function create_timer()
timer_obj = timer('ExecutionMode', 'fixedRate', 'Period', 0.1, ...
'TimerFcn', @update_visualization_callback);
end
% 选择数据文件的回调函数
function select_data_file_callback(~, ~)
[file_name, path_name] = uigetfile({'*.txt'}, 'Select Data File');
if isequal(file_name, 0)
return;
end
data_file_path = fullfile(path_name, file_name);
% 读取数据文件
data = dlmread(data_file_path);
data = data(1:n_samples, :);
% 更新波形和频谱显示
update_visualization();
end
% 开始/停止数据可视化的回调函数
function start_stop_callback(~, ~)
if stop_visualization
% 开始可视化
start(stop(timer_obj));
stop_visualization = false;
start_stop_button.Text = 'Stop';
else
% 停止可视化
stop(timer_obj);
stop_visualization = true;
start_stop_button.Text = 'Start';
end
end
% 更新图形的回调函数
function update_visualization_callback(~, ~)
update_visualization();
end
% 更新波形和频谱显示
function update_visualization()
if isempty(data)
return;
end
% 显示波形
wave_axes.XLim = [t(1) t(end)];
wave_axes.YLim = [min(min(data)) max(max(data))];
plot(wave_axes, t, data(:, 1), 'b', t, data(:, 2), 'r');
legend(wave_axes, {'Channel 1', 'Channel 2'});
% 显示频谱
spec_data = fft(data) / n_samples;
f = (0:n_samples-1) / duration;
spec_axes.XLim = [0 fs/2];
spec_axes.YLim = [0 max(max(abs(spec_data)))];
plot(spec_axes, f, abs(spec_data(:, 1)), 'b', f, abs(spec_data(:, 2)), 'r');
legend(spec_axes, {'Channel 1', 'Channel 2'});
end
% 关闭窗口时停止定时器
function close_figure_callback(~, ~)
if ~isempty(timer_obj)
stop(timer_obj);
delete(timer_obj);
end
delete(fig);
end
% 设置窗口关闭的回调函数
fig.CloseRequestFcn = @close_figure_callback;
% 创建定时器对象
create_timer();
可以参考下:
%读取文件
fid_2=fopen('rcv_data.txt', 'r'); %总共10000个
x=10000;y=4;
data_5=cell(x,y);%定义cell矩阵,存储文件内容
data_6=cell(x,y);
data_7=cell(x,1);%高16位 (16进制)
data_8=cell(x,1);%低16位 (16进制)
for i=1:x
for j=1:y
data_5{i,j}=fscanf(fid_2,'%s',[1,1]);%以字符方式读取每个值,遇空格完成每个值的读取
end
end
fclose (fid_2);
for i=1:x %交换顺序
data_6{i,1}=data_5{i,4};
data_6{i,2}=data_5{i,3};
data_6{i,3}=data_5{i,2};
data_6{i,4}=data_5{i,1};
end
for i=1:x %两个分开
data_7{i,1}=[data_6{i,1},data_6{i,2}];
data_8{i,1}=[data_6{i,3},data_6{i,4}];
end
for i=1:x %
data_7{i,1}=hex2dec(data_7{i,1});%将文本格式转为数字格式
data_8{i,1}=hex2dec(data_8{i,1});%将文本格式转为数字格式
end
data_9 = cell2mat(data_7)-8192;
data_10 = cell2mat(data_8)-8192;
%画图
t1=10:500
figure(1)
plot(t1,data_9(t1,1));
hold on
plot(t1,data_10(t1,1));
% SNR_ADC(data_9,14);
% %fft_i
Fs = 200000000 ; % 采样频率200M
N_i = length(data_9); %样点个数
fft_i = fft(data_9,N_i);
P2_i = abs(fft_i/N_i);
P1_i = P2_i(1:N_i/2+1);
P1_i(2:end-1) = 2 * P1_i(2:end-1);
dBm_i = 10 + 20 * log10( 0.5 * (P1_i/1000) );
f_i=(Fs*(0:(N_i/2))/N_i)/1000000;
%
figure(3);
%(x-1)/x*fs
plot(f_i,dBm_i);
title('信号频谱');
xlabel('f/MHz');
ylabel('功率/dBm');
%
% %fft
Fs = 200000000 ; % 采样频率200M
N_q = length(data_10); %样点个数
fft_q = fft(data_10,N_q);
P2_q = abs(fft_q/N_q);
P1_q = P2_q(1:N_q/2+1);
P1_q(2:end-1) = 2 * P1_q(2:end-1);
dBm_q = 10 + 20 * log10( 0.5 * (P1_q/1000) );
f_q=(Fs*(0:(N_q/2))/N_q)/1000000;
figure(4);
%(x-1)/x*fs
plot(f_q,dBm_q);
title('信号频谱');
xlabel('f/MHz');
ylabel('幅度');
你是需要其他老师的思路和方法还是通过邮箱拿数据,给到你结果?
首先,新建一个 MATLAB 的 GUI 项目,在命令行输入 guide,即会弹出一个窗口,选择 Blank GUI,点击 ok,弹出一个 untitled.fig 窗口,这就是你所要设计的 GUI 界面,如下图所示:
接下来,在刚刚创建的空白 GUI 界面上右击鼠标,选择 Property Inspector 选项,在新弹出的属性框中找到 Tag,这是一个句柄属性,是控件在计算机内部唯一标识符,类似于我们的身份证号,为便于代码的理解,一般情况输入有意义的字符,不要包括汉字,此处为
sine_figure;然后点击保存,命名为 sinetyq。
这样一个已命名的空白 GUI 界面就做好了。接下来,添加控件,选择 4 个 static text,4 个
edit text,排列成四行两列,双击每个控件,进入属性设置界面,此处着重注意三个地方,
FontSize、String、Tag,在 FontSize 处可设置要显示的字体大小,String 是显示的字符内容,
Tag 是这个控件在.M 文件中的名字,类似于变量名,同样也要秉持程序易于理解的原则来命名,如在频率栏,可将要输入频率的 edit text 的 Tag 设置为 frequency_input,这样便于理解。
在我们自己添加控件时,为了界面美观,常需要将各控件对齐,这时手动调节多个控件会很 费时,我们按住 ctrl 键,用鼠标选中要排列的控件,然后点击工具栏的这个按钮,选择对齐方式即可自动对齐。
现在我们右击某一个 edit text,选择 view callbacks,就会调到我们这个 GUI 界面对应的.M 文件,这个.M 文件是自动创建的,要实现的程序代码就是在各个控件对应的程序块处编写实现的。
接下来,再添加一个运行按钮,命名为 RUN,同时句柄 Tag 也为 RUN。
接下来,为窗口增加两个坐标,用来显示正弦波的时域和频域图。在左侧的工具栏处选择
Axes,拖动到空白界面上。同时为其命名为 time、spectrum。
界面布局到此就结束了,我们可以看到界面有点偏小,所以可以在界面的右下角出拉大界面 以便于较好的显示图形。
点击工具栏的运行 按钮,运行一下界面。
注意右上角的放大图标为灰色的,表明不可放大,如果要实现放大按钮,可在界面设计页面 的空白处双击鼠标,找到 resize 复选框,并选中它,即显示为 on,这样在运行一次就可最大化窗口了。
到此,界面设计完毕,接下来是为相关控件添加代码。代码如下,注意采样率一定要结合抽 样定理。还有 set 函数的 gcbo:returns the handle of the graphics object whose callback is executing.
————————————————
版权声明:本文为CSDN博主「MATLAB管家」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_59833680/article/details/119908347