MATLAB Examples

Contents

function modulated = qpsk_mod( msg, varargin )

A function to perform Quadrature Phase Shift Keying

     Using good form and properly vectorized code, we generate the QPSK
     sequence of the msg passed from user land.  Plots are generated to
     show the result generated from the original bits.
     modulated = QPSK_MOD( msg )  "msg" can be a row vector if you only want to modulate one
     message, or you can create a matrix... with the rows comprising the messages.  The
     result will be either a vector or a matrix of modulated signal.
     modulated = QPSK_MOD( msg, samples_per_symbol ) The user can set the number of samples
     per symbol in the final modulated carrier.
     modulated = QPSK_MOD( msg, samples_per_symbol, do_plot ) If the user wants to turn off
     the plotting, just set the third argument to 1 for on, or 0 for off.
     modulated = QPSK_MOD( msg, samples_per_symbol, do_plot, do_complex ) When I wrote this,
     the instructor wanted a real-valued QPSK as the result.  I usually work with
     complex-valued signals, so I just gave an option to provide a complex result or a
     real-valued result.
     Example :
     >> msg = [1 0 0 0 1 1 1 0 1];
     >> qpsk_mod( msg, 100 );
     ** Poof... magic plots **
     Example #2 :
     >> msg = [[1 0 0 0 1 1 1 0 1]; [0 1 0 0 1 0 1 0 1]];
     >> qpsk_mod( msg );
     ** Poof... more magic plots **

SEE ALSO : ASK_MOD, BPSK_MOD, FSK_MOD

QPSK Modulation

The math for QPSK. Even bits are multiplied by a sine, while odd bits are multiplied by a cosine.

$$m(t) = e*sin(f) + o*cos(f)$$

    narginchk( 1, 4 );

    % Some input checking : Only allow 0's and 1's.
    if ~isempty(find( msg ~= 0 & msg ~= 1, 1 ))
        error( 'Only values between 0 and 1 are supported for modulation in ASK.' );
    end

    % Check the shape of what the user gave us.  I decided to make this work on matrices of
    % bits.  So each row will be a message.
    [m,n] = size(msg);

    % We're going to oversample a bit so we can see good resolution on the
    % sine wave we will be generating for the carrier wave.
    samples_per_symbol = 100;
    if nargin >= 2
        % Allow the user to override the samples per symbol
        samples_per_symbol = varargin{1};
    end

    % Let the user turn off verbose prints/plots
    doplot = 1;
    if nargin >= 3
        doplot = varargin{2};
    end

    % Allow complex output
    docomplex = 0;
    if nargin >= 4
        docomplex = 1;
    end
Error using qpsk_mod (line 42)
Not enough input arguments.

Variable Declarations :

    % Hz : Frequency of the carrier signal.  To be precise, the actual
    % frequency is f/samples_per_symbol.  So 2Hz.
    f = 200;

    % Generate our time vector for the sine wave generation.  We're
    % creating one period, so from 0->2*pi in steps of
    % 2*pi/samples_per_symbol.  i.e. 0->2*pi in 100 steps, evenly divided.
    t = 0:2*pi/(samples_per_symbol-1):2*pi;

    % In case the original message was odd in length, we need to truncate.
    len_min = floor(n/2);

    % Repeat our time vector for the sines and cosines.
    t = repmat( t, 1, len_min );

    % Preallocate for speed... because you should.
    modulated = zeros(m, len_min*samples_per_symbol );

The actual work is done in the following lines :

    for k = 1:m
        % Grab the even bits for Q
        msg_q = msg( k, 2:2:end )*2 - 1;
        % Grab the odd bits for I
        msg_i = msg( k, 1:2:end )*2 - 1;

        % "upsample", so to speak, the message by a factor of samples_per_symbol
        % This is another way to replicate a certain bit.  In the other files, I used repmat().
        % I also mentioned rectpulse() from the comms toolbox.
        msg_i = msg_i(ones(1,samples_per_symbol), 1:len_min);
        msg_i = msg_i(:);
        msg_q = msg_q(ones(1,samples_per_symbol), 1:len_min);
        msg_q = msg_q(:);

        % Modulate the signal by the carrier just like BPSK, but on the I and Q
        % pair.
        %
        %   $m(t) = e*sin(f*t) + o*cos(f*t)$
        if ~docomplex
            modulated(k,:) = (msg_i.*(sin(f * t )') + msg_q.*(cos(f * t)'))';
        else
            modulated(k,:) = (msg_i.*(sin(f * t )') + 1i*msg_q.*(cos(f * t)')).';
        end
    end

Plot the results in a pretty display... with titles!

    if doplot == 1
        figure;             % Create a new plot figure
        for k = 1:m
            % Plot the results
            subplot( 2,1,1 );   % Create a subplot frame inside the figure with
                                % 2 horizontal plots
            if ~docomplex
                plot( modulated(k,:) );  % plot the modulated data
            else
                plotiq( modulated(k,:) );% plot the modulated data
            end

            % Set the axes limits for the y axis... cause I HATE how MATLAB does
            % this by default.
            ylim( [-1.5 1.5] );
            str = sprintf( 'QPSK Modulated Message : %d of %d', k, m );
            title( str );               % Give it a title.

            % Move to the next frame in the subplot
            subplot(2,1,2);
            plot( msg(k,:) );

            % Set the ylimit so you can see the top of the msg bits... otherwise
            % they're unviewable.
            ylim( [-0.5 1.5] );
            str = sprintf( 'Original Message Bits : Message %d of %d', k, m );
            title( str );               % Give it a title.

            if k ~= m
                fprintf( 'Press space bar or enter to move on to the next plot\n' );
                pause;
            end
        end
    end
end

function plotiq( t, str )
%PLOTIQ Plots real and imaginary parts of a signal
%   Just saving typing...
    narginchk(1,2);

    plot(real(t));
    hold on;
    plot(imag(t), 'r');
    hold off;

    if (nargin == 2)
        title(str);
    end

    legend('I', 'Q');
end