Created
August 7, 2018 20:53
-
-
Save MartinBloedorn/22fbb077dc1306b35712840fed95d214 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function [ y, r, c ] = spwm( f1, fc, varargin ) | |
%SPWM Generates sine-wave modulated bipolar PWM. | |
% Will produce the closest possible to a single period of f1. | |
% [ y, t, c ] = spwm( f1, fc, varargin ) | |
% | |
% f1 Base harmonic frequency. | |
% fc Carrier frequency. | |
% 'NSamples' [100] Samples per 1/fc period. | |
% 'Method' ['left'] 'left', 'right' or 'center'. | |
% 'ModIndex' [1] Modulation index. | |
% 'OutAmpl' [0.5] Output PWM amplitude. | |
% 'ThiPWM' [false] Enable third harmonic injection | |
% 'Unipolar' [false] Enable unipolar signal. | |
% 'Phase' [0] Phase offset (rad) | |
% | |
% y PWM Signal. | |
% r Reference sine wave used. | |
% c Carrier wave. | |
% Parse input | |
p = inputParser; | |
defltMethod = 'left'; | |
validMethod = {'left','center','right'}; | |
checkMethod = @(x) any(validatestring(x,validMethod)); | |
p.addOptional('NSamples', 100, @isnumeric); | |
p.addOptional('ModIndex', 1, @isnumeric); | |
p.addOptional('Method', defltMethod, checkMethod); | |
p.addOptional('ThiPWM', false, @islogical); | |
p.addOptional('Unipolar', false, @islogical); | |
p.addOptional('OutAmpl', 0.5, @isnumeric); | |
p.addOptional('Phase', 0, @isnumeric); | |
p.parse(varargin{:}); | |
% Get if THIPWM is enabled | |
thipwm = p.Results.ThiPWM; | |
method = p.Results.Method; | |
% Get samples per period | |
n = p.Results.NSamples; | |
% Define counter based on method | |
switch method | |
case 'left' | |
u = linspace(-1, 1, n); | |
case 'right' | |
u = linspace(1, -1, n); | |
case 'center' | |
u = linspace(1, -1, ceil(n/2 + 1)); | |
u = [linspace(u(end-1), u(2), floor(n/2 - 1)) u]; | |
otherwise | |
error('Please supply a valid method') | |
end | |
% Amounnt of carrier cycles | |
q = ceil(fc/f1); | |
% Output signal amplitude: -1/2 to 1/2 | |
k = p.Results.OutAmpl; | |
% Offset if signal is unipolar | |
o = (k)*p.Results.Unipolar; | |
% Carrier wave with unit amplitude | |
%c = (1/p.Results.ModIndex)*repmat(u, 1, q); | |
c = repmat(u, 1, q); | |
% Frequency input | |
%w = (2*pi/(q*n))*(1:(q*n)); | |
w = linspace(0, 2*pi, q*n); | |
% Reference signal, in the -1/2 to 1/2 range | |
if ~thipwm | |
r = sin(w + p.Results.Phase); | |
else | |
r = (2/sqrt(3))*(sin(w + p.Results.Phase) + (1/6)*sin(3*w)); | |
end | |
% Set reference waveform's amplitude to produce desired ModIndex | |
r = r*(p.Results.ModIndex); | |
% Use definition, but fix cases where r-c = 0, and sign = 0 | |
y = k*(sign(r-c) + (sign(r).*((r-c)==0))) + o; | |
% Update output waveforms | |
r = k*r + o; | |
c = k*c + o; | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment