%% ============== FM 发射端程序 (98.5 MHz 版本) ============== %%
%% 参数设置 (匹配FM广播频段)
fs = 2e6; % 采样率 2 MS/s (满足 HackRF 最低要求)
fc = 98.5e6; % 载波频率 98.5 MHz (FM广播频段)
duration = 60; % 信号持续时间 60 秒
fm_freq = 15e3; % 调制频率 15 kHz
deviation = 75e3; % 频偏 75 kHz (标准FM广播参数)
%% 分块处理 (优化内存管理)
block_size = 2; % 每块 2 秒数据
num_blocks = ceil(duration / block_size);
total_samples = duration * fs;
%% 创建输出文件
filename = 'fm_signal_98.5MHz_15kHz_2MSps.raw'; % 更新文件名反映新频率
fid = fopen(filename, 'wb');
disp(['Generating FM signal - Carrier: ' num2str(fc/1e6) ' MHz, Mod: ' num2str(fm_freq/1e3) ' kHz']);
disp(['Frequency deviation: ±' num2str(deviation/1e3) ' kHz (FM广播标准)']);
disp(['Sampling rate: ' num2str(fs/1e6) ' MS/s']);
disp(['Estimated file size: ' num2str(2 * total_samples / 1e6) ' MB']);
%% 分块生成信号 (防止内存溢出)
for block = 1:num_blocks
% 当前块处理
block_start = (block - 1) * block_size;
actual_block_size = min(block_size, duration - block_start);
% 生成时间向量
t = (0:1/fs:actual_block_size - 1/fs) + block_start;
num_samples = length(t);
% 生成 15kHz 单声道音频信号 (标准FM频段)
audio_signal = sin(2*pi*fm_freq*t);
% FM 调制 (卡森带宽: 2*(75+15)=180kHz)
phi = cumsum(audio_signal) / fs * 2 * pi * deviation;
iq_signal = exp(1j * phi);
% 归一化并缩放 (匹配HackRF输入要求)
iq_signal = iq_signal / max(abs(iq_signal));
iq_signal = round(iq_signal * 127);
% 交错 I 和 Q 分量
interleaved = zeros(1, 2 * num_samples);
interleaved(1:2:end) = real(iq_signal);
interleaved(2:2:end) = imag(iq_signal);
% 写入文件
fwrite(fid, interleaved, 'int8');
% 进度显示
progress = block/num_blocks * 100;
disp(['Progress: ' num2str(progress, '%.1f') '%, Generated: ' num2str(block * block_size) 's']);
% 定期清理内存
if mod(block, 5) == 0
clear audio_signal phi iq_signal interleaved;
disp('Memory cleared to prevent overflow');
end
end
%% 关闭文件
fclose(fid);
disp(['FM broadcast signal saved as ' filename]);
%% 发射控制 (使用 HackRF)
tx_serial = '000000000000000026b468dc366e448f';
tx_cmd = sprintf('hackrf_transfer -t %s -f %d -s %d -x 30 -a 1 -d %s', ...
filename, fc, fs, tx_serial);
disp(' ');
disp('=== TX Command for 98.5 MHz Broadcast ===');
disp(tx_cmd);
disp('=========================================');
%% 接收端配置建议
rx_serial = '000000000000000017c467dc259181c3';
rx_cmd = sprintf('hackrf_transfer -r received.raw -f %d -s %d -l 24 -g 40 -b 1750000 -d %s',...
fc, fs, rx_serial);
disp('=== Recommended RX Command ===');
disp(rx_cmd);
disp('==============================');
%% 信号质量分析
samples_to_show = min(fs, 20000);
fid = fopen(filename, 'rb');
first_sec_data = fread(fid, 2 * samples_to_show, 'int8');
fclose(fid);
% 分离 I/Q 分量
i_data = first_sec_data(1:2:end);
q_data = first_sec_data(2:2:end);
iq_signal = complex(i_data, q_data);
% 频谱分析
NFFT = 4096; % 增加分辨率
[Pxx, F] = pwelch(iq_signal, hamming(NFFT), NFFT/2, NFFT, fs);
F_shift = F - fs/2; % 中心频率移至0
% 计算卡森带宽
carson_bandwidth = 2*(deviation + fm_freq);
fprintf('\n理论卡森带宽: %.1f kHz\n', carson_bandwidth/1e3);
% 可视化
figure('Name', '98.5 MHz FM Signal Analysis', 'Position', [100, 100, 800, 800]);
% 时域波形 (前1ms)
subplot(3,1,1);
t_vis = (0:length(iq_signal)-1)/fs;
plot(t_vis(1:fs/1000), real(iq_signal(1:fs/1000)));
title(['I Component - ' num2str(fc/1e6) ' MHz FM Signal']);
xlabel('Time (ms)');
xticks(0:0.1:1);
xticklabels(0:10);
ylabel('Amplitude');
grid on;
% 调制信号验证
subplot(3,1,2);
demod_audio = diff(unwrap(angle(iq_signal)) * fs / (2*pi*deviation));
plot(t_vis(1:length(demod_audio)), demod_audio);
title('Demodulated Audio Signal (15 kHz)');
xlabel('Time (s)');
ylabel('Amplitude');
xlim([0 0.002]); % 显示2ms
grid on;
% 频谱分析
subplot(3,1,3);
plot(F_shift/1e3, 10*log10(fftshift(Pxx)));
title(['Power Spectrum - ' num2str(fc/1e6) ' MHz @ ' num2str(fs/1e6) ' MS/s']);
xlabel('Frequency Offset (kHz)');
ylabel('Power (dB)');
xlim([-100, 100]); % 聚焦主瓣
hold on;
% 标记关键频率点
plot([-deviation -deviation]/1e3, ylim, 'r--');
plot([deviation deviation]/1e3, ylim, 'r--');
plot([-fm_freq -fm_freq]/1e3, ylim, 'g--');
plot([fm_freq fm_freq]/1e3, ylim, 'g--');
legend('Spectrum', '±75 kHz Deviation', '±15 kHz Modulation');
grid on;
% 计算占用带宽
power_total = bandpower(Pxx);
bw_90 = obw(Pxx, F); % 90%占用带宽
fprintf('实际占用带宽: %.1f kHz\n', bw_90/1e3);可以将这个程序进行修改,不要改变程序的整体框架,不要乱加其他程序,其中这个是一个hackrf的信号发射程序,我想实现一个hackrf发射,另一个hackrf同时接收,可以怎么修改这个是MATLAB的程序
最新发布