# 数字调制的误比特率

一晃就到了2012年了，之前在通信人家园水了很长一段时间，也曾萌发把博客搬移到C114上去，毕竟那里才是通信的中心，而CSDN是计算机的圣地。但是，又一想自己写博客的目的主要还是为了自己以后能寻找到当初的思维过程，而不是过多其他什么的，就像博客的名字一样---找寻最初的美：我能循着这一篇篇过往的文章，找寻到当初那些给我带来写作冲动抑或是技术上的那一抹美丽，就心满意足了。所以，最后还是坚持在CSDN上继续下去，虽然它很多时候登不上去，虽然它闹出了密码门事件，但是看着过去的文章，竟有一种不忍割舍的情怀。

好了，言归正传，今天记录一下简单的数字调制的误比特率，首先，我们看看常见的数字调制方式的BER情况，如下图所示：

%simulation of the  QPSK
%Version 1.0 by ZXY
%data:2012.2.4

%NOTE: the reason for this simulation is that:
% 1:we know the BER for QPSK and BPSK is the same with the same value
%    of Eb/N0
% 2:we would like to do some investigation in the relation between Eb/N0 and SNR.

clear all
close all

ns = 1000; %number of data for one loop
loop = 100000; %we will simulate 10000 times to generate 'enough' errors
ebn0 = 0:1:10; %the parameter of Eb/N0
h1 = modem.pskmod('M',4,'SymbolOrder','Gray','InputType','Bit'); %to make it simple ,wo use build-in function to accomplish this task
h2 = modem.pskdemod('M',4,'SymbolOrder','Gray','OutputType','Bit');
h11 = modem.pskmod('M',4,'InputType','Bit');
h22 = modem.pskdemod('M',4,'OutputType','Bit');
tic  % start the counter of time
for i = 1:length(ebn0)  %outer loop for --each value of Eb/N0
error = 0;  % for each Eb/N0,first,set number of errors to be ZERO.
for iii=1:loop %inner loop : for each Eb/N0,we do simulation for <loop> times,ie--10000
data = randint(1,ns)'; %generate the source data
tx1 = modulate(h1,data); %modulate by using build-in function
%To simulate Rayleigh Channel
x=randn(1,ns);
y=randn(1,ns);
r=sqrt(0.5*(x.^2+y.^2));%r is a Rayleigh distribution
%tx = tx1.*r;
%------------
%Es/N0 = Eb/N0 + 10log10(k),k is the number of useful information bits
%  per symbol
%Es/N0 = snr + 10log10(m),m is the ratio between the period of symbol
%  and the sampling
%------------
%for QPSK ,we set m=1 and we know that k is 2
snr = ebn0(i) +10*log10(2);
ynoisy = awgn(tx1,snr,'measured');% for 'awgn' function,we shoule use the SNR parameter
yrx = ynoisy;%contaminated signal
zsym = demodulate(h2,yrx);%demodulate
[number_of_errors,bit_error_rate] = biterr(data,zsym);%calculate the number of errors
error = error + number_of_errors;%counter for the total errors
%if we obtain enough errors,then,we stop the inner loop
if(error>100)
break
end

end
BER(i) = error/(iii*1000);%calculate the BER

end
toc%stop time counter
EbN0_in_db=0:10;EbN0=10.^(EbN0_in_db/10);
%pe=0.5*erfc(sqrt(EbN0));%theoretical curve
theoretical_ber = berawgn(EbN0_in_db,'psk',4,'nondiff');
semilogy(EbN0_in_db,theoretical_ber,'g')
hold on;%plot
semilogy(ebn0,BER,'k*')
grid

1）为了保证足够的可靠度，我们对于每个En/N0的值都要收集到100个errors或者要仿真ns*loop=1e8个数据才停止。

2）通过仿真我们发现，所有的这些理论曲线有一个共同的基础，那就是：它们都默认采用了Gray映射的星座图。这点在matlab的berawgn()函数中有特别说明，所以当你发现自己的程序没有逻辑错误但是总是与理论曲线不吻合，就可以考虑是不是星座映射的问题了。

3）也是最重要的一点，通常的理论曲线都是BER-EbN0之间的，而我们的加噪函数往往需要的SNR的值，那么我们都需要转换，转换关系根据matlab的帮助文件里说明如下：