Shop OBEX P1 Docs P2 Docs Learn Events
Inverted PWM using NCO mode — Parallax Forums

Inverted PWM using NCO mode

ctwardellctwardell Posts: 1,716
edited 2013-08-11 15:39 in Propeller 1
I'm working on a driver for the TI DRV8833 motor driver and it needs an inverted PWM signal when used in the "slow decay / brake" mode.

After looking at some code for doing PWM using the counter NCO mode I realized that if I could just count down instead of up I could do "inverted" PWM.

Since NCO mode adds FRQx to PHSx, setting FRQx to -1 (2^32 - 1) allows us to count down. By setting a positive PHSx value and counting down we can do inverted PWM.

This may already be a known technique, but I didn't see it anywhere so I thought I would share it.

An example using a modified version of code from the PEK is given below.

C.W.
{{
// TestInvertedPWM.spin
// Modified version of TestDualPWM.spin
// PEK Manual v1.2 page 164
// Used to demonstrate inverted PWM using counter NCO mode using the LED's
// on a QuickStart board.
//
// The NCO mode outputs that value of phsx[31] on the selected output pin.
//
// "Normal" PWM usage is to set frqx = 1 and load phsx with the negative of the
// desired PWM count.  This sets the output pin high until phsx is incremented to 0
// resulting in phsx[31] going low which sets the output pin low.
//
// "Inverted" PWM usage is to set frqx = -1 and load phsx with the desired PWM count.
// This sets the output pin low until phsx is decremented to -1
// resulting in phsx[31] going high which sets the output pin high.
//
// Setting frqx = -1 sets frqx to 2^32 - 1, adding this value
// to phsx results in subtracting 1 from phsx, allowing us to count down instead of up.
//
// This is useful for cases when an inverted PWM signal is required.
}}

CON
_clkmode = xtal1 + pll16x ' System clock → 80 MHz
_xinfreq = 5_000_000

PUB TestPwm | tc, tHa, tHb, t

  ctra[30..26] := ctrb[30..26] := %00100 ' Counters A and B → NCO single-ended
  ctra[5..0] := 16 ' Set pins for counters to control
  ctrb[5..0] := 17
  frqa := 1 ' Add 1 to phsa with each clock tick (PWM active high use +1 frqa value)
  frqb := -1 ' Add -1 to phsb with each clock tick (PWM active low use -1 frqa value)

  dira[16] := dira[17] := 1 ' Set I/O pins to output

  tC := clkfreq ' Set up cycle time
  tHa := clkfreq/5
  tHb := clkfreq/5 - 1 'Subtract 1 because 0 is still positive 
  t := cnt ' Mark current time.

  repeat ' Repeat PWM signal
    phsa := -tHa ' Define and start the A pulse. PWM active high use negative phsa value.
    phsb := tHb ' Define and start the B pulse. PWM active low use positive phsa value.
    t += tC ' Calculate next cycle repeat
    waitcnt(t) ' Wait for next cycle
Sign In or Register to comment.