# Quadrature Amplitude Modulation (4-QAM)

			
clear; clc;
close all;

N = 4096; % input data stream length
Fs = 8.192e7; % sample rate
Mc = 211; % carrier bin

Mm = 157; % message bin

phi = pi/8; % IQ phase error (shows up as lower side-band)
D = 0.05; % IQ amplitude error (shows up as carrier leakage)

[t, fc, c] = f_cos(1.0, N/2, Mc, Fs); % carrier vector is N/2 length
fprintf('carrier freq, fc = %1.3e\n', fc);

[t, fm, m] = f_cos(1.0, N/2, Mm, Fs); % carrier vector is N/2 length
fprintf('message freq, fm = %1.3e\n', fm);

[f, cf] = f_fft(N/2, Fs, c);
cf = mag2db(cf);
cf = cf - max(cf);

% random input binary data stream consisting of 1(0) and 2(1)
in = randi([1 2], N, 1);

[ampl, phase] = f_4QAM(in);

I = zeros(N/2:1);
Q = zeros(N/2:1);
for i = 1:N/2
I(i) = ampl(i) * cos(fm*t(i) + phase(i)+ phi) + D;
Q(i) = ampl(i) * sin(fm*t(i) + phase(i));
end

y = zeros(N/2:1);
for i = 1:N/2
y(i) = I(i) * cos(2*pi*fc*t(i)) - Q(i) * sin(2*pi*fc*t(i)); % modulated
end

[f, yf] = f_fft(N/2, Fs, y);
yf = mag2db(yf);
yf = yf - max(yf);

figure; % plot carrier
subplot(2,1,1);
stairs(t,c);
xlabel('time');
ylabel('amplitude');
title('carrier');
axis([0, 5e-6, -1, 1]);

subplot(2,1,2);
stairs(f, cf);
xlabel('freq');
ylabel('magnitude');
title('carrier FFT');
grid on;

figure; % plot I/Q
subplot(2,1,1);
stairs(t, I);
xlabel('time');
ylabel('amplitude');
title('I');
axis([0, 5e-6, -1, 1]);

subplot(2,1,2);
stairs(t, Q);
xlabel('time');
ylabel('amplitude');
title('Q');
axis([0, 5e-6, -1, 1]);

figure; % plot IQ modulated
subplot(2,1,1);
stairs(t, y);
xlabel('time');
ylabel('amplitude');
title('IQ modulated');
axis([0, 5e-6, -1, 1]);

subplot(2,1,2);
stairs(f, yf);
xlabel('freq');
ylabel('magnitude');
title('IQ modulated FFT');
grid on;


			
function [ampl, phase] = f_4QAM( in )
% f_4QAM Return IQ vectors for input stream

% f_4QAM generate amplitude & phase pairs from input data
% in = input data

n = length(in);

% init amplitude and phase array
ai = zeros(n/2:1);
pi = zeros(n/2:1);

% group input data by 2 elements and create index arrays
% having values 1 and 2 i.e. amplitude(aval) and phase(pval) index
for i = 1:n/2
ai(i) = in(2*i - 1); % odd elements to ampl
pi(i) = in(2*i); % even elements to phase
end

% 2 actual values possible of phase and amplitude for 4 QAM
aval = [0.25 0.75]; % aval(1) = 0.25, aval(2) = 0.75
pval = [pi/4 3*pi/4];

% init input amplitude and phase array
ampl = zeros(n/2:1);
phase = zeros(n/2:1);

% reference index to find acutal values of amplitude and phase
% to reperesent input data
for i = 1:n/2
ampl(i) = aval(ai(i)); % amplitude
phase(i) = pval(pi(i)); % phase
end

end


function [t, fi, x] = f_cos(A, N, M, fs)
% create sine signal from sampling parameters

% usage f_sine(0.5, 1000, 4, 5e6)

%     A = amplitude
%     N = number of samples
%     M = number of cycles/bin
%     fs = sampling rate

%     t = time vector
%     x = cos wave

fi = (fs/N) * M; % frequency of interest
t = (0 : N-1)/fs;
x = A * cos(2*pi*fi*t);

end


function [f, xf ] = f_fft(N, Fs, x)

% single-sided fft
% usage f_fft(1024, 1.024e3, 4)

%    N = number of samples
%    Fs = sampling rate
%    M = number of cycles/bin

f = Fs/2 * linspace(0, 1, N/2+1); % frequency vector

xf = fft(x,N)/N;
xf = 2 * abs (xf(1: N/2 +1)); % single sided magnitude

end


>>
carrier freq, fc = 8.440e+06
message freq, fm = 6.280e+06



## References:

1. National Instruments: Sources of Error in IQ Based RF Signal Generation
2. RF Cafe: Quadrature modulators
© 2021 Copyright. For individual use only. No liability is accepted for any consequences of using information on Testips.com.