PM的正交解调法

cnblogs 2024-10-06 08:09:00 阅读 71

1.PM的模拟调制过程

​PM信号是一种相位调制信号,其携带的信息保存在其信号的相位中,通过改变载波的相位来实现基带数据的传输。

其函数表达式如下:

\[s(t) = A*cos(w_c*t + K_f*m(t))

\]

其中:

\(A\):表示载波幅度。

\(m(t)\):表示基带信号。

\(w_c\):表示载波信号角度增量。

\(K_f\):是调制灵敏度。

正交调制法公式如下:

\[I(t) = cos(K_f*m(t)) \\

Q(t) = sin(K_f*m(t)) \\

s(t) = A*(I(t)*cos(w_c*t) - Q(t)*sin(w_c*t))

\]

2.PM的数字正交解调

原理:

对于I路,其中\(\varphi\)表示调制载波与解调载波的相位差:

\[\begin{array}{flalign}

I(n) & = LPF(s(n)*cos(w_c*n + \varphi)) \\

& = \frac{cos(K_f*m(n))*cos(\varphi) + sin(K_f*m(n))*sin(\varphi)}{2} \\

& = \frac{1}{2}*cos(K_f*m(n) - \varphi)

\end{array}

\]

对于Q路:

\[\begin{array}{flalign}

Q(n) & = LPF(s(n)*sin(w_c*n + \varphi)) \\

& = \frac{cos(K_f*m(n))*sin(\varphi) - sin(K_f*m(n))*cos(\varphi)}{2} \\

& = \frac{1}{2}*sin(K_f*m(n) - \varphi)

\end{array}

\]

同时:

\[\begin{array}{flalign}

&\ \frac{Q(n)}{I(n)} = \frac{sin(K_f* m(n)- \varphi)}{cos(K_f* m(n)- \varphi)} = tan(K_f* m(n) - \varphi) \\

&\ M(n) = arctan(\frac{Q(n)}{I(n)}) = K_f* m(n) - \varphi\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space

(\frac{Q(n)}{I(n)})\in (-\pi/2\space\space\space\space\pi/2)

\end{array}

\]

注:上式推算中使用了<code>arctan函数,其中arctan的输入范围\((-\pi/2\space\space\space\space\pi/2)\)。当范围超过将计算错误。所以将使用MATLAB的atan2函数进行计算。

\[M(n) = atan2(Q(n),I(n)) = K_f*m(n)- \varphi

\]

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('解调数据(去直流)');

结果:

4.FPGA解调

逻辑代码:

<code>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

仿真结果:



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。