Commit | Line | Data |
---|---|---|
de9186c1 AIL |
1 | function RRC_PSK_BER_SNR(rolloff, M, numSymbs) |
2 | %% Set defaults for inputs | |
3 | if nargin < 3 | |
4 | numSymbs = 1000; | |
5 | end | |
6 | if nargin < 2 | |
7 | M = 2; | |
8 | end | |
9 | if nargin < 1 | |
10 | rolloff = 0.5; | |
11 | end | |
12 | ||
13 | if isOctave() | |
14 | pkg load communications | |
15 | end | |
16 | ||
17 | %% https://www.mathworks.com/help/signal/ref/rcosdesign.html | |
18 | %% https://www.mathworks.com/help/comm/ug/pulse-shaping-using-a-raised-cosine-filter.html | |
19 | span = 6; % filter span | |
20 | sps = 4; | |
21 | ||
22 | rrcFilter = rcosdesign(rolloff, span, sps, 'sqrt'); | |
23 | ||
24 | EbN0_db = 0:0.2:10; | |
25 | EbN0 = 10 .^ (EbN0_db ./ 10); | |
26 | ||
27 | Es = 1; | |
28 | Eb = Es / log2(M); | |
29 | N0 = Eb ./ EbN0; | |
30 | ||
31 | EsN0 = EbN0 .* log2(M); | |
32 | EsN0_db = 10 .* log10(EsN0); | |
33 | ||
34 | plotlen = length(EbN0); | |
35 | ||
36 | ber = zeros(1, plotlen); | |
37 | ||
38 | data = randi([0 M - 1], numSymbs, 1); | |
39 | modData = pskmod(data, M, 0, 'gray'); | |
40 | ||
41 | txSig = upfirdn(modData, rrcFilter, sps); | |
42 | ||
43 | for i = 1:plotlen | |
44 | snr = EbN0_db(i) + 10 * log10(log2(M));% - 10 * log10(sps); % why sps? | |
45 | rxSig = awgn(txSig, snr); | |
46 | ||
47 | rxFilt = upfirdn(rxSig, rrcFilter, 1, sps); | |
48 | rxFilt = rxFilt(span + 1 : end - span); % remove filter delay | |
49 | ||
50 | demodData = pskdemod(rxFilt, M, 0, 'gray'); | |
51 | ||
52 | [bitErrors, ber(i)] = biterr(data, demodData); | |
53 | end | |
54 | ||
55 | fig1 = figure(1); | |
56 | clf; | |
57 | ||
58 | %% Plot simulated results | |
59 | semilogy(EbN0_db, ber, 'r', 'LineWidth', 2); | |
60 | hold on; | |
61 | ||
62 | %% Plot theoretical curve | |
63 | %% BPSK: bit error when noise Nr > sqrt(Eb) | |
64 | %% Pr(Nr > sqrt(Eb)) | |
65 | %% = Pr(Z > sqrt(Eb) / sqrt(N0/2)) | |
66 | %% | |
67 | %% QPSK = 2 BPSKs, one real and one imaginary, each with one bit | |
68 | %% so BER is the same as BPSK (assuming Gray code) | |
69 | if M == 2 || M == 4 | |
70 | ber_th = qfunc(sqrt(2 * EbN0)); | |
71 | semilogy(EbN0_db, ber_th, 'b', 'LineWidth', 1); | |
72 | legend('Simulated RRC', 'Discrete'); | |
73 | else | |
74 | %% Approximation: J.G. Proakis and M. Salehi, 2000, Contemporary | |
75 | %% Communication Systems using MATLAB (Equations | |
76 | %% 7.3.18 and 7.3.19), Brooks/Cole. | |
77 | ber_ap = 2 * qfunc(sqrt(EbN0 * log2(M) * 2) * sin(pi / M)) / log2(M); | |
78 | semilogy(EbN0_db, ber_ap, 'b', 'LineWidth', 1); | |
79 | legend('Simulated RRC', 'Discrete'); | |
80 | end | |
81 | ||
82 | title(strcat(num2str(M), '-PSK RRC with Gray code')); | |
83 | grid on; | |
84 | xlabel('$E_b/N_0$ (dB)'); | |
85 | ylabel('BER'); | |
86 | ||
87 | formatFigure; | |
88 | %saveas(gcf, strcat('BER_SNR_', num2str(M), 'PSK_', num2str(numSymbs), ... | |
89 | % '.svg')); | |
90 | ||
91 | %scatterplot(rxFilt); | |
92 | %eyediagram(rxFilt, sps); | |
93 | ||
94 | end |