本课程学习成果预览
欢迎订阅FPGA/MATLAB/Simulink系列教程
目录
1.软件版本
vivado2019.2,matlab2022a
2.ASK调制理论简介
在《FPGA入门100例》中的31.通信案例1——基于FPGA的ASK调制信号产生中,我们初步学习了ASK调制的基本原理和FPGA实现。在本章节中,我们将进一步学习基于fpga的ASK调制解调系统的实现。我们首先学习ASK调制的FPGA实现。订阅过 《FPGA入门100例》的读者可以直接复习案例31,没有订阅过的读者,可以看本章节内容。
ASK调制的基本原理是利用载波信号的幅度变化来传递数字信息。在二进制ASK中,数据以0和1的形式表示,其中0对应于无幅度的载波信号,而1对应于一定幅度的载波信号。因此,二进制数据位被映射到不同的幅度级别上。
对于ASK调制,一个基本的数学模型可以表示为:y(t) = A(t)cos(2πfct + θ(t)),其中A(t)是时间变量,fc是载波频率,θ(t)是相位函数,通常是一个与输入数据有关的函数。
在实际应用中,ASK调制具有实现简单、抗干扰性能较好等优点。然而,ASK也存在一些缺点,如频带利用率较低、误码率较高以及对信道条件变化较为敏感等。因此,在选择使用ASK调制时需要根据具体的应用场景和信道条件进行综合考虑。
2ASK信号可表示为:
因此,从ASK调制的原理可知,其本质上是一个乘法器,将输入信号和调制载波相乘的过程。下面我们介绍如何通过FPGA来实现ASK调制过程。
综上所述,ASK调制的过程示意图如下图所示:
从图中可以看到,对于数据1,ASK调制信号为载波,而数据0,ASK调制信号为0。
3.ASK调制过程的MATLAB实现
根据ASK的原理,我们编写如下的matlab程序:
clc; % 清除命令窗口
clear; % 清除工作空间变量
close all; % 关闭所有图形窗口
warning off; % 关闭警告信息
Num = 20; % 定义比特数
bits = rand(1,Num)>=0.5; % 生成随机比特序列
f1 = 1; % 定义载波频率
t = 0:1/100:4-1/100; % 定义时间序列
% ASK
sa1 = sin(2*pi*f1*t); % 生成载波信号(对应比特1)
sa0 = 0*sin(2*pi*f1*t); % 生成零信号(对应比特0)
% 调制
ask=[]; % 初始化ASK信号
for i=1:Num
if bits(i)==1
ask=[ask sa1]; % 如果比特为1,添加sa1到ASK信号
else
ask=[ask sa0]; % 如果比特为0,添加sa0到ASK信号
end
end
figure % 创建图形窗口
subplot(311) % 创建3行1列的子图,并定位到第一个
stairs(bits,'linewidth',1) % 绘制比特序列的阶梯图
title('Message Bits'); % 设置标题
grid on % 打开网格
subplot(312) % 定位到第二个子图
plot(sa1,'r','linewidth',1) % 绘制载波信号
title('carrier'); % 设置标题
grid on % 打开网格
subplot(313) % 定位到第三个子图
plot(ask,'r','linewidth',1) % 绘制ASK调制信号
title('ASK Modulation'); % 设置标题
grid on % 打开网格
运行之后,我们可以获得如下的仿真结果:
可以看到,对于数据1部分,会得到载波数据,而对于0部分,则为0,每一个符号,对应4个载波。
4.ASK调制过程的FPGA实现
4.1 verilog程序
ASK调制程序如下:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/10/18 19:56:50
// Design Name:
// Module Name: FSK_mod
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module ASK2_mod(
input i_clk,
input i_rst,
input i_x,
output signed[15:0]o_carrier,
output signed[15:0]o_demod
);
wire[31:0]m_axis_data_tdata1;
dds_compiler_0 dds_compiler_u1(
.aclk (i_clk),
.aresetn (~i_rst),
.m_axis_data_tvalid(),
.m_axis_data_tdata(m_axis_data_tdata1),
.m_axis_phase_tvalid(),
.m_axis_phase_tdata()
);
assign o_carrier=m_axis_data_tdata1[31:16];
assign o_demod=(i_x == 1'b00)?16'd0:{o_carrier};
endmodule
其中NCO核的设置如下:
上面NCO的时钟设置为50M,输出频率为2.5M。
4.2测试程序
testbench代码如下:
`timescale 1ns / 1ps
module test_ASK2;
reg i_clk;
reg i_rst;
reg i_x;
wire signed[15:0]o_carrier;
wire signed[15:0]o_demod;
ASK2_mod uut(
.i_clk(i_clk),
.i_rst(i_rst),
.i_x(i_x),
.o_carrier(o_carrier),
.o_demod(o_demod)
);
initial
begin
i_clk = 1'b1;
i_rst = 1'b1;
#1600
i_rst = 1'b0;
end
initial
begin
i_x= 1'b0;
#1640
i_x= 1'b1;
#320
i_x= 1'b1;
#320
i_x= 1'b0;
#640
i_x= 1'b1;
#1280
i_x= 1'b0;
#640
i_x= 1'b0;
#640
i_x= 1'b1;
#1280
i_x= 1'b0;
end
always #5 i_clk=~i_clk;
endmodule
4.3整体工程与仿真
完成上面的程序之后,我们可以得到如下的文件内容:
最后,仿真测试结果如下:
从仿真结果可以看到,FPGA的ASK调制输出和MATLAB完全一致。
5.参考文献
[1]【FPGA教程案例31】通信案例1——基于FPGA的ASK调制信号产生_基于fpga的ask信号产生及测量-CSDN博客
[2]宋依青.一种新型ASK调制系统的设计与实现[J].通信技术, 2011, 44(2):3.DOI:10.3969/j.issn.1002-0802.2011.02.008.