SPWM source code

.PS
include(pstricks.m4)

scale=0.750

cct_init

pi = atan2(0,-1)

#Triangular Waveform
_fs=2000	 					#Switching frequency
_Ts=1/_fs						#Switching Period
_As=100
_ms=_As*2/_Ts

#Reference Signal
_Ar=45
_fr=50
_wr=2*pi*_fr

_refA=_Ar*sin(0+0)+_As/2
_refB=_Ar*sin(0-2*pi/3)+_As/2
_refC=_Ar*sin(0-4*pi/3)+_As/2

#PWM Definition	
_pwm_Hi=100
_pwm_Lo=0

_pwmA=_pwm_Hi
_pwmB=_pwm_Hi
_pwmC=_pwm_Hi

_pwmAB=_pwmA-_pwmB

_tri_offset=0
_ref_offset=0

_pwm_offsetAB=0.75*4.65

_pwm_offsetA=0.75*3
_pwm_offsetB=0.75*2
_pwm_offsetC=0.75

_num_of_cycles=40		#Number of Switching Cycles

_res=20				#Resolution
_dt=_Ts/_res			#Step size

_xscale=4/(_num_of_cycles*_Ts)	#Horizontal scaling factor
_yscale=0.5/_As

"$u_{an}$" at (0, _pwm_offsetA+_pwm_Hi/2*_yscale) rjust
"$u_{bn}$" at (0, _pwm_offsetB+_pwm_Hi/2*_yscale) rjust
"$u_{cn}$" at (0, _pwm_offsetC+_pwm_Hi/2*_yscale) rjust
"$u_{ab}$" at (0, _pwm_offsetAB+_pwm_Hi/2*_yscale) rjust

"$u_{sa}^*$" at (0, +_refA*_yscale) rjust below
"$u_{sb}^*$" at (0, +_refB*_yscale) rjust below
"$u_{sc}^*$" at (0, +_refC*_yscale) rjust below
"$u_{tri}$" at (0, _As*1.1*_yscale) rjust

for _cycle = 0 to _num_of_cycles do
{
	_tri=0
	
	_t=_cycle*_Ts
	
	for _tc = 0 to _Ts/2 by _dt do
	{
		x0=(_t+_tc)*_xscale
		x1=(_t+_tc+_dt)*_xscale
		
		_old_pwmA=_pwmA
		_old_pwmB=_pwmB
		_old_pwmC=_pwmC

		y00=_tri*_yscale+_tri_offset

		y10=_refA*_yscale+_ref_offset
		y30=_refB*_yscale+_ref_offset
		y50=_refC*_yscale+_ref_offset

		y20=_pwmA*_yscale+_pwm_offsetA
		y40=_pwmB*_yscale+_pwm_offsetB
		y60=_pwmC*_yscale+_pwm_offsetC
		
		y70=(_pwmA-_pwmB)*_yscale+_pwm_offsetAB
		
		_tri=_tri+_ms*_dt

		_refA=_Ar*sin(_wr*(_t+_tc+_dt))+_As/2
		_refB=_Ar*sin(_wr*(_t+_tc+_dt)-2*pi/3)+_As/2
		_refC=_Ar*sin(_wr*(_t+_tc+_dt)-4*pi/3)+_As/2
		
		if (_refA > _tri) then {_pwmA=_pwm_Hi} else {_pwmA=_pwm_Lo}		
		if (_refB > _tri) then {_pwmB=_pwm_Hi} else {_pwmB=_pwm_Lo}		
		if (_refC > _tri) then {_pwmC=_pwm_Hi} else {_pwmC=_pwm_Lo}		
		
		y01=_tri*_yscale+_tri_offset

		y11=_refA*_yscale+_ref_offset
		y31=_refB*_yscale+_ref_offset
		y51=_refC*_yscale+_ref_offset

		y21=_pwmA*_yscale+_pwm_offsetA
		y41=_pwmB*_yscale+_pwm_offsetB
		y61=_pwmC*_yscale+_pwm_offsetC

		y71=(_pwmA-_pwmB)*_yscale+_pwm_offsetAB

		linethick_(0.5)
		\psset{linecolor=black}
		line from (x0,y00) to (x1,y01)	
		
		\psset{linecolor=red}
		line from (x0,y10) to (x1,y11)	
		\psset{linecolor=yellow}
		line from (x0,y30) to (x1,y31)	
		\psset{linecolor=blue}
		line from (x0,y50) to (x1,y51)	

		\psset{linecolor=black}
		if ((_old_pwmA-_old_pwmB)!=(_pwmA-_pwmB)) then
		{
			line from (x0,y70) to (x1,y70) then to (x1,y71)
		} else
		{
		  line from (x0,y70) to (x1,y71)
		}
		
		if (_old_pwmA > _pwmA) then
		{
			line from (x0,y20) to (x1,y20) then to (x1,y21)
		} else
		{
			line from (x0,y20) to (x1,y21)	
		}

		if (_old_pwmB > _pwmB) then
		{
			line from (x0,y40) to (x1,y40) then to (x1,y41)
		} else
		{
			line from (x0,y40) to (x1,y41)	
		}

		if (_old_pwmC > _pwmC) then
		{
			line from (x0,y60) to (x1,y60) then to (x1,y61)
			
		  \psset{linecolor=gray}
		  linethick_(0.2)
			line dashed 0.02 from (x1,y00) to (x1,y61)
		} else
		{
			line from (x0,y60) to (x1,y61)	
		}

	}

	_t=_cycle*_Ts+_Ts/2
	
	for _tc = 0 to _Ts/2 by _dt do
	{
		x0=(_t+_tc)*_xscale
		x1=(_t+_tc+_dt)*_xscale
		
		_old_pwmA=_pwmA
		_old_pwmB=_pwmB
		_old_pwmC=_pwmC

		y00=_tri*_yscale+_tri_offset

		y10=_refA*_yscale+_ref_offset
		y30=_refB*_yscale+_ref_offset
		y50=_refC*_yscale+_ref_offset

		y20=_pwmA*_yscale+_pwm_offsetA
		y40=_pwmB*_yscale+_pwm_offsetB
		y60=_pwmC*_yscale+_pwm_offsetC
		
		y70=(_pwmA-_pwmB)*_yscale+_pwm_offsetAB
		
		_tri=_tri-_ms*_dt

		_refA=_Ar*sin(_wr*(_t+_tc+_dt))+_As/2
		_refB=_Ar*sin(_wr*(_t+_tc+_dt)-2*pi/3)+_As/2
		_refC=_Ar*sin(_wr*(_t+_tc+_dt)-4*pi/3)+_As/2
		
		if (_refA > _tri) then {_pwmA=_pwm_Hi} else {_pwmA=_pwm_Lo}		
		if (_refB > _tri) then {_pwmB=_pwm_Hi} else {_pwmB=_pwm_Lo}		
		if (_refC > _tri) then {_pwmC=_pwm_Hi} else {_pwmC=_pwm_Lo}		
		
		y01=_tri*_yscale+_tri_offset

		y11=_refA*_yscale+_ref_offset
		y31=_refB*_yscale+_ref_offset
		y51=_refC*_yscale+_ref_offset

		y21=_pwmA*_yscale+_pwm_offsetA
		y41=_pwmB*_yscale+_pwm_offsetB
		y61=_pwmC*_yscale+_pwm_offsetC

		y71=(_pwmA-_pwmB)*_yscale+_pwm_offsetAB
		
		linethick_(0.5)
		\psset{linecolor=black}
		line from (x0,y00) to (x1,y01)	

		\psset{linecolor=red}
		line from (x0,y10) to (x1,y11)	
		\psset{linecolor=yellow}
		line from (x0,y30) to (x1,y31)	
		\psset{linecolor=blue}
		line from (x0,y50) to (x1,y51)	

		\psset{linecolor=black}
		if ((_old_pwmA-_old_pwmB)!=(_pwmA-_pwmB)) then
		{
			line from (x0,y70) to (x1,y70) then to (x1,y71)
		}	else
		{
		  line from (x0,y70) to (x1,y71)
		}
		
		if (_pwmA > _old_pwmA) then
		{
			line from (x0,y20) to (x1,y20) then to (x1,y21)
		} else
		{
			line from (x0,y20) to (x1,y21)	
		}

		if (_pwmB > _old_pwmB) then
		{
			line from (x0,y40) to (x1,y40) then to (x1,y41)
		} else
		{
			line from (x0,y40) to (x1,y41)	
		}

		if (_pwmC > _old_pwmC) then
		{
			line from (x0,y60) to (x1,y60) then to (x1,y61)
			
		  \psset{linecolor=gray}
		  linethick_(0.2)
			line dashed 0.02 from (x1,y00) to (x1,y61)
		} else
		{
			line from (x0,y60) to (x1,y61)	
		}
	}
	
}
.PE