pwn PWM

Not really much of a hack for this hack session, but still a lot of fun – PWM output control in a PIC microcontroller for a configurable H bridge / 3 phase bridge. A High/Low pair of outputs is set up in complementary mode with a dead time (where in a transition, both outputs are off for a short period of time) so we never get the scenario with slow reacting FET’s, of both High and Low sides of the bridge being on at the same time hence shorting the circuit.

Oscilloscope Complementary H/L PWM trace

The simplest implementation here is a H bridge – we have two High-Low bridges with say a DC motor connected across the centre of the bridge. In that case, we complementary control PWM on one side of the H bridge, and we logic control the other side. We control the duty cycle of the PWM which controls the speed of the motor, and we could swap sides that are being PWM and Logic, to make the motor move in the opposite direction.

Finally, we throw in some varying setpoints to alter the duty cycle. I also added some code to allow the motor to move in either direction from a positive or negative set point.

And there we have it;

void pwmForward(void) {
  P1OVDCONbits.POVD1L = 1;    /* PWM */
  P1OVDCONbits.POVD1H = 1;    /* PWM */
  P1OVDCONbits.POVD2L = 0;    /* Override */
  P1OVDCONbits.POVD2H = 0;    /* Override */
}

void pwmReverse(void) {
  P1OVDCONbits.POVD1L = 0;    /* Override */
  P1OVDCONbits.POVD1H = 0;    /* Override */
  P1OVDCONbits.POVD2L = 1;    /* PWM */
  P1OVDCONbits.POVD2H = 1;    /* PWM */
}

A gotcha – Using Port IO on the logic side left the output at a mid level – there is however an override register which sets or clears the logic level so use this rather than conventional TRIS/LAT when using PWM. (It is all in the documentation, but hack night is about beer and fun, not documents!)

/* Low side active when override active */
P1OVDCONbits.POUT1L = 1;

/* High side inactive when override active */
P1OVDCONbits.POUT1H = 0;

/* Low side active when override active */
P1OVDCONbits.POUT2L = 1;

/* High side inactive when override active */
P1OVDCONbits.POUT2H = 0;

About Tim

Timothy Freeburn is the owner of Freeburn Robotics Limited, a robotics design and engineering consultancy company in Cambridge, UK.
This entry was posted in Programming. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>