Pulse and PWM Generation Techniques
The 68HC11 processor’s output compare functions provide lots of flexibility for creating single pulses or pulse-width-modulated waveforms that are useful for instrument control and automation applications. Most methods are variations on this algorithm:
- The desired start time of the pulse is programmed by storing an appropriate count in the output-compare register (TOCx) of OCx, and the OCx interrupt is enabled by setting a flag bit in TMSK1.
- OCx’s mode/level bits (OMx and OLx) are configured to automatically set the output compare’s corresponding output either high or low, depending on the polarity of the desired pulse (this action enables the output compare).
- When the compare occurs, the pin state is automatically changed and an interrupt service routine called.
- The interrupt service routine (ISR) reprograms the output compare to automatically change its pin back to its inactive level on the next compare;
- The ISR also increments the output-compare register by a value corresponding to the desired duration of the pulse.
Since the pin-state is changed by hardware automatically at specific values of the free-running counter, the pulse width is controlled accurately to the resolution of the free-running counter irrespective of software latencies. By repeating the actions for generating a pulse, you can generate an output signal of a specific frequency and duty cycle. While software latency and execution times do not affect the timing of the waveform, they do impose limits on the frequency and duty cycles attainable. The different methods of generating PWM signals differ primarily on where the software execution times are constrained to fit, either within the on time, the off time, or the waveform’s period as a whole.
The following is a quick summary of some of some specific ways you can use output compares to generate pulses or PWM waveforms using the QCard Controller Single Board Computer (SBC). You can find complete descriptions of the registers mentioned in Motorola’s MC68HC11F1 Technical Data Manual. Example 1 shows you how to generate a tirggered pulse, Examples 2 and 3 represent exceptional and instructive methods of generating PWM signals, and examples 4-6 are commonly used PWM methods. Example 6 provides code for generating "failsafe" PWM signals.
Example 1
Creating a single precise pulse from an external trigger
Suppose you’d like to output a single pulse on PA5 with very precise duration in response to a triggering event, for example the leading edge of an input pulse on PA0. You’d like the output pulse to start a precise, fixed time after the initiating trigger and to last some precise duration, between 2 microseconds and 131 milliseconds. Further, the output pulse should occur after the first occurrence of the trigger (after enabling the system) and then stay off rather than being retriggered by subsequent input pulses.
To do this you would use one input capture (IC3) and two output compares (OC1 and OC3). Because the trigger may occur anytime an input capture is used to determine the precise time of its leading edge. And because the output pulse width must be precisely controlled, and its duration can potentially be shorter than any interrupt service routine, the pulse should be turned on and off by output compares. The input capture invokes an interrupt service routine that enables the output compares. For our example we’ll assume the desired pulse start time is 10 milliseconds (or 5000 TCNT counts) after the trigger is detected, and its duration is precisely 10 microseconds (5 TCNT counts). Here’s one way to do it using three C-language routines:
An initialization routine (called ENABLE) that configures and enables IC3 to capture a rising edge on PA0, forces PA5 off to initialize it, and configures and enables OC3 to turn off pin PA5;
An interrupt service routine for IC3 (called IC3_ISR) that programs the comparator registers of OC1 and OC3 and enables OC1; and,
An interrupt service routine for OC1 (called OC1_ISR) that disables OC1 so that after the output pulse is first turned on it is not turned on again.
Here’s how to write the routines:
ENABLE – Inhibit IC3, OC1, and OC3 interrupts by storing 0x0xxxx0 to TMSK1 (using CLEAR.BITS with a mask of 0xA1). Configure OC1 to set PA5 high on an output compare by setting bit 5 of OC1D, but don’t enable it using OC1M yet – the IC3_ISR will be responsible for doing that. Configure OC3 to clear its associated pin (PA5) on an output compare by storing appropriate mode/level bits (OM3 and OL3), that is xx10xxxx, into the timer control register (TCTL1). Initialize PA5 to the OFF state by forcing an early output compare on OC3. This is done by setting bit 5 of CFORC. Configure and enable IC3 to capture a rising edge PA0. This is done by clearing bit 0 of DDRA (to set the data direction of PA0 to input), and setting the lower two bits of TCTL2 (the two corresponding to IC3) to xxxxxx01 to capture a rising edge. Clear the interrupt flag bit (IC3F) left over from any prior edge detection, if any, by writing a one to IC3F in TFLG1. Finally, enable an IC3 interrupt by setting the IC3I bit in TMSK1.
IC3_ISR – On entering the ISR routine first disable further interrupts by clearing the IC3I bit in TMSK1, and clear the interrupt flag bit (IC3F) by writing a one to IC3F in TFLG1. Then read TIC3 to determine the trigger time, we’ll call it TT. Set up OC1 to turn on output pin PA5 at time TT+5000 by setting TOC1=TT+5000 and configure OC3 to turn it back off just 5 counts later, by setting TOC3=TT+5005. Enable an OC1 interrupt by setting the OC1I bit in TMSK1. Finally enable OC1 and tie it to PA5 by setting bit 5 in OC1M.
OC1_ISR – This interrupt service routine will be invoked when the output pulse is turned on. It only needs to disable OC1 so that further pulses are not produced until the system is re-enabled by executing ENABLE again. Disable OC1 by clearing bit 5 in OC1M. Disable interrupts on OC1 by first clearing the OC1I bit in TMSK1, then clear the interrupt flag bit (OC1F) by writing a one to OC1F in TFLG1.
Example 2
Two OCs generate a PWM waveform without interrupts
Using two output compares you can generate a PWM waveform of any duty cycle (from 1/65536 to 65535/65536) without using interrupt service routines. As no ISR is used, no software resources are needed to maintain the waveform, and there is no impact on overall system performance. The PWM waveform is free – from a software perspective. So what’s the catch? The catch is that the waveform must have a fixed period, equal to the rollover period of the free-running counter, or 131.072 milliseconds. If you can live with that, here’s how it’s done: Two output compares are used, one sets the output pin at a particular value of TCNT, and the other simply resets the pin at another TCNT value. One of the output compares must be OC1 – because it can be used in conjunction with another to control the same pin. Let’s use OC1 to turn ON an output pin (PA5) whenever TCNT hits 0x0000, and OC3 to turn it OFF whenever TCNT hits 0x1000. More specifically,
- Disable interrupts caused by OCs by storing 0x00 to the timer interrupt mask register 1 (TMSK1). Now, output compares will not cause interrupts. Even so, they can still control output pins.
- Use OC3 to turn OFF the pulse whenever TCNT=0x1000 (for example, for a duty cycle of 1/16) by storing 0x1000 into TOC3. Configure OC3 to clear its associated pin (PA5) on a successful compare by storing appropriate mode/level bits (OM3 and OL3), that is xx10xxxx, into the timer control register (TCTL1). Now, whenever TCNT hits 0x1000 pin PA5 will be cleared. We configure the OFF transition first because we don’t want the pin to get stuck ON before we’re done configuring our output compares, just in case.
- Use OC1 to turn ON the pulse whenever TCNT=0x0000 by storing 0x0000 into TOC1. Associate OC1 with pin PA5 by setting bit 5 in the output compare mask register OC1M. Configure OC1 to set the pin high by storing 0x20 into the OC1 data register, OC1D. Now, whenever TCNT hits 0x0000 pin PA5 will be set high.
Because an ISR isn’t used, there is no possibility of software delays influencing the PWM output.
Advantages: Precise transition time control, all duty cycles possible with 16-bit resolution, no software needed to keep things running, failsafe in that a software crash is not likely to affect operation.
Disadvantages: Only a single channel, only a single PWM period.
Example 3
A single OC-driven ISR generates many PWM channels
What if you want to generate many channels of PWM waveforms, more than there are output compares? In the prior example output compares were used to generate a precisely-timed high-resolution waveform on a single channel without the assistance of an ISR (interrupt service routine). This example provides the other extreme, an unlimited number of channels of low-resolution PWM signals are generated by a single output-compare-driven interrupt service routine.
The scheme uses a single output compare to periodically invoke an interrupt service routine. The OC is not tied to a PORTA pin, rather it is used only as a dedicated clock that calls the ISR at a fixed interval corresponding to the smallest ON or OFF time that can be produced. Each time the ISR is called it updates all the PWM outputs using any general purpose output pins available. It may do this by reading values from a look-up table, counting, or more computationally.
Because the ISR latency can vary depending on what other interrupt-driven services are running on the controller there is some low jitter (or variance) on the transition times, producing a slightly varying PWM duty cycle. This variation can be compensated on the average if the ISR reads TCNT to determine the actual ON and OFF times and modulates the next ON or OFF time to attain the desired PWM duty cycle averaged over a number of cycles – but of course that requires greater execution time.
The sum of the ISR latency and execution times must be less than the difference between adjacent OC times, placing a limit on the smallest ON or OFF time attainable. If the ISR is delayed so long that the next OC time is missed, the next ISR doesn’t occur until TCNT rolls over and another match occurs. Consequently rollover delays of a TCNT period may be inserted into the desired ON or OFF times.
For an example of software generated PWM signals with 8-bit resolution and best averaging properties see "MI-AN-056 Optimal PWM Algorithm" and "MI-AN-058 Using Port PPA for PWM".
Advantages: Any number of channels can be accommodated.
Disadvantages: ISR latency causes jitter in the transition times; ON or OFF times smaller than the ISR latency and execution time are not possible; rollover delays possible if timing criteria not met; not failsafe.
Example 4
One OC and ISR generates a "no jitter" PWM signal
The simplest way of generating a precise PWM waveform with arbitrary duty cycle and period is to use a single output compare to automatically turn on and off an output pin and an interrupt service routine that reprograms the output compare after each transition. The "off" transition invokes the ISR which sets up the turn-on time and programs the next output state to be "on", and the "on" transition invokes the same ISR to set up the turn-off time and the next "off" state. The on and off times must each be great enough to contain the latency and execution time of the ISR. So duty cycles that would require very small on or off times are not attainable. If the ISR is delayed so that it does not program the next transition in time, than the output compare doesn’t find a match until TCNT rolls all the way around. In this case rollover delays of approximately 131 msec may be inserted into either the on or off time.
An example of this approach is presented by the function named OC3Service()
in the TURNKEY.C
example program found in the last chapter of this book.
Advantages: Transitions are precise, with no jitter; duty cycle and period are programmable over a wide range.
Disadvantages: ON or OFF times smaller than the ISR execution time and latency are not possible; rollover delays are possible; not failsafe – a software crash can leave the output stuck ON.
Example 5
Two OCs and ISRs generate a "no jitter" PWM signal of any duty cycle
To obtain ON and OFF times that may be each as small as a single clock tick, two OCs and ISRs are required. The "off" transition invokes an ISR which sets up the next turn-off time, and the "on" transition invokes a different ISR to set up the next turn-on time. Each ISR simply increments the next ON or OFF comparison register by the period. There is no particular restriction on the shortness of the ON or OFF times, either can extend down to just a single count of TCNT, but their sum, the period, must be great enough to contain the latency and execution times of both ISRs. Because OCs are used to drive the output pin, the transition times are exact, with no jitter. If service of either ISR is delayed for more than a period then a rollover delay may be inserted into either the on or off time.
Advantages: Transitions are precise, with no jitter; duty cycle and period are programmable over a wide range, duty cycle extends fully from 1/65536 to 65535/65536.
Disadvantages: Rollover delays are possible; not failsafe – a software crash can leave the output stuck ON.
Example 6
One OC and ISR generates a "failsafe" PWM signal
A single OC and associated ISR is used. The OC invokes an ISR for each transition. For the ON transition, the ISR is responsible for setting the output pin. It also computes the next turn-off time based on the time at which the pulse is actually turned on, and programs the OC to automatically turn it back OFF at the turn-off time. At the next OC the pin is turned off by hardware and the ISR is again called. This time the ISR just sets the turn-on time for the next OC time, disconnecting the OC from the pin so that the pin is not automatically set. This sequence of events produces pulses whose duration is invariant with respect to ISR delay, but that may jitter back and forth within their fixed period. Despite any jitter, the duty cycle and period are both precisely controlled. If the ISR is delayed by more than the off time, rollovers are inserted into only the off time, never the on time. So the pulse on times are failsafe so long as the processor’s clock is running.
Advantages: Failsafe operation assures an ON pulse is never longer than desired and the pulses turn off on a software crash. ON time may be as small as a single TCNT count.
Disadvantages: Pulse position jitter; rollover delays are possible in the OFF time; minimum OFF time must be greater than the IST latency and execution time.
Summary of PWM Methods | ||||||||
---|---|---|---|---|---|---|---|---|
Method | ISR Used | Output Compares | Turn ON/OFF | Jitter | D.C. Accuracy | D.C. Range | Rollovers inserted? | Period |
2 | no | OC1 and one other | OC/OC | no | Perfect | any | no – failsafe | Fixed at 131.072 ms |
3 | yes | any OC | ISR/ISR | yes | limited by ISR delays | Ton, Toff >ISR | yes | on and off times must each be greater than ISR latency and execution times |
4 | yes | any OC | OC/OC | no | Perfect | Ton, Toff >ISR | yes | on and off times must each be greater than ISR latency and execution times |
5 | yes | OC1 and one other | OC/OC | no | Perfect | Ton, Toff unlimited | yes | P>ISR1+ISR2 |
6 | yes | any OC | ISR/OC | yes | Perfect | Ton unlimited, Toff>ISR | failsafe – into only the off time |