FM调制解调-matlab

        信号调制的目的是是一种波形的某些特性按照另一种波形或信号而变化的过程或处理方法。而在无线电通信中,将电磁波作为信息传输的载体,信息为待传输的基带信号,即调制信号,特点是频率较低,频带较宽且相互重叠,为了适合单一信道传输,必须进行调制。       

        调制的原因:需要将待传输的基带信号也即是调制信号加载到高频振荡信号上的过程,其实质是将基带信号搬移到高频载波上去,频谱搬移,目的是将待传输的模拟信号或数字信号变换成适合信道传输的高频信号,保证解调的正确性。

        FM调频是使载波的频率随调制信号的大小变化而变化,而振幅保持不变的调制方式。

        调频信号数学表达式:

        𝑆(t)  = Ac ∗ cos(𝜔𝑐 t + 𝜑 𝑡 )
               = Ac ∗ (cos(𝜔𝑐 t) cos (𝑘 𝑓 ∗ ∑𝑚(𝜏)) − sin(𝜔 𝑐 t)sin (𝑘 𝑓 ∗ ∑𝑚(𝜏)))
        Ac:基带振幅 ;       cos(𝜔𝑐 t):载波分量;
        cos (𝑘 𝑓 ∗ ∑𝑚(𝜏)) :实际的调制信号,I 路数据
         sin (𝑘 𝑓 ∗ ∑𝑚(𝜏)):实际的调制信号,Q 路数据
        上述公式:对实际调制的 I Q路信号进行累加,通过控制查找表,做为其相位或者地址,输出幅值,生成 I Q路,完成整体调制过程;对 调制完成的 I Q路数据累加,得到 s(t) 即为最终调制之后的信号。在中心频率下有一定的频偏,频偏受实际的 I Q路数据的影响。
        IQ 调制:将 I 路信号调制为cos(𝑘𝑓 ∗ ∑ 𝑚(𝜏))然后与载波相乘;将Q 路信号调制为sin(𝑘𝑓 ∗ ∑𝑚(𝜏))然后与载波相移 90°并取反后相乘,之后相加得到的信号就能通过天线发射。
        
        频率控制字 w 的计算方式:(fs / 2𝑁)∗ 𝑤 = 𝑓,fs 为采样率、N 为相位累加器位宽,w 为频率控制字,f 就是输出的频率。有了频率控制字就可以进行累加,然后取高位查表就能输出对应频率的载波了。
        调频灵敏度Kf :𝑘𝑓 = w / m(t) , w:最大频偏频率控制字,m(t):基带音频信号, 随着时间变化;所以 w 频率控制字也会随时间而变化;从而会导致 DDS输出的频率也会随时间变化,就相当于将音频实际的振幅信号转换成频率信息了。
        FM解调:使用非相干解调算法
        接收信号为:S(t) = Ac ∗ cos(𝜔𝑐t + 𝑘𝑓 ∗ ∑ 𝑚(𝜏))
        对信号做正交分解,然后低通滤波将载波频率分量滤除,只保留基带信号积分分量。
        
        正交:将接收到的信号分别乘以与载波相同中心频率的正余弦,得到 I Q 路数据,再经低通滤波处理后得到的数据。
        表达式:
        I(n) = S(n) ∗ cos(𝜔𝑐n)
        = A ∗ cos(𝑘𝑓 ∗ ∑ 𝑚(𝑛)) + A ∗ cos(2𝜔 𝑐 n + 𝑘 𝑓 ∗ ∑ 𝑚(𝑛))
        … LPF …(低通滤波)
        = A ∗ cos(𝑘𝑓 ∗ ∑ 𝑚(𝑛))
        Q(n) = S(n) ∗ −sin(𝜔𝑐 n)
        = A ∗ sin(𝑘𝑓 ∗ ∑ 𝑚(𝑛))

        原理: cosAcosB = 1/2(cos(A+B) + cos(A-B))

                    cosAsinB = 1/2(sin(A+B) - sin(A-B))
        传统FM解调方案:
                 
        

          m(n)序列就是最终解调结果,而求 m(n)的过程被称为鉴频。但是该方法计算量过大且占用资源,可使用改进算法,规避FM鉴频器存在的“门限效应”和反正切运算。

        

        Q(n)当前Q路采样点;I(n)当前I路采样点

       I( n-1),Q(n-1) 指上一拍I 路的值和 Q路的值

        实验思路:
        1:在16MHz采样率下,将输入的语言信号扩展至16msps,每个数据扩展 fs / fm = 1000点,再对每个点进行频偏计算,位宽16位,将75KHz的频偏 映射在 16 位的数据位宽中,通过与数据相乘就能得到数据对应的频偏值,然后进行查表得到 I 路与 Q 路数据;
        2: I 路与 Q 路乘以要调制的频率的载波,将信号调制到1MHz上,然后累加,模拟天线发射信号
        3:接收到信号后进行正交变换,由AD9361芯片完成, 进行一个低通滤波,滤掉高频信号载波信号,保留语音信号,滤波器系数通过 Filtersolution 生成,采样频率为 16MHz ,滤除 2MHz 信号;
        4:得到滤波后的 IQ 信号后,按照公式进行解调,解调完成进行降采样,也就是每 1000 个点采集出一个点;这里降采样可以作为均值滤波,也就是将累加 1000 次再除以 1000 的方式来抑制毛刺噪声。
%***************调制过程********
%读音频文件
%产生载波
%产生两个调制信号的dac I Q路调制数据
%进行正交调制
%*********************
fs = 16e6;%载波采样率 16mhz
fc = 1e6;%载波中心频率 1mhz
df = 75e3;%最大频偏 75khz
fm = 16e3;%音频采样率 16khz
%2^23 为相位累加器; fs = 16e6;32767=2^15-1 音频最大值(16位)
kf = df*(2^32/fs)/32767;%调频灵敏度 , 75k 为最大频偏
AC=1024;%幅度
%***************
%read pcm file
file = fopen('v3edu.pcm','r');%file 为文件的句柄
m = fread(file,'int16');
figure(1);
plot(m);
m_len = length(m)*fs/fm;%按照载波采样率的长度计算
%用DDS 生成载波信号 1mhz
%计算频率控制字 w  
w= fc*2^32/fs;%1mhz 载波的频率控制字
%实现载波查表的过程,生成载波的ROM
n=0:1/1024:1023/1024;
s_rom=sin(2*pi*n);
c_rom=cos(2*pi*n);
%相位累加器,读取rom,生成信号
w_r=0;
rrom_addr=0;%读查找表的地址
%zeros(1,10); 1行10个0
cw_sin=zeros(1,m_len); %定义向量的长度
cw_cos=zeros(1,m_len);
%for循环内部完成DDS操作,累加-》取高10位-》送到rom-》取出来的幅值就是1mhz频率
for i=1:m_len
    w_r = w_r + w;%相位累加
    if(w_r > 2^32)%作32位累加器的溢出判断
       w_r = w_r -2^32; 
    end
    rrom_addr=round(w_r/2^22);% /2^22 取高10位,取整,读查找表地址
    if rrom_addr==0
        rrom_addr=1;
    end
    cw_sin(i)= s_rom(rrom_addr);%寻址,得到载波
    cw_cos(i)= c_rom(rrom_addr);%寻址,得到载波
end
%测试 DDS
%plot(cw_sin(1:3000),'r');
%hold on;
%plot(cw_cos(1:3000),'b');

%对音频信号重采样,即1个点复制1下,复制1000次,升采样
m_t= zeros(1,m_len); %16mhz
for i=1:length(m)
   for j=1:fix(fs/fm) %复制1000次
        m_t((i-1)*fix(fs/fm)+j)=m(i);%同一个16k的采样点复制1000次,这样就是16M采样点
   end
end
%频率控制字:kf * m_t
%*************************
%调制  sin 和 cos 信号
w_r=0;
rrom_addr=0;%读查找表的地址
%zeros(1,10); 1行10个0
dac_i=zeros(1,m_len); %定义向量的长度
dac_q=zeros(1,m_len);
%for循环内部完成DDS操作,累加-》取高10位-》送到rom-》取出来的幅值就是1mhz频率
for i=1:m_len
    w_r = w_r + kf*m_t(i);%相位累加
    if(w_r > 2^32)%作32位累加器的溢出判断
       w_r = w_r -2^32; 
    elseif(w_r <0)
       w_r = w_r + 2^32;%负的溢出时,纠正为正数 
    end
        
    rrom_addr=round(w_r/2^22);% /2^22 取高10位
    if rrom_addr==0
        rrom_addr=1;
    end
    %得到 I Q 路数据,下一步可进行混频
    dac_q(i)= AC*s_rom(rrom_addr);%寻址,得到载波
    dac_i(i)= AC*c_rom(rrom_addr);%寻址,得到载波
end

%**********************
%正交调制
s_t= zeros(1,m_len);%s_t最终调制好的载波
for i=1:m_len
    s_t(i)=dac_i(i)*cw_cos(i)+dac_q(i)*cw_sin(i)*(-1);
end

%*******************************
%正交解调
i_data=zeros(1,m_len);
q_data=zeros(1,m_len);
for i=1:m_len
    i_data(i)=s_t(i)*cw_cos(i);
    q_data(i)=(-1)*s_t(i)*cw_sin(i);
end

% I Q 路数据进行低通滤波,把高频分量滤除
%滤波器抽头系数 taps filter
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=conv(i_data,NUM);%卷积,得到I路低频分量
adc_q=conv(q_data,NUM);
%conv会叠加上抽头系数-1个数据点,长度会改变
% FM解调
c_len=length(adc_i);%conv运算后length会改变,重新取length
cr=zeros(1,c_len);
cj=zeros(1,c_len);
for i=2:c_len% n-1=1  
    cr(i) = adc_i(i)*adc_i(i)+adc_q(i)*adc_q(i);%I(n)^2+ Q(n)^2
    cj(i) = adc_i(i-1)*adc_q(i)-adc_i(i)*adc_q(i-1); % I(n-1)*Q(n) - I(n)*Q(n-1);
end

%angle用于存储解调出的数据
angle= zeros(1,c_len);
for i=1:c_len
   if cr(i) == 0
        angle(i) = 0;
   else 
       angle(i) = (cj(i)/cr(i))*2^16;%  *2^16  位宽转换 
   end
end

%以取均值的方式完成降采样,16M -》 16K
d_len=length(angle);
sum=0;
cnt=0;
demout=zeros(1,fix(d_len*(fm/fs)));
dcnt=1;
for i=1:d_len
   sum=sum+angle(i);
   if cnt==fs/fm % 完成1000次的累加,进行平均,并且存储到demout
       demout(dcnt)=sum/cnt;
       dcnt = dcnt+1;
       cnt =0; 
       sum =0;
   end
   cnt=cnt+1;
end
figure(2);
plot(demout);

%FM解调-方法2    近似arctan求法
c_len = length(adc_i);
cr = zeros(1,c_len);
cj = zeros(1,c_len);
for i = 2:c_len
 cr(i) = adc_i(i)*adc_i(i-1) + adc_q(i)*adc_q(i-1);
 cj(i) = adc_q(i)*adc_i(i-1) - adc_i(i)*adc_q(i-1);
end
figure;
subplot(2,1,1);plot(cr(200:end-200));title('cr');
subplot(2,1,2);plot(cj(200:end-200));title('cj');
% angle = atan2(cj,cr);
pi4 = 2^16 * pi/4;
pi34 = 2^16 * pi*3/4;
cjabs = zeros(1,c_len);
angle = zeros(1,c_len);
for i = 1:c_len
 if (cr(i) == 0 && cj(i) == 0)
 angle(i) = 0;
 else
 cjabs(i) = cj(i);
 if cjabs(i) < 0
 cjabs(i) = -cjabs(i);
 end
 if cr(i) >= 0
% angle(i) = pi4 - pi4 * (cr(i) - cj_r(i))/(cr(i) + cj_r(i)); % pi4 = pi/4
angle(i) = pi4*(2^16 - 2^16 * (cr(i) - cjabs(i))/(cr(i) + cjabs(i))); 
 else
% angle(i) = pi34 - pi4 * (cr(i) + cj_r(i))/(cj_r(i) -cr(i)); %pi34 = pi *3/4
 angle(i) = pi4*(3*2^16 - 2^16 * (cr(i) + cjabs(i))/(cjabs(i) - cr(i)));
 end
 if cj(i) < 0
 angle(i) = -angle(i);
 end
 end
end
angle = fix(angle)/2^16;
figure;plot(angle);title(' angle ');

  • 11
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值