PM的正交解调法
1.PM的模拟调制过程
PM信号是一种相位调制信号,其携带的信息保存在其信号的相位中,通过改变载波的相位来实现基带数据的传输。
其函数表达式如下:
其中:
正交调制法公式如下:
2.PM的数字正交解调
原理:
对于I路,其中
对于Q路:
同时:
注:上式推算中使用了arctan
函数,其中arctan
的输入范围atan2
函数进行计算。
3.MATLAB仿真
仿真代码:
fs = 20000;%采样率
l = 1E3;%基带信号点数
f = 100;%基带信号
f_c = 500;%载波信号
t = 0:1/fs:(l-1)/fs;
mt = cos(2*pi*f*t);
kf = 2;
fi = pi/3;
%% IQ信号
I = cos(kf*mt + fi);
Q = sin(kf*mt + fi);
%% 调制数据
mod_data = I.*cos(2*pi*f_c*t) - Q.*sin(2*pi*f_c*t);
%% 解调
demod = atan2(Q,I);
for i = 2:1:length(demod)
if(demod(i) >= pi)
demod(i) = demod(i) - pi*2;
elseif(demod(i) <= -pi)
demod(i) = demod(i) + pi*2;
else
demod(i) = demod(i);
end
end
%% 去直流
dc_signal = sum(demod)/l;
demod0 = demod-dc_signal;
%% 保存IQ数据FPGA使用仿真
fid = fopen('PM.txt','w');
for i = 1:l
fprintf(fid,'%d %d\n',floor(I(i)* (2^13)),floor(Q(i)* (2^13)));
end
fclose(fid);
%% 绘制
figure
time = 4;
subplot(time,1,1);
plot(mt);
title('基带数据');
subplot(time,1,2);
plot(mod_data);
title('调制数据');
subplot(time,1,3);
plot(demod);
title('解调数据');
subplot(time,1,4);
plot(demod0);
title('解调数据(去直流)');
结果:
![](https://s2.loli.net/2024/10/05/LQICiaEWMK4G1e3.png)
4.FPGA解调
逻辑代码:
module pm_demod(
input clk ,
input rst ,
//解调参数
input i_valid ,
input [15:0] i_data_i ,
input [15:0] i_data_q ,
output o_rdy ,
output [15:0] o_data
);
wire pm_valid ;
wire [23:0] pm_i ;
wire [23:0] pm_q ;
wire pm_rdy ;
wire [47 : 0] m_axis_dout_tdata ;
//AM 解调
assign pm_valid = i_valid ;
assign pm_i = {{8{i_data_i[15]}},i_data_i} ;
assign pm_q = {{8{i_data_q[15]}},i_data_q} ;
cordic_translate cordic_translate (
.aclk (clk ), // input wire aclk
.s_axis_cartesian_tvalid (pm_valid ), // input wire s_axis_cartesian_tvalid
.s_axis_cartesian_tdata ({pm_i,pm_q} ), // input wire [47 : 0] s_axis_cartesian_tdata
.m_axis_dout_tvalid (pm_rdy ), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata (m_axis_dout_tdata ) // output wire [47 : 0] m_axis_dout_tdata
);
assign o_data = m_axis_dout_tdata[24 +:16];
assign o_rdy = pm_rdy;
endmodule
仿真代码:
module tb_pm_demod();
reg clk;
reg rst;
initial begin
clk <= 0;
rst <= 1;
#300
rst <= 0;
end
always #(100/2) clk <=~clk;
reg valid;
reg [15:0] din_i;
reg [15:0] din_q;
wire o_rdy ;
wire [15:0] o_data ;
pm_demod pm_demod(
.clk (clk),
.rst (rst),
.i_valid (valid),
.i_data_i (din_i),
.i_data_q (din_q),
.o_rdy (o_rdy ),
.o_data (o_data )
);
integer file_rd; //定义数据读指针
integer flag;
initial begin //打开读取和写入的文件,这里的路径要对
file_rd = $fopen("PM.txt","r");
end
reg [15:0] cnt;
always @(posedge clk)begin
if(rst)begin
din_i <= 0;
din_q <= 0;
cnt <= 0;
valid <= 0;
end
else if(cnt <= 1000)begin
valid <= 1;
flag = $fscanf(file_rd,"%d %d",din_i,din_q);
cnt <= cnt + 1;
end
else begin
$fclose(file_rd);
$stop();
end
end
endmodule
仿真结果:
![](https://s2.loli.net/2024/10/05/h2O8bpIHJdz5v6k.png)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 如何基于DeepSeek开展AI项目