clear all;
close all;
clc;
%% 基本参数设置
M = 100; % 码元数量
L = 100; % 每码元采样点数
fs = 2000; % 模拟信号采样频率 (Hz)
Rb = 1000; % 数字信号码元速率 (bps)
Ts_digital = 1/Rb; % 数字码元间隔
dt = Ts_digital/L; % 系统采样间隔
% 载波参数
fc = 2000; % 载波频率 2kHz
% 信道参数
SNR_dB = 15; % 信噪比 (dB)
%% 1. 生成两路模拟信号
% 计算模拟信号时间向量
TotalT_analog = M * Ts_digital; % 模拟信号总时长
t_analog = 0:1/fs:TotalT_analog-1/fs; % 模拟信号时间向量
% 第一路信号: 正弦波 + 噪声
f1 = 50; % 信号频率 50Hz
signal1 = 0.8*sin(2*pi*f1*t_analog)
% 第二路信号: 方波
f2 = 40; % 信号频率 20Hz
signal2 = 0.5*square(2*pi*f2*t_analog, 40)
% 多路信号波形
figure('Name', '多路信源波形', 'NumberTitle', 'off');
subplot(2,1,1);
plot(t_analog, signal1, 'b', 'LineWidth', 1.5);
title('第一路模拟信号 (正弦波)');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
axis tight;
subplot(2,1,2);
plot(t_analog, signal2, 'r', 'LineWidth', 1.5);
title('第二路模拟信号 (方波)');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
axis tight;
%% 2. PCM编码 (8位)
% 采样模拟信号
sample_indices = round(linspace(1, length(t_analog), M));
sampled_signal1 = signal1(sample_indices);
sampled_signal2 = signal2(sample_indices);
% 归一化到0-255范围 (8位)
normalized1 = floor((sampled_signal1 + 1) * 127.5);
normalized2 = floor((sampled_signal2 + 1) * 127.5);
% 确保值在0-255范围内
normalized1(normalized1 < 0) = 0;
normalized1(normalized1 > 255) = 255;
normalized2(normalized2 < 0) = 0;
normalized2(normalized2 > 255) = 255;
% 转换为8位二进制
pcm_signal1 = dec2bin(normalized1, 8);
pcm_signal2 = dec2bin(normalized2, 8);
% 将PCM编码转换为二进制流
binary_stream1 = [];
binary_stream2 = [];
for i = 1:size(pcm_signal1, 1)
binary_stream1 = [binary_stream1, pcm_signal1(i,:) - '0'];
end
for i = 1:size(pcm_signal2, 1)
binary_stream2 = [binary_stream2, pcm_signal2(i,:) - '0'];
end
% 显示PCM编码波形
figure('Name', 'PCM编码波形', 'NumberTitle', 'off');
subplot(2,1,1);
plot_bits = min(100, length(binary_stream1)); % 限制绘图点数
stairs(1:plot_bits, binary_stream1(1:plot_bits), 'LineWidth', 1.5);
title('第一路信号PCM编码');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
subplot(2,1,2);
plot_bits = min(100, length(binary_stream2));
stairs(1:plot_bits, binary_stream2(1:plot_bits), 'LineWidth', 1.5);
title('第二路信号PCM编码');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
%% 3. 信道编码 (汉明码 7,4)
% 汉明码编码函数
hamming_encoded1 = hamming_encode(binary_stream1);
hamming_encoded2 = hamming_encode(binary_stream2);
% 显示信道编码波形
figure('Name', '信道编码波形', 'NumberTitle', 'off');
subplot(2,1,1);
plot_bits = min(100, length(hamming_encoded1));
stairs(1:plot_bits, hamming_encoded1(1:plot_bits), 'LineWidth', 1.5);
title('第一路信号汉明码编码');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
subplot(2,1,2);
plot_bits = min(100, length(hamming_encoded2));
stairs(1:plot_bits, hamming_encoded2(1:plot_bits), 'LineWidth', 1.5);
title('第二路信号汉明码编码');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
%% 4. 时分多路复用
% 交替两路信号
multiplexed_signal = [];
min_length = min(length(hamming_encoded1), length(hamming_encoded2));
for i = 1:min_length
multiplexed_signal = [multiplexed_signal, hamming_encoded1(i), hamming_encoded2(i)];
end
% 显示复用信号
figure('Name', '信道传输波形', 'NumberTitle', 'off');
plot_bits = min(200, length(multiplexed_signal));
stairs(1:plot_bits, multiplexed_signal(1:plot_bits), 'LineWidth', 1.5);
title('时分多路复用信号');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
%% 5. 创建数字系统时间向量
total_bits = length(multiplexed_signal);
TotalT_digital = total_bits * Ts_digital; % 数字信号总时长
t_digital = 0:dt:TotalT_digital; % 数字系统时间向量
if length(t_digital) > total_bits * L
t_digital = t_digital(1:total_bits*L); % 确保时间向量长度匹配
end
%% 6. 2ASK调制
% 复制每个比特L次
baseband = repelem(multiplexed_signal, L);
% 确保baseband长度与时间向量匹配
if length(baseband) > length(t_digital)
baseband = baseband(1:length(t_digital));
elseif length(baseband) < length(t_digital)
t_digital = t_digital(1:length(baseband));
end
% 生成载波
carrier = cos(2*pi*fc*t_digital(1:length(baseband)));
% 2ASK调制
ask_signal = baseband .* carrier;
% 显示调制信号
figure('Name', '2ASK调制信号', 'NumberTitle', 'off');
subplot(2,1,1);
plot(t_digital(1:min(2000, length(ask_signal))), ask_signal(1:min(2000, length(ask_signal))), 'b', 'LineWidth', 1);
title('2ASK调制信号');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
subplot(2,1,2);
zoom_samples = min(200, length(ask_signal)); % 只显示前200个点
plot(t_digital(1:zoom_samples), ask_signal(1:zoom_samples), 'b', 'LineWidth', 1);
title('2ASK调制信号 (放大)');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
%% 7. 信道传输 (加入高斯白噪声)
noisy_signal = awgn(ask_signal, SNR_dB, 'measured');
% 显示加噪信号
figure('Name', '信道加入噪声后波形', 'NumberTitle', 'off');
subplot(2,1,1);
plot(t_digital(1:min(2000, length(noisy_signal))), noisy_signal(1:min(2000, length(noisy_signal))), 'b', 'LineWidth', 1);
title('加入高斯白噪声后的信号');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
subplot(2,1,2);
zoom_samples = min(200, length(noisy_signal));
plot(t_digital(1:zoom_samples), noisy_signal(1:zoom_samples), 'b', 'LineWidth', 1);
title('加入高斯白噪声后的信号 (放大)');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
%% 8. 接收端处理
% 带通滤波器设计
bpFilt = designfilt('bandpassfir', 'FilterOrder', 100, ...
'CutoffFrequency1', fc-500, 'CutoffFrequency2', fc+500, ...
'SampleRate', 1/dt);
% 应用带通滤波器
filtered_signal = filtfilt(bpFilt, noisy_signal);
% 显示带通滤波后的信号
figure('Name', '接收端滤波器后波形', 'NumberTitle', 'off');
subplot(2,1,1);
plot(t_digital(1:min(2000, length(filtered_signal))), filtered_signal(1:min(2000, length(filtered_signal))), 'b', 'LineWidth', 1);
title('带通滤波后的信号');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
subplot(2,1,2);
zoom_samples = min(200, length(filtered_signal));
plot(t_digital(1:zoom_samples), filtered_signal(1:zoom_samples), 'b', 'LineWidth', 1);
title('带通滤波后的信号 (放大)');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
% 相干解调
demod_signal = filtered_signal .* carrier(1:length(filtered_signal));
% 低通滤波器设计
lpFilt = designfilt('lowpassfir', 'FilterOrder', 100, ...
'PassbandFrequency', Rb/2, 'StopbandFrequency', Rb, ...
'SampleRate', 1/dt);
% 应用低通滤波器
demod_filtered = filtfilt(lpFilt, demod_signal);
% 显示解调信号
figure('Name', '解调后波形', 'NumberTitle', 'off');
subplot(3,1,1);
plot(t_digital(1:min(2000, length(demod_signal))), demod_signal(1:min(2000, length(demod_signal))), 'b', 'LineWidth', 1);
title('相干解调后的信号');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
subplot(3,1,2);
plot(t_digital(1:min(2000, length(demod_filtered))), demod_filtered(1:min(2000, length(demod_filtered))), 'r', 'LineWidth', 1.5);
title('低通滤波后的信号');
xlabel('时间 (s)');
ylabel('幅度');
grid on;
% 抽样判决
sampled_signal = demod_filtered(round(L/2):L:end);
received_bits = sampled_signal > 0.5;
% 截取与发送相同长度的比特流
if length(received_bits) > length(multiplexed_signal)
received_bits = received_bits(1:length(multiplexed_signal));
else
multiplexed_signal = multiplexed_signal(1:length(received_bits));
end
% 显示抽样判决后的信号
subplot(3,1,3);
plot_bits = min(200, length(received_bits));
stairs(1:plot_bits, received_bits(1:plot_bits), 'm', 'LineWidth', 1.5);
title('抽样判决后的数字信号');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
%% 9. 分路
received_signal1 = received_bits(1:2:end);
received_signal2 = received_bits(2:2:end);
% 确保长度匹配
min_length = min(length(received_signal1), length(hamming_encoded1));
received_signal1 = received_signal1(1:min_length);
hamming_encoded1 = hamming_encoded1(1:min_length);
min_length = min(length(received_signal2), length(hamming_encoded2));
received_signal2 = received_signal2(1:min_length);
hamming_encoded2 = hamming_encoded2(1:min_length);
% 显示分路信号
figure('Name', '多路信源解调波形', 'NumberTitle', 'off');
subplot(2,1,1);
plot_bits = min(100, length(received_signal1));
stairs(1:plot_bits, received_signal1(1:plot_bits), 'b', 'LineWidth', 1.5);
title('第一路解调信号');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
subplot(2,1,2);
plot_bits = min(100, length(received_signal2));
stairs(1:plot_bits, received_signal2(1:plot_bits), 'r', 'LineWidth', 1.5);
title('第二路解调信号');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
%% 10. 信道译码 (汉明码 7,4)
decoded_signal1 = hamming_decode(received_signal1);
decoded_signal2 = hamming_decode(received_signal2);
% 确保长度匹配
min_length = min(length(decoded_signal1), length(binary_stream1));
decoded_signal1 = decoded_signal1(1:min_length);
binary_stream1 = binary_stream1(1:min_length);
min_length = min(length(decoded_signal2), length(binary_stream2));
decoded_signal2 = decoded_signal2(1:min_length);
binary_stream2 = binary_stream2(1:min_length);
% 显示信道译码波形
figure('Name', '信道译码波形', 'NumberTitle', 'off');
subplot(2,1,1);
plot_bits = min(100, length(decoded_signal1));
stairs(1:plot_bits, decoded_signal1(1:plot_bits), 'b', 'LineWidth', 1.5);
title('第一路汉明码译码');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
subplot(2,1,2);
plot_bits = min(100, length(decoded_signal2));
stairs(1:plot_bits, decoded_signal2(1:plot_bits), 'r', 'LineWidth', 1.5);
title('第二路汉明码译码');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
grid on;
%% 11. PCM译码
% 将二进制流转换为十进制
decoded_bytes1 = reshape(decoded_signal1(1:floor(length(decoded_signal1)/8)*8), 8, [])';
decoded_bytes2 = reshape(decoded_signal2(1:floor(length(decoded_signal2)/8)*8), 8, [])';
digital_values1 = bin2dec(char(decoded_bytes1 + '0'));
digital_values2 = bin2dec(char(decoded_bytes2 + '0'));
% 转换为模拟信号
recovered_signal1 = (digital_values1 / 127.5) - 1;
recovered_signal2 = (digital_values2 / 127.5) - 1;
% 插值恢复连续信号
recovery_time = (0:length(recovered_signal1)-1) * Ts_digital;
continuous_time = t_analog;
interp_signal1 = interp1(recovery_time, recovered_signal1, continuous_time, 'spline');
interp_signal2 = interp1(recovery_time, recovered_signal2, continuous_time, 'spline');
% 显示恢复信号
figure('Name', 'PCM译码波形', 'NumberTitle', 'off');
subplot(2,1,1);
plot(continuous_time, interp_signal1, 'b', 'LineWidth', 1.5);
hold on;
stem(recovery_time, recovered_signal1, 'r', 'filled');
title('第一路信号PCM译码恢复');
xlabel('时间 (s)');
ylabel('幅度');
legend('恢复信号', '采样点');
grid on;
axis tight;
subplot(2,1,2);
plot(continuous_time, interp_signal2, 'b', 'LineWidth', 1.5);
hold on;
stem(recovery_time, recovered_signal2, 'r', 'filled');
title('第二路信号PCM译码恢复');
xlabel('时间 (s)');
ylabel('幅度');
legend('恢复信号', '采样点');
grid on;
axis tight;
%% 12. 误码率分析
% 计算原始信号与接收信号的比特差异
original_bits = [multiplexed_signal];
if length(original_bits) > length(received_bits)
original_bits = original_bits(1:length(received_bits));
else
received_bits = received_bits(1:length(original_bits));
end
% 计算误码率
bit_errors = sum(original_bits ~= received_bits);
total_bits = length(original_bits);
bit_error_rate = bit_errors / total_bits;
% 计算信道编码前后的误码率
original_data = [binary_stream1, binary_stream2];
received_data = [decoded_signal1(1:length(binary_stream1)), decoded_signal2(1:length(binary_stream2))];
if length(original_data) > length(received_data)
original_data = original_data(1:length(received_data));
else
received_data = received_data(1:length(original_data));
end
data_errors = sum(original_data ~= received_data);
data_error_rate = data_errors / length(original_data);
% 显示结果
fprintf('通信系统性能分析:\n');
fprintf('总传输比特数: %d\n', total_bits);
fprintf('信道编码前误码数: %d\n', data_errors);
fprintf('信道编码前误码率: %.4f\n', data_error_rate);
fprintf('信道编码后误码数: %d\n', bit_errors);
fprintf('信道编码后误码率: %.4f\n', bit_error_rate);
fprintf('信道编码纠错能力: %.2f%%\n', (data_errors - bit_errors)/max(1,data_errors)*100);
% 显示误码位置
figure('Name', '误码分析', 'NumberTitle', 'off');
subplot(2,1,1);
plot_bits = min(200, length(original_bits));
stem(1:plot_bits, original_bits(1:plot_bits), 'b', 'filled');
hold on;
error_positions = find(original_bits(1:plot_bits) ~= received_bits(1:plot_bits));
stem(error_positions, original_bits(error_positions), 'r', 'filled');
title('原始发送比特流 (红色为误码位置)');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
legend('正确比特', '错误比特');
grid on;
subplot(2,1,2);
stem(1:plot_bits, received_bits(1:plot_bits), 'g', 'filled');
hold on;
stem(error_positions, received_bits(error_positions), 'r', 'filled');
title('接收比特流 (红色为误码位置)');
xlabel('比特位置');
ylabel('比特值');
ylim([-0.1 1.1]);
legend('接收比特', '错误比特');
grid on;
%% 汉明码编码函数
function encoded = hamming_encode(data)
% (7,4)汉明码编码
encoded = [];
for i = 1:4:length(data)
% 获取4位数据
start_idx = i;
end_idx = min(i+3, length(data));
block = data(start_idx:end_idx);
% 如果不足4位,补零
if length(block) < 4
block = [block, zeros(1, 4-length(block))];
end
% 计算校验位
p1 = mod(block(1) + block(2) + block(3), 2);
p2 = mod(block(1) + block(3) + block(4), 2);
p3 = mod(block(2) + block(3) + block(4), 2);
% 组合为7位码字
encoded = [encoded, block(1), block(2), block(3), block(4), p1, p2, p3];
end
end
%% 汉明码解码函数
function decoded = hamming_decode(data)
% (7,4)汉明码解码
decoded = [];
for i = 1:7:length(data)
% 获取7位码字
start_idx = i;
end_idx = min(i+6, length(data));
block = data(start_idx:end_idx);
% 如果不足7位,补零
if length(block) < 7
block = [block, zeros(1, 7-length(block))];
end
% 提取数据和校验位
d1 = block(1);
d2 = block(2);
d3 = block(3);
d4 = block(4);
p1 = block(5);
p2 = block(6);
p3 = block(7);
% 计算校验子
s1 = mod(p1 + d1 + d2 + d3, 2);
s2 = mod(p2 + d1 + d3 + d4, 2);
s3 = mod(p3 + d2 + d3 + d4, 2);
% 错误定位和纠正
error_pos = s1*1 + s2*2 + s3*4;
if error_pos > 0 && error_pos <= 7
% 纠正错误
block(error_pos) = mod(block(error_pos) + 1, 2);
end
% 提取原始数据
decoded = [decoded, block(1:min(4, end_idx-start_idx+1))];
end
end上述代码PCM译码恢复质量差,进行优化,给出优化后完整代码