Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Hardware PWM or Software PWM

Status
Not open for further replies.

Overclocked

Member
Which would be better to control a servo? I have the hardware PWM working, but would using one over the other make a difference? Im using swordfish as my language and the microcontroller Does have support for hardware PWM (PIC18F1320).

I would assume software PWM would be something like;

High
waitsome period of time (1.5mS)
Low
Wait more time (20mS)
...etc
 
Last edited:

blueroomelectronics

Well-Known Member
It's actually easier in software, the HW PWM is poorly suited to the 1-2ms on and 20ms off. It can be done (I've done it) but is fairly course.
 

Mike - K8LH

Well-Known Member
.....the HW PWM is poorly suited to the 1-2ms on and 20ms off. It can be done (I've done it) but is fairly course.

The PWM module works great for generating jitter free high resolution Servo pulses if you break up the 20 msec Servo period into smaller PWM period "frames".

For example, twenty 1 msec PWM "frames" could be used to make up the 20 msec Servo period and could easily output any pulse width from 0 to 20,000 usecs in 1 usec 'steps'. Here's what the ISR "helper" code might look like;

Regards, Mike

Code:
;
;  //  setup a 1000 usec PWM period with PR2 = 249 and prescaler
;  //  16:1 (16 MHz clock) for 20 PWM 'frames' per 20 msec Servo
;  //  period and 1 usec pulse width resolution
;
;  int servo = 1500;            // 0..20000 in 1 usec steps
;  int width = 0;               // ISR work variable
;  int frame = 1;               // frame number 1..20
;
;  void ISR()
;  { PIR1bits.TMR2IF = 0;       // clear Timer 2 interrupt flag
;    frame--;                   //
;    if (frame == 0)            // if end of the 20 msec period
;    { frame = 20;              // reset for new 20 msec period
;      width = servo;           // reset 'width' work variable
;    }
;    if ((width > 1000)         // if width > 1000 usecs
;    { CCPR1L = 250;            // do a 100% duty cycle frame
;      CCP1CONbits.CCP1Y = 0;   //
;      CCP1CONbits.CCP1X = 0;   //
;      width -= 1000;           // subtract 1000 usecs
;    }
;    else
;    { CCP1CONbits.CCP1Y = (width & 1);
;      CCP1CONbits.CCP1X = (width & 2);
;      CCPR1L = (width >> 2);   // 0..249 (0..999 usecs)
;      width = 0;               // force remaining frames to 0%
;    }
;  }
;
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Top