11 FM调制与解调的仿真

调频简介

FM调制(即调频)是使载波的频率随调制信号(即原始信号,也叫基带信号)的大小变化而变化,而振幅保持不变的调制方式,其数学公式如下:

调频的主要指标

要实现频率调制(FM),就要保证基带信号与瞬时频率偏移成线性对应关系。

DDS信号发生器的补充

DDS信号发生器框图如下:

  1. 由上图可以看出DDS发生器主要由相位累加器、相位量化器、波形ROM表、 D/A 转换器构成
  • 相位累加器:宽度为N位,它按相位步进K进行累加运算,并向相位量化器输出结
  • 相位量化器:将相位累加器输出的N位相位控制字和外部输入的N位相位控制字P相加,然后在进行截断,输出M位结果到波形ROM表
  • 波形ROM表:一共存储有2^M个波形参数,它根据相位量化器输出的值从ROM中取出数据,并输出到DA转换器
  • D/A 转换器:将数字量转换为模拟量输出
  1. 相位累加器每来一个时钟就会按相位步进(K)进行一次累加运算,溢出后又从零开始进行累加,如此往复;相位累加器完成一次溢出便对应着的完成了一次波形ROM的遍历,所以相位累加器的溢出频率就是DDS信号发生器的输出频率:

DDS相位增量

使用DDS进行FM调制

FM解调

FM调制后的信号如下:

对信号做IQ分解:

matlab音频信号FM调制解调仿真

以音频信号的FM调制解调为例编写matlab仿真程序,仿真代码如下:

c 复制代码
clc;
clear;
close all;

%载波采样率,16M
Fsc = 16e6;
%载波中心频率,1M
Fc = 1e6;
%载波幅度
Ac = 1024;

%音频的采样率,16K
Fsm = 16e3;

%最大频偏,75K
dF = 75e3;

%% 音频信号加载
%读取音频文件
file= fopen('v3edu.pcm', 'r');
audio = fread(file, 'int16');
fclose(file);
%显示音频数据波形
figure(1);
plot(audio);
%计算仿真长度,以音频扩展到16M采样率后的长度为仿真长度
sim_len = length(audio) * Fsc / Fsm;

%% 将音频信号扩为16M采样
m = zeros(1, sim_len);
for i = 1:length(audio)
    for j = 1:fix(Fsc/Fsm)
        %将一个16K采样率得到的采样点复制fix(Fsc/Fsm)次(这里应该是1000次)就得到16M采样率的采样点
        m((i-1)*fix(Fsc/Fsm)+j) = audio(i);
    end
end

%% 波形ROM表
%生成波形ROM表,共1024个波形参数
n = 0:1/1024:1023/1024;
sin_rom = sin(2*pi*n);
cos_rom = cos(2*pi*n);

%% 已调信号非载波部分
%利用DDS进行FM调制的参数
dK = (2^32*dF)/Fsc;
Kf = (((2*pi)/2^32)*dK*Fsc)/(2^15-1);
Kfs = Kf/Fsc;
Kfdds = Kfs/((2*pi)/2^32);

%相位累加器
w = 0;
%生成已调信号非载波部分
dac_i = zeros(1, sim_len);
dac_q = zeros(1, sim_len);
for i = 1:sim_len
    %相位累加
    w = w + Kfdds * m(i);
    %做32位累加器的溢出判断
    w = mod(w, 2^32);
    %将相位转换为波形ROM地址(通过除以2^22来截断低22位,保留高10位)
    rrom_addr = fix(w/2^22) + 1;
    %IQ通道非载波部分
    dac_i(i) = Ac*cos_rom(rrom_addr);
    dac_q(i) = Ac*sin_rom(rrom_addr);
end
%Q路取反
dac_q = -1*dac_q;

%% 已调信号载波部分,实际工程中载波由AD9361产生
%载波相位步进,采样率16M,频率1M,相位控制字32位
k = (2^32 * Fc) / Fsc;
%相位累加器
w = 0;
%生成1M的载波信号
cos_wave = zeros(1, sim_len);
sin_wave = zeros(1, sim_len);
for i = 1:sim_len
    %相位累加
    w = w + k;
    %32位相位溢出处理
    w = mod(w, 2^32);
    %将相位转换为波形ROM地址(通过除以2^22来截断低22位,保留高10位)
    rrom_addr = fix(w/2^22) + 1;
    %载波
    cos_wave(i) = cos_rom(rrom_addr);
    sin_wave(i) = sin_rom(rrom_addr);
end

%% 正交调制输出,实际工程中载波由AD9361进行正交调制
fm = zeros(1, sim_len);
for i = 1:sim_len
    %i_ch(i)是I通道,q_ch(i)是Q通道
    fm(i) = cos_wave(i)*dac_i(i) + sin_wave(i)*dac_q(i);
end


%% 对已调信号做正交分解
%正交解调,实际工程中载波由由AD9361进行正交解调
I = zeros(1, sim_len);
Q = zeros(1, sim_len);
for i = 1:sim_len
    I(i) = fm(i)*cos_wave(i);
    Q(i) = fm(i)*sin_wave(i);
end

%% 对IQ数据进行低通滤波把高频分量滤除
%进行低通滤波
NUM = [-7.894e-05, -2.483e-04, -4.516e-04, -7.089e-04, -1.035e-03, -1.435e-03, -1.903e-03, -2.417e-03, -2.938e-03, -3.415e-03, -3.778e-03, -3.948e-03, -3.837e-03, -3.357e-03, -2.42e-03, -9.524e-04, 1.106e-03, 3.791e-03, 7.113e-03, 1.105e-02, 1.554e-02, 2.051e-02, 2.583e-02, 3.135e-02, 3.691e-02, 4.233e-02, 4.742e-02, 5.199e-02, 5.588e-02, 5.894e-02, 6.105e-02, 6.213e-02, 6.213e-02, 6.105e-02, 5.894e-02, 5.588e-02, 5.199e-02, 4.742e-02, 4.233e-02, 3.691e-02, 3.135e-02, 2.583e-02, 2.051e-02, 1.554e-02, 1.105e-02, 7.113e-03, 3.791e-03, 1.106e-03, -9.524e-04, -2.42e-03, -3.357e-03, -3.837e-03, -3.948e-03, -3.778e-03, -3.415e-03, -2.938e-03, -2.417e-03, -1.903e-03, -1.435e-03, -1.035e-03, -7.089e-04, -4.516e-04, -2.483e-04, -7.894e-05];
adc_i_lpf = conv(I, NUM);
adc_q_lpf = conv(Q, NUM);
%前面部分滤波器未收敛,将其去掉
adc_i_lpf = adc_i_lpf(32:end-32);
adc_q_lpf = adc_q_lpf(32:end-32);
%Q路取反
adc_q_lpf = -1*adc_q_lpf;

%% FM解调
denominator = zeros(1,sim_len);
numerator = zeros(1,sim_len);
fm_temp = zeros(1, sim_len);
for i = 2:sim_len
    %I(n-1)*Q(n) -I(n)*Q(n-1)
    numerator(i) = adc_i_lpf(i-1)*adc_q_lpf(i) - adc_i_lpf(i)*adc_q_lpf(i-1); 
    %I(n)^2+Q(n)^2
    denominator(i) = adc_i_lpf(i)*adc_i_lpf(i) + adc_q_lpf(i)*adc_q_lpf(i);
    %(I(n-1)*Q(n) -I(n)*Q(n-1))/(I(n)^2+Q(n)^2)
    if abs(denominator(i)) < 0.000001
        fm_temp(i) = 0;
    else
        fm_temp(i) = (numerator(i)/denominator(i))*2^16;
    end
end

%% 降采样
%采用取均值的方式来完成降采样,将采样率由16M降低到16K
sum = 0;
sum_cnt = 0;
data_cnt = 1;
fm_out = zeros(1, fix(sim_len*(Fsm/Fsc)));
for i = 1:sim_len
    sum = sum+fm_temp(i);
    sum_cnt = sum_cnt+1;
    %完成了Fsc/Fsm(这里应该是1000)次的累加进行平均并且存储到fm_out
    if(sum_cnt == fix(Fsc/Fsm))
        fm_out(data_cnt) = sum/sum_cnt;
        data_cnt = data_cnt+1;
        sum_cnt = 0;
        sum = 0;
    end
end
%显示解调结果
% figure(2);
hold on
plot(fm_out*17,'b');

仿真输出如下所示,可见解调出来的信号与原始信号基本重叠。

相关推荐
xiaojiaohuazi1 小时前
国产安陆EG4S20 FPGA实现千兆以太网TCP/IP:AD7606C 8通道1 MSPS采集、SDRAM缓存与Python上位机
tcp/ip·缓存·fpga开发
尤老师FPGA1 小时前
HDMI数据的接收发送实验(二十四)
fpga开发
MDYFPGA2 小时前
明德扬 Kintex-7 FPGA核心板及多接口扩展底板介绍
fpga开发·fpga
I'm a winner2 小时前
【源码】一文读懂 TDOA 无源时差定位原理
fpga开发
FPGA小迷弟3 小时前
FPGA复位策略深度解析:异步复位、同步释放与设计最佳实践
fpga开发·fpga
MDYFPGA3 小时前
Arria 10 10AX027 核心板适合哪些高速数据处理项目
fpga开发·fpga
Terasic友晶科技20 小时前
【教程】Agilex 5 SOC FPGA的HPS端如何响应FPGA端中断(一)——GIC控制器介绍
fpga开发·hps·agilex 5·gic控制器
芯路行者2 天前
4.4 HDLBits —— 更多时序逻辑电路
fpga开发·verilog·fpga·hdlbits
HUSTCH20212 天前
有符号数无符号数加法器逻辑
fpga开发
LCMICRO-133108477462 天前
国产长芯微LP4807完全P2P替代ADA4807,1mA、300MHz 增益带宽、电压反馈运算放大器
arm开发·嵌入式硬件·fpga开发·硬件工程·运算放大器·ada4807