基于高云FPGA的FM调制与解调

一、概述

基于高云FPGA开发板自主设计支持FM调制方式的数字发射机,FM调制外部输入的音频信号,可使FM接收机正确接收并播放。

二、平台

Gowin_V1.9.8
Modelsim SE-64 2019.2
(如果用Gowin,首先要学会Gowin和Modelsim 如何进行联调;用vivado可忽略)

三、要求

(1)FM调制信号由外部音频输入;
(2)FM发射机在国家划分的FM广播频段,包含多个电台频率;
(3)调制信号通过天线发出,接收距离可达两米以上;

四、原理

FM调制的结构如下图所示:在这里插入图片描述
  调制信号是用DDS产生正弦信号来模拟实现的。DDS的实现需要用到ROM IP核,在配置ROM IP核之前需要用Matlab生成IP核所需要的.mi文件。
  在FM调制中,有两个比较重要的概念:中心频率和频偏。中心频率可以理解为只有“Freq”时的频率;频偏可以理解为当再加上一个变量后,输出频率大小与中心频率的差值。因此FM调制的关键就在于如何确定“Freq”这个常量后面再加上的这个变量的值。
  假设中心频率为:5M,频偏为:-75KHz ~ 75KHz。当输入调制信号幅度为0时,输出的FM已调信号频率为5MHz,即载波频率;当输入调制信号幅度最大(即+211)时,输出的FM已调信号频率为5.075MHz(5M+75K);当输入调制信号幅度最小(即-211)时,输出的FM已调信号频率为4.925MHz(5M-75K)。根据以上情况,可以通过调制信号的大小计算出此时输出频率的大小。总结如下表:
在这里插入图片描述

五、调试过程

1、FM调制

  (1)首先,通过MATLAB生产.mi文件,.mi文件里是一个正弦波的采样:
在这里插入图片描述

  (2)Gowin_pROM ip核调用.mi文件生成一个5k HZ、12位的正弦调制波。(通过rom_addr地址的长度控制频率)
在这里插入图片描述
  (3)通过调制波幅度控制载波频率;生成中心频率为500k HZ,频偏为:-15k Hz ~ 15k Hz的已调信号。(根据调制波幅度修改rom_addr地址的长度)
在这里插入图片描述

  (4)最后截取已调信号的高8位作为输出。

2、FM解调

  (1)首先对FM已调波进行微分,将调制信号与载波的频率关系转换为幅度关系;

  (2)再进行FIR低通滤波,得到滤波信号。(可能是截止频率计算得有问题,信号不平滑)
在这里插入图片描述
  (3)由于滤波后的信号不平滑,故增加一个均值滤波算法。
在这里插入图片描述

六、程序

(1)生成.mi文件

x = linspace(0,6.28,4096); %在0和2pi间取1024个点
y1 = sin(x)+1;
y1 = round(y1 * 2047);
fid = fopen('sine.mi','wt'); % 生成.mi文件
fprintf(fid,'#File_format=Hex\n');
fprintf(fid,'#Address_depth=4096\n');
fprintf(fid,'#Data_width=12\n');
fprintf(fid,'%03x\n',y1);  % 生成三位数据,不足的在前面补零
fclose(fid);

(2)主程序


module FM_mod(
  input clk,
  input rst_n,
  output wire [11:0] Data_in_carry,
  output wire [11:0] Data_in_modulate,
  output wire [7:0] Data_out,
  output wire clk_out_DA,
  output wire [11:0]data_out2,
  output wire [11:0]demolate_final,

  output wire  wr_en_data_i,
  output wire  wr_en_coeffi_i,
  output wire [15:0] din_coeffi_i,
  output wire  input_rdy,
  output reg  [4:0]cnt,
  output wire  done,
  output wire [53:0]demolate_final_out
);
wire  clk_200M;
assign Data_out[7:0] = Data_in_carry[11:4];
assign clk_out_DA = clk_200M ;
reg [11:0] rom_addr_carry;
reg [11:0] rom_addr_modulate;

//倍频
    Gowin_rPLL your_instance_name_1(
        .clkout(clk_200M), //output clkout
        .clkin(clk) //input clkin
    );

//分频5M
reg [3:0] counter;
reg clk_5M;
  always@(
  • 8
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值