一、理论部分

接上篇,我们继续完成题目,这次我们要做FM调制,调频(Frequency Modulation, 简称FM)是一种以调制信号的幅度变化来控制载波频率变化的调制方式。在FM调制中,载波的频率会随着调制信号的电压而改变,而其幅度保持恒定。这使得FM调制在抗干扰性、信噪比和频谱效率方面相比AM(调幅)更具优势,广泛应用于广播、无线通信、雷达等系统。

设有一载波信号:

其中,Ac是载波幅度,fc​ 是载波频率。调制信号记作 m(t),则FM调制后的信号可以表示为:

  • kf​:频率灵敏度(调频系数),单位为Hz/V;
  • Δf=kf*Am​:最大频偏,即调制信号幅度所引起的最大频率变化。
  • β=kf*Am/fm:调频指数,反映调制深度;

二、FPGA实现

以上是数学部分的推导,那么在FPGA中,如何实现FM?

本质上,调频是以调制信号幅度变化来控制载波频率变化的方式,现在我们回忆一下DDS的原理:频率字控制累加器的累加增量,从而控制向ROM波表中寻址间隔的大小,从而控制频率,频率字不变,输出频率也不变。

那么如果我们在FPGA用中利用调制信号m(t)的幅度控制载波频率字的变化,是不是就实现了FM调制?

接下来我们考虑另一个问题:如何准确的控制FM的各指标,即如何控制最大频偏?

我的思路是,根据题目要求的最大频偏,将其转换为该系统时钟对应频率字,作为调制信号的“幅值”,在这道题中,要求调制指数(1~5),调制信号频率(1kHz~5kHz),那么最大频偏就是调制指数*调制信号频率。为实现功能,先简化要求,我们在FPGA中对调制指数和调制信号频率均设置1~5 5个步进值,然后利用按键调整数值,做动态计算

initial begin
  Mf_TABLE[0] = 4'sd1;  //调制指数
  Mf_TABLE[1] = 4'sd2;  
  Mf_TABLE[2] = 4'sd3; 
  Mf_TABLE[3] = 4'sd4;  
  Mf_TABLE[4] = 4'sd5;  

  FW_TABLE[0] = 32'd85899;    //1k   //调制信号频率字
  FW_TABLE[1] = 32'd171798;   //2k
  FW_TABLE[2] = 32'd257697;   //3k
  FW_TABLE[3] = 32'd343596;   //4k
  FW_TABLE[4] = 32'd429496;   //5k
end

将计算出来的最大频偏频率字与定点数归一化的调制信号相乘,即可得到瞬时频偏频率字,该频率字将作为这一时刻的累加器增量控制DDS进行ROM寻址,把代码贴出来供大家参考:

  // ========== FM 调制 ==========

(* keep *)wire signed [35:0] fm_shift_tmp = $signed(Mf) * $signed(fw);  //计算频率字偏移mf*fm 全整数 36位

(* keep *)wire signed [31:0] fm_shift={fm_shift_tmp[35],fm_shift_tmp[30:0]};//调整频率字位宽

(* keep *)wire signed [45:0] fm_dev_tmp = $signed(fm_shift) * $signed(mod_sig); //实时偏移  Q32.0*Q1.13=Q33.13 46BIT
assign test=fm_dev_tmp;
(* keep *)wire signed [31:0] fm_dev = {{fm_dev_tmp[45]},fm_dev_tmp[43: 13]};//调整位宽


// 假设已有载波频率字 Fw(Q32,整型)
(* keep *)wire [31:0] carrier_FW = 32'd171798692;



// 总频率控制字 = 载波频率字 + 频偏
(* keep *)wire [31:0] total_FW = carrier_FW + fm_dev;

// 总频率字用于控制 NCO 或 DDS

中间涉及了许多定点数的计算,一定要仔细再仔细,不然很容易取位错误或发生溢出。

设置调制指数5,调制信号频率为5KHz,载波2MHz,我们看一下输出波形

将信号采样送进MATLAB分析,绘制时域频域波形如下:

紧接着对FM信号进行解调,看看能否能恢复波形:

答案是解调出了5KHz的信号。

接下来,准备搞硬件端的调制方式识别及解调。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐