Electronic – PIC measuring PWM pulse length

mplabpicpwm

I'm just getting started with PIC processors, driven mainly by a shortage of the simpler PICAXE from my local retailer. My question is, how do I read the length of a PWM pulse on a certain input pin (analogous to the PULSIN command on PICAXEs). I'm using the MPLab IDE, and the specific PIC in question is the 12F683.
Secondly, (sorry to combine two questions into one), are there libraries out there that contain 'common' functions (PWM output, i2c support and the like)? Google's turning up dry-ish, but it seems to me that such libraries have to be out there, somewhere…. Thanks for any help!

EDIT: the language is C, and the PWM signal is the output from a RC reciever intended for a servo, so, it is a 1-2 ms high pulse every 20 ms (if I understand that correctly)

Best Answer

There are various ways to measure the width of incoming pulses. Which is most appropriate depends on the width of the pulses, what accuracy you need, and which peripherals your PIC has. Some possibilities are:

  1. Use two CCP modules in capture mode. This is not possible for your particular PIC since it has only one CCP module, I'll mention it anyway for others or in case you change the PIC. A CCP module in capture mode grabs a snapshot of the free running 16 bit timer 1 on the edge of a I/O pin. With two of these captures, one for each edge, you subtract them to get the pulse duration.

    This method allows for the shortest duration pulses and has the most accuracy, but takes two CCP modules.

  2. Use a single CCP module and flip the edge it captures on in a interrupt triggered by the first capture. This has the same accuracy and resolution as #1 and uses only a single CCP module, but requires the pulse to be some minimum width so that the interrupt routine has time to grab the captured value switch the capture edge polarity.

  3. Capture the free running timer 1 in firmware every edge, then do the subtraction as in #1 and #2. This requires no CCP module at all, but there must be some minimum time between edges for the interrupt routine to do its job. It also has a bit more error due to some uncertainty in the interrupt response, and possibly in variable number of instructions from the interrupt routine if not coded carefully.

  4. Gate timer 1 from the pulse. Have the trailing edge cause a interrupt, which then reads the timer 1 value and possibly resets it ready for the next pulse. This has good accuracy and resolution, but requires some minimum time between pulses for the interrupt to grab the timer 1 value and set up for the next pulse.

There are other methods too, but without knowing more about the characteristics of your pulses it's not worth spending time on them. Given that your PIC has a single CCP module and timer 1 with gating option, methods 2 and 4 are worth considering. Again, it would help to know more about the pulse characteristics.

One thing I didn't metion is overflow handling for long pulses, but if your pulses are known to be short enough this is not a issue.