
Here at Rabbit tech support we have received several questions lately asking how to generate some number of pulses from a Rabbit output. With some consideration I decided to address this question in this month’s Ask Larry and present one possibility.
There are two pulse generating mechanisms in the Rabbit 4000 and 5000 processors:
- Pulse Width Modulation – PWM
- Pulse Position Modulation – PPM
Both of these features allow an interrupt to be generated:
- PWM generates its interrupt when the counter counts down to 0
- PPM generates its interrupt when it reaches the count loaded into the Divisor register
In order to generate a programmable number of pulses with a Rabbit, the only practical solution is to count the pulses and turn them off after the desired number of pulses have been transmitted. The easiest way to count pulses is to generate an interrupt with each pulse and count the pulses in the Interrupt Service Routine (ISR).
This diagram shows PWM interrupt timing:

There are essentially two problems using PWM, both due to the interrupt occurring at the same time as the beginning of the output pulse:
- If the interrupt is for the last pulse how does the system stop at the end of the pulse? There is no mechanism in the Rabbit to terminate the pulses after a pulse has completed.
- If the interrupt is for the pulse immediately after the “last” pulse then a partial pulse will be output.
There is one way to get around both of these issues but it involves using the External Interrupt feature of the Rabbit. An interrupt can be generated on the falling edge of the pulse. This can be done without using any external wiring since two of the PWM outputs are available on two pins that are also External Interrupt inputs. I did not want to tie up another feature of the Rabbit if not absolutely necessary.
The method I chose to control the number of pulses described here and implemented in the attached program uses PPM and its interrupt feature to both enable and disable output pulses. PPM is used because the output pulse can be delayed from the interrupt event. Delaying the start of the pulse allows the ISR time to enable or terminate the pulse stream before the next pulse would start. The diagram below illustrates this.

The attached sample program is well documented and should be fairly easy to follow. Note that the method chosen to enable/disable the PPM output is that of changing the behavior of the selected I/O pin. When the pulse stream is enabled the I/O pin is set up to be the output of Timer C0. When the pulse stream is disabled the I/O pin is set to be a simple parallel output. It is important to realize that even when the output pin is not outputting pulses the PPM system is still running. Basically, the ISR is synchronously gating the output pulses to the I/O pin.
With Timer C driven by Pclk/2, the start count of 100 allows a theoretical maximum ISR execution time of 200 clocks. Since the longest ISR time is 149 clocks there is some margin of safety. Note that the interrupt priority level is set to 2. This is done to ensure that the interrupt has a higher priority than normal Dynamic C ISRs so that there are no truncated or missing pulses.
If you use an RCM4xxx prototype board and define the macro PB_SWITCHES, you can use S2 to trigger a burst of pulses. If you hold down S3 when you press and release S2 the output frequency will be doubled. The code attempts to keep the duty cycle at 50% but may not be as accurate at higher frequencies.
Another macro, PB7_DEBUG, may be defined which will cause PB7 to toggle its state each time the ISR is executed – even if pulses are disabled.
In order to use the code in this program all you have to do is place a value in the variable Pulses_Remaining. As long as PPM interrupts are enabled, the ISR will turn on the pulse stream at the next interrupt and then turn it off after outputting the specified number of pulses.
If your application is concerned about excessive ISR time while not generating pulses you can disable the PPM system from generating interrupts by writing a 0 into TCCR. To re-enable the system I recommend that you enable interrupts first, via TCCR, then load the desired value into Pulses_Remaining.
This example provides a reliable mechanism for something like a DC stepper motor. By tweaking the included sample code you can easily vary the speed and the number of steps which might be just the thing you need for your next project.
- Larry C.
Larry Cicchinelli is Rabbit’s Technical Support Manager. He has 30 years of embedded experience, and is considered one of the foremost authorities on Rabbit products. Larry and his staff offer comprehensive technical support to Rabbit customers.
Submit your questions for Larry via email at AskLarry@rabbit.com
Read more Ask Larry Answers
