MFSK调制与相干解调-MATLAB基带仿真
MFSK调制原理
发送信号形式:(等概)
s 1 = ( E , 0 , … , 0 ) s_{1}=(\sqrt{\mathcal{E}}, 0, \ldots, 0) s1=(E ,0,…,0)
s 2 = ( 0 , E , … , 0 ) s_{2}=(0, \sqrt{\mathcal{E}}, \ldots, 0) s2=(0,E ,…,0)
⋮ \vdots ⋮
s M = ( 0 , … , 0 , E ) s_{M}=(0, \ldots, 0, \sqrt{\mathcal{E}}) sM=(0,…,0,E )
其中 M M M为调制阶数, E \mathcal{E} E为符号能量,即每一个发送符号都是 M M M维向量。
M = 2 M=2 M=2时,就是我们常见的BFSK(2FSK)。
简单理解一下哈,频带中调制到的不同频率之间应该是互不影响的,那么在基带上应体现为各个发送信号之间是相互正交的。
因此在下面的仿真中,实际上采用的方法是利用二进制转十进制,把 log 2 M \log_2M log2M个比特映射为一个发送符号。这里如果不仿真误比特率,或者原始发送数据没别的用的话,在仿真中可以考虑直接给出用户的发送符号,写一个随机数表示调制位置,该位置置1,其余置0就可以了,解调同理,省去了进位制转换的麻烦,有兴趣的同学可以试一下~
特别注意:由于仿真语言不同,MATLAB的向量从1开始,因此二进制转十进制表示调制位置的值要加1。Python或者C则不用考虑这一问题。
相干解调:
m ^ = arg max 1 ≤ m ≤ M r ⋅ s m \hat{m}=\underset{1 \leq m \leq M}{\arg \max} \text{ }{\boldsymbol{r} \cdot \boldsymbol{s}_{m}} m^=1≤m≤Margmaxr⋅sm
MFSK理论误码率:
P e = 1 2 π ∫ − ∞ ∞ [ 1 − ( 1 − Q ( x ) ) M − 1 ] e − ( x − 2 E N 0 ) 2 2 d x P_{e}=\frac{1}{\sqrt{2 \pi}} \int_{-\infty}^{\infty}\left[1-(1-Q(x))^{M-1}\right] e^{-\frac{(x-\sqrt{\frac{2 \mathcal{E}}{N_{0}}})^{2}}{2}} d x Pe=2π 1∫−∞∞[1−(1−Q(x))M−1]e−2(x−N02E )2dx
需要理论推导误码率的同学详情参考《通信原理》、《数字通信》等相关教材,可以私信博主。
仿真结果图
可以看到,当 M M M增大时,系统可靠性是提升的,实际上这是一种典型的“带宽换性能”。
关于2FSK在衰落信道下的情况,请移步:
2FSK在瑞利衰落信道下的相干解调与非相干解调-MATLAB基带仿真
MATLAB仿真程序
clcclearclose all% Title: MFSK的调制与相干解调实现V1.2 %% Data: .08.21 %% Author: K.X.SongM = 4; % 此处修改M值k = log2(M);L = k*100000;% 蒙特卡洛仿真次数,此处*k是保证L/k为整数data = round(rand(1,L)); % 生成长度为L的仿真数据send = zeros(M,L/k); % 预置调制后的发送数据,每列为一个符号,行表示M维信号。mod_nonzero_place = zeros(1,L/k); % 预置调制中的非零位置demod_nonzero_place = zeros(1,L/k);% 预置解调中的非零位置% 调制for q = 1:L/kmod_nonzero_place(q) = bin2dec(num2str(data(k*q-k+1:k*q))); % 第k*q-k+1位到第k*q位的二进制数据转成字符串后换为十进制数send(mod_nonzero_place(q)+1,q) = 1; % 十进制数+1为非零位置end% 设置信噪比EbN0_dB = 0:12;EbN0 = 10.^(EbN0_dB/10);Eb = 1/k;N0 = Eb ./ EbN0;error = zeros(1,length(EbN0_dB));ser = zeros(1,length(EbN0_dB));tser = zeros(1,length(EbN0_dB));for q = 1:length(EbN0_dB)noise = sqrt(N0(q)/2) * randn(M,L/k); % 设置噪声receive = send + noise; % 通过AWGN信道后接收信号for w = 1:L/kdemod_nonzero_place = find(receive(:,w) == max(receive(:,w))) - 1;% 减1是为了与调制非零位置对应% 统计错误数if (mod_nonzero_place(w) ~= demod_nonzero_place)error(q) = error(q) + 1;endendser(q) = error(q) / (L/k);% MFSK相干解调理论误码率ac = @(x)(1-(1-erfc(x/sqrt(2))/2).^(M-1)).*exp((-(x-sqrt(2*k*EbN0(q))).^2)/2); tser(q) = (1/sqrt(2*pi)).*integral(ac,-inf,inf);end% 画图semilogy(EbN0_dB,ser,'o',EbN0_dB,tser,'b');grid on;xlabel('Eb/N0 (dB)');ylabel('SER');legend('MFSK相干解调仿真误码率','MFSK相干解调理论误码率');axis([0 12 10^-5 10^-1]);