你当前的代码是基于 `AWGN Channel` 模块设置 `Eb/No` 参数,现在你要改为使用 **Rician SISO 信道**,并控制其 **Maximum Doppler Shift** 参数。Simulink 中的 `Rician SISO Channel` 模块支持动态设置 `Maximum Doppler shift`。
---
### ✅ 修改说明:
1. **模块名称和路径**:
- 原来的 `AWGN Channel` 改为 `Rician SISO Channel`。
- 确保模块名称在模型中是准确的,例如:`Rician SISO Channel`。
2. **参数名称**:
- `EbNo` 改为 `'Maximum Doppler shift'`。
- 设置值为 `Hz` 单位(如 0~200 Hz)。
3. **BER 数据提取方式保持不变**,前提是模型中 BER 数据仍输出到基础工作区。
---
### ✅ 修改后的完整代码如下:
```matlab
% -------------------------------------------------------------------------
% 1. 模型基础配置(根据实际路径调整)
% -------------------------------------------------------------------------
model_names = {'commdvbt_no_codec_1', 'commdvbt_no_codec_64qam'}; % 两个模型名称
model_dir = fullfile('E:', 'fangzhen'); % 模型所在目录
% 检查模型文件路径
model_paths = cell(1, 2);
for k = 1:2
model_paths{k} = fullfile(model_dir, [model_names{k} '.slx']);
if ~exist(model_paths{k}, 'file')
error('模型文件不存在,请检查路径:%s', model_paths{k});
end
end
% -------------------------------------------------------------------------
% 2. 加载模型(加载两个模型)
% -------------------------------------------------------------------------
for k = 1:2
try
load_system(model_names{k});
disp(['模型加载成功:' model_names{k}]);
catch err
error('模型加载失败:%s', err.message);
end
end
% -------------------------------------------------------------------------
% 3. 定义 Maximum Doppler Shift 遍历范围(单位:Hz)
% -------------------------------------------------------------------------
doppler_start = 0; % 起始 Doppler 频移
doppler_end = 200; % 终止 Doppler 频移
doppler_step = 20; % 步长
doppler_values = doppler_start:doppler_step:doppler_end;
num_runs = length(doppler_values);
% -------------------------------------------------------------------------
% 4. 初始化结果数组(两个模型的结果)
% -------------------------------------------------------------------------
ber_results1 = zeros(1, num_runs); % 模型1的结果
ber_results2 = zeros(1, num_runs); % 模型2的结果
% -------------------------------------------------------------------------
% 5. 循环遍历每个 Doppler Shift 值,运行两个仿真并提取 BER
% -------------------------------------------------------------------------
disp('------------------- 开始遍历 Doppler Shift 值 -------------------');
for i = 1:num_runs
current_doppler = doppler_values(i);
% ========================= 运行第一个模型 =========================
% 设置模型1的 Rician SISO Channel
rician_block_path1 = [model_names{1} '/Rician SISO Channel'];
set_param(rician_block_path1, 'Maximum Doppler shift', num2str(current_doppler));
% 运行模型1
sim(model_names{1});
% 提取模型1的BER数据(假设输出变量名为BER_data1)
if ~exist('BER_data1', 'var')
error('基础工作区中不存在BER_data1变量');
end
ber_data1 = evalin('base', 'BER_data1');
if isa(ber_data1, 'timeseries')
ber_data1 = ber_data1.Data;
end
% 提取稳态BER(取最后一行第一列)
steady_ber1 = ber_data1(end, 1);
ber_results1(i) = steady_ber1;
fprintf('[模型1] Max Doppler = %.1f Hz -> BER = %.6f\n', current_doppler, steady_ber1);
% ========================= 运行第二个模型 =========================
% 设置模型2的 Rician SISO Channel
rician_block_path2 = [model_names{2} '/Rician SISO Channel'];
set_param(rician_block_path2, 'Maximum Doppler shift', num2str(current_doppler));
% 运行模型2
sim(model_names{2});
% 提取模型2的BER数据(假设输出变量名为BER_data2)
if ~exist('BER_data2', 'var')
error('基础工作区中不存在BER_data2变量');
end
ber_data2 = evalin('base', 'BER_data2');
if isa(ber_data2, 'timeseries')
ber_data2 = ber_data2.Data;
end
% 提取稳态BER(取最后一行第一列)
steady_ber2 = ber_data2(end, 1);
ber_results2(i) = steady_ber2;
fprintf('[模型2] Max Doppler = %.1f Hz -> BER = %.6f\n\n', current_doppler, steady_ber2);
end
% -------------------------------------------------------------------------
% 6. 绘制两条BER曲线(同一张图)
% -------------------------------------------------------------------------
disp('------------------- 绘制性能对比曲线 -------------------');
figure('Name', 'BER性能对比', 'Position', [100 100 900 600]);
semilogy(doppler_values, ber_results1, 'bo-', 'LineWidth', 1.5, 'MarkerSize', 8, 'MarkerFaceColor', 'b');
hold on; % 保持图形
semilogy(doppler_values, ber_results2, 'rs--', 'LineWidth', 1.5, 'MarkerSize', 8, 'MarkerFaceColor', 'r');
% 图形标注
xlabel('Maximum Doppler Shift (Hz)', 'FontSize', 12);
ylabel('Bit Error Rate (BER)', 'FontSize', 12);
title('QPSK-OFDM和64QAM-OFDM系统在Rician信道下的BER性能对比', 'FontSize', 14, 'FontWeight', 'bold');
grid on;
legend('QPSK-OFDM','64QAM-OFDM', 'Location', 'best', 'FontSize', 10);
set(gca, 'FontSize', 10, 'YMinorGrid', 'on');
hold off; % 释放图形
% -------------------------------------------------------------------------
% 7. 关闭模型(可选)
% -------------------------------------------------------------------------
for k = 1:2
close_system(model_names{k}, 0); % 不保存更改
end
disp('所有模型已关闭');
```
---
### ✅ 注意事项:
- 确保你的模型中确实存在名为 `Rician SISO Channel` 的模块,路径拼接正确。
- 如果模块在子系统中,路径应写为 `'模型名/子系统名/Rician SISO Channel'`。
- 可以加入 `get_param(...)` 来验证是否设置成功,例如:
```matlab
actual_doppler = get_param(rician_block_path1, 'Maximum Doppler shift');
```
---
###