Analog comparators, though not particularly sexy, must surely rate as one of the more useful building blocks for a wide variety of circuits. They can be used to generate pulse width modulation, monitor under- or over-voltages, shape up ugly signals into nice crisp pulse waves, act as logical inverters, help with interfacing mechanical switches and more. A comparator has two analog inputs, and a lone output which can be considered digital since it can assume only two possible states. If the voltage on what’s referred to as the non-inverting input exceeds that on the inverting input, then the output snaps high, otherwise it remains low.
It’s easy to forget that most PIC microcontrollers sport one or more uncommitted analog comparators. For example, after designing the two-wire LCD project here, all of a sudden it hit me (a slap on the forehead moment) that the transistor inverter required there could be completely eliminated, including its two resistors, and replaced with an internal comparator within the driving PIC chip. Just like that, the parts count shrinks by three components, and at no extra cost.
Apart from forgetting to make good use of these comparators, there’s that business of the data sheet. On the one hand, I’m delighted Microchip (the manufacturer of PIC microcontrollers) has given us such comprehensive materials to work with. And yet, who hasn’t dragged their feet when first approaching this huge, daunting manual?
That’s where this tutorial comes in. Besides reminding you of the utility of comparators, it will reorganize the concepts of the data sheets into something more approachable. We’ll get the big picture in mind first, and only after that, will we proceed to the details. Along the way, seven experiments give you a chance to really nail everything down, the very tests I performed to confirm what was going on. With just a handful of common components at your side and a couple sessions at the breadboard, you’ll be all set to design your own PIC circuits exploiting analog comparators.
The Big View
As mentioned, just about all of the PIC chips contain at least one analog comparator available for use in various modes or configurations. To keep things specific here, let’s consider the ever-popular PIC16F88, one of the most commonly employed microcontrollers. But do keep in mind that similar arrangements are apt to apply to whichever specific PIC chip you’re keen on.
There are so many options available that it’s easy for your eyes to just glaze over and make you want to walk away from the mess. But in my thirty years of teaching, I’ve always found branching tree diagrams useful for organizing multiple options. Somehow, visualizing the choices graphically makes them all less daunting, and the details won’t swamp you. So, begin by referring to the following figure which illustrates the relationships among the eight possible modes available for the two comparators within the PIC16F88. Each mode is indicated by a three-bit binary number, about which, more later.
The figure really does tell most of the story quite well, so I won’t waste many words here describing what you can see for yourself. But let me call point out a few of the more salient points.
Starting at the top of the diagram, you’ll see that the comparator modes split into two main categories: Single and Dual. In Single mode, only Comparator 2 is enabled. Comparator 1 is completely disconnected from the PIC (via internal multiplexing), freeing up its associated pins for other uses.
On the other hand, with any of the Dual modes, both comparators are available. The Dual modes, can be divided into two major categories: Independent and Common Reference. As the name implies, in an Independent mode, the two comparators are completely divorced from one another and can be treated as separate circuits. But a Common Reference mode has the two non-inverting inputs ganged together. Typically, this frees up a pin for other applications in the PIC.
Continuing our tour of the tree, Independent mode splits in two again, either Disconnected or Connected. If the comparators are disconnected, they are indeed disabled altogether, and their pins (port pins A.0 through A.3) are liberated for other general purpose uses. This is the default situation at power-up, which is why many of us forget about the comparators!
But if the comparators are in fact connected, then the internal multiplexer brings the inputs out to the chip pins. As the figure indicates, there are two Connected modes: Reset and Running. When the mode is configured to Reset, the comparators are still hooked up, but their outputs are forced to be zero, regardless of the state of the inputs. Otherwise in Running mode, they are free to operate independently of whatever else the microcontroller is up to.
That takes care of all the Independent modes. Move over to the Common Reference modes mentioned earlier. You get two main choices here: Register Outputs or Pin Outputs. In the former, the outputs of the comparators are only accessible from within an internal register, CMCON to be described in a moment. But in the latter, it is also possible to route the outputs to physical pins on the PIC16F88, in which case the comparators behave like any outboard unit you may have used in the past.
Now the Register Output modes bifurcate, giving the ability to sense either an Internal Reference or an External Reference. In either case, the reference voltage will be applied to the non-inverting inputs of the comparators.
Finally, when using an External Reference, you get a choice of either the default pins that Microchip has designated, or are offered some flexibility on which ones actually connect up to the inverting inputs. That’s thanks to the magic of multiplexing. This would make it possible to choose one of two voltages to monitor under software control, for example, sort of like an SPDT switch.
How to Select a Mode
Setting each of these eight modes is a snap by means of the CMCON register. The acronym stands for Comparator Module Control, of course. This is illustrated in the next figure.
Take a look at bits 6 and 7 first. These are the comparator output bits, alluded to previously. They are always in operation, diligently following whatever the two comparators are up to. Clearly, they are read-only in nature.
Bits 0 through 2 form the three-bit mode number mentioned above. Did you notice these codes in the first figure of this tutorial? Just pop the desired number in here and away you go.
Bit 3 is only required by modes 001 and 010 and let you select which pins actually connect to the PIC comparators. You’ll get a chance to see it used in the experiments.
Finally, bits 4 and 5 provide a nice little piece of flexibility. These guys change the sense of the comparators under software control. For example, if bit 4 is cleared to zero, then Comparator 1 behaves as you’d normally expect. But make it a one, and then it becomes an inverting comparator. This is sort of like exchanging the inverting and non-inverting inputs, and is particularly useful in keeping the firmware less convoluted to the eye.
What About Interrupts?
Designing circuits and software to handle an interrupt generated by the comparators is remarkably straightforward. Here are the few things you need to know.
There are three levels of interrupt enable flags (sometimes called masks in other processors). At the deepest level, you need to set the flag CMIE, which stands for Comparator Module Interrupt Enable when you do indeed want interrupt action. You’ll find this in the register PIE2, an acronym for Peripheral Interrupt Enable 2. Obviously, the comparators are considered to be peripherals.
One step up from this is PEIE bit, or the Peripheral Interrupt Enable. It too must be set to get things cooking. Look for it in the register named INTCON, a symbol for Interrupt Control.
Finally, at the highest level, you’ll need to set the flag GIE, an abbreviation for Global Interrupt Enable. This one, too, is found within INTCON.
Putting it altogether, if you really do want the comparators to generate interrupts, then set CMIE, PEIE and GIE. If any one of these is clear, then the interrupts are masked.
One final thing. If you look inside register PIR2 (Peripheral Interrupt Register 2) you’ll notice the bit CMIF, which stands for Comparator Module Interrupt Flag. This bit is constantly watching the comparators and is set any time a state changes, regardless if the interrupts are masked or not. When you enter a comparator interrupt routine, be sure to clear this flag before returning to the main program.
And don’t be disheartened if it sounds a bit messy! As you’ll see in Experiment 7 below, it’s remarkably easy to make this stuff all work.
Well, let’s stop all this yammering and head straight to the workbench! Your first step is to get the firmware source code written in the PIC Micro Pascal language.
The following schematic is for Experiment 1.
Here we get to see mode 101 in operation. Recall that only Comparator 2 is utilized, the other being disabled. A reference voltage of +2.5V (courtesy of divider R2/R3) is applied to the inverting input (at pin 18) as the reference. Now while monitoring the wiper of potentiometer R4 with a multimeter, watch what happens as you increase the voltage on the non-inverting input at pin 1. Once it exceeds +2.5V, LED D1 snaps to attention.
Observe that since Comparator 1 is out of the picture, port pins A.0 and A.3 are freed up for any other use you have in mind. This is a simple experiment, but a great way to get your feet wet.
Now turn to the next schematic which shows the layout for the Experiment 2.
We’re in Dual mode now, with both comparators doing their thing. In particular, you’ll get to see them running normally, or have their outputs forced to reset.
A +1V reference is applied to Comparator 1 at pin 17, while + 2V is put onto Comparator 2 at pin 18. Again, while monitoring the wiper of either R6 or R7 with a multimeter, observe how LEDs D1 and D2 respond once the threshold voltages are reached.
Closing switch S1 puts the mode to 000 which forces both comparators to reset, regardless of what the potentiometers are up to.
Experiments 3, 4 and 5
The next three experiments use the following schematic.
In Experiment 3, mode 011 is used which gives a fixed pin arrangement and an external reference (provided by divider R5/R6) applied to the ganged reference inputs of the comparators.
Mode 001 is utilized in Experiment 4. This implies that reference pins 17 and 18 could be assigned elsewhere if desired. Again, multiplexing makes this all possible.
For Experiment 5, completely remove voltage divider resistors R5 and R6, because an internal reference of +2.5V will be handily created by the PIC. Refer to the source code to see how easy it is generate the desired voltage. And if it isn’t clear, we’re using mode 010 now.
You’ll find the circuit diagram for this experiment next.
At last, we’re using the pin output feature provided by mode 110. In particular, the pulse-width modulation unit within the PIC16F88 applies a varying rectangular pulse to the green element within bicolor LED D1. Simultaneously, that signal is pumped through Comparator 1 acting as a logical inverter. Its output is then applied to the red element of D1. This implies, for example, that when the green element is seeing a 75% duty cycle signal, the red element is getting a 25% signal. The program sweeps these back and forth, giving a pleasing morph of green to orange to red and back again, over and over.
This is a neat little demonstration, and really shows off the power of PIC Micro Pascal simultaneously. Here's the schematic.
In this case we’re using interrupts and coercing the PIC to behave as a sort of retriggerable one-shot. Press pushbutton S1 briefly, and LED D1 will light for one second. But press and hold the switch and the LED simply stays lit until the button is released. Utilizing comparator interrupts is particularly easy, as the source code readily shows. Give it a quick read-over and see for yourself.
Some Lessons Learned
When I first timidly approached the PIC data sheet I fell into the trap of misinterpreting a number of concepts concerning the analog comparators. And then there was the swirl of too many details thrown at me all at once. But after working the experiments, I found that everything behaved very simply after all, and reliably to boot. Let me relate just a few of the things I picked up along the way; maybe they’ll save you some headaches.
- The comparators are disabled by default at power-up.
- There is no need to diddle at all with ANSEL, the analog select register. Setting the mode in CMCON takes care of configuring the input pins as analog.
- But, do set the data direction in TRISA for the input pins.
- Any pins not actively used by the comparators are available for any other purpose.
- The comparator inputs always read as zero (not that you’d want to read them directly anyway).
- The output impedance of whatever is driving the comparator inputs should be less than 10k.
- Altering a mode midstream in a program may fire an interrupt.
- Any change in either comparator (low to high or high to low) triggers an interrupt.
Next Tutorial: Eeproms and Program Memory