As just one noteworthy example, consider the Apollo 14 lunar lander in its final descent to the Moon, back on February 5, 197l. Moon landings are insanely complicated and dangerous in any event, but at 13,000 feet the on-board radar system refused to operate. NASA rules dictated that if the craft dropped any lower without navigational radar, the astronauts were to abort the mission and return home. Back on Earth, the ground crew frantically scrambled to find a solution. With time rapidly running out, one young man surmised that the radar was locked on infinity. It was suggested that the commander, Alan Shepard, cycle the radar off, then on again. Lo and behold! The rebooted radar acquired the Moon's surface, and the lunar module touched down safely.
A power-on reset was all it took to rescue a mission, millions of dollars and maybe even two lives.
Your own projects with PIC microcontrollers probably won't have such dire implications, but it's still worthwhile to master the various types of resets at your disposal. Let's dig in.
The Big Picture
I have a love-hate relationship with PIC data sheets. On the one hand, they're very complete and chock full of useful information. Then again, they're so gigantic and detailed that it's easy to get lost in search of the practical. What's needed is a gentle treatment which begins with generalities, providing specific details only when absolutely required. Let's turn the beast into a step-by-step learning exercise, concluding with a capstone experiment to pull the pieces together.
All PIC chips have various types of built-in reset mechanisms of one sort or another. To keep this article specific, I've chosen the PIC16F88 to illustrate things as a representative and popular middle-of-the-road chip. Most other microcontrollers feature similar resets.
So what really happens when the PIC16F88 is reset? Quite a bit, actually. First off, various internal registers are initialized to default values. Likewise, configuration bits, what some folks refer to as fuses, are taken into account. These typically set up certain peripheral pins, choose a master clock source, or determine what types of resets will be activated. Next, some delays may be instigated until the power supply and master clock stabilize. You get the idea. There's a lot of commotion during those first few microseconds, which fortunately need not concern us much.
When the smoke clears, the PIC is finally ready to start executing your program. It does this by jumping to the reset vector at location zero in the program space. We're off and running!
As mentioned above, a reset in the PIC16F88 can be invoked four different ways. See the following figure.
A power-on reset (POR) is pure brute force, but nonetheless very necessary if we are to start the circuit off from a known condition when power is first applied. You'll recognize the astronaut from above recycling his radar as an example of a power-on reset.
Next is !MCLR, which stands for Master Clear. But really this is nothing more than a provision for an external pushbutton to force a reset. Did you note the exclamation sign in front of the acronym? It means that negative logic is employed here. (Normally that would be indicated by an overbar, but that’s hard to do in this blog.) In particular, when !MCLR pin is high, the microcontroller keeps steaming along. But if brought low for an instant, an external reset occurs, far more genteel than yanking the power cord out and plugging it back in again.
The third type available is the watch dog timer reset (WDT). Within the PIC is a counter circuit clocked by a separate low frequency oscillator. Whenever the counter overflows, a watch dog timer reset takes place. But if we periodically reset it to zero, preventing it from reaching its limit, then the reset is avoided. There are several uses for what seems to be an electronic equivalent of Sisyphus eternally pushing that boulder up the hill, just to have it roll down again. For example, if by some hardware glitch or software error the PIC program gets stuck in an infinite loop, then the watch dog counter times out; a reset occurs, which can right things gracefully.
The last option available is the brown-out reset (BOR). In most applications, the PIC16F88 operates on a power supply voltage of +5V. But if this level drops more than a volt lower, a brown-out reset takes charge. Again, we can work in some code to handle the problem, perhaps taking steps to disable external gear until the power supply is back up to spec again.
Now that we can see the forest, let's investigate the trees. A number of features of the PIC can be customized when flashing (burning) the chip for your application. These are handled by the configuration bits, or fuses. There are quite a few of these, but referring to the following figure, only the ones required for working with resets are described.
There are bits to enable or disable the last three resets listed in the first figure: BOREN, MCLRE and WDTEN. In the latter case, if WDTEN = 1 then the watch dog timer is always running. But if 0, it can be engaged or disengaged through software, as we'll see later.
The pressing question at the moment is: how can the PIC program know which of these four types of reset has occurred? The answer is to be found in some flags, that is, special bits within several registers. We simply test these bits in various combinations to decide what needs to happen.
The first register we meet is the STATUS register, containing one flag of interest. Here's that negative logic once again. When !TO is clear, a watch dog timeout has occurred. Note that this is a read-only bit. The PIC takes care of manipulating it appropriately.
The next register, PCON, standing for Power Control, contains two flags which further help narrow things down. You should be getting used to the negative logic by now. When !POR = 0, a power-on reset has just occurred. Similarly, if !BOR = 0, then a brown-out reset flew by. Observe that both of these are read-write bits, so it's up to your program to set them before use.
Configuring the Watch Dog Timer
The following figure shows how to make the watch dog jump through its hoop.
An oscillator distinct from the master PIC clock, runs at 31.25 kHz, and can drive either Timer0 or the watch dog timer. We're only interested in the latter for this article, so set bit PSA high in the OPTION_REG register.
Now the watch dog timer has a prescaler and a postscaler, both of which can be used to slow down the timing interval before we catch it out and make it start over again to prevent a reset. The postscaler choice is also determined in OPTION_REG. (When used with Timer0, it reverts to prescaler status).
WDTCON, or Watch Dog Timer Control, configures the genuine prescaler. Note too that there is a bit which gives you additional control. Supposing that the WDTEN fuse (described earlier) is 0, then this new bit, SWDTEN, can be employed to enable or disable the watch dog timer in software.
You might want to pull out your calculator at this point and confirm you understand the effects the prescaler and postscaler have upon the watch dog timer. Recalling that the base oscillator runs at 31.25 kHz, and that period is the reciprocal of frequency, a quick computation reveals that the shortest timing interval possible is 1.024 mS, while the longest is about 268 seconds.
Putting It All Together
So the problem now boils down to, how can we read the various flags and interpret which type of reset has occurred? In fact, this can get a trifle messy and difficult to decipher from the data sheet, requiring much back and forth among the various tables to uncover. Here's a better plan.
Check out the following figure which details an algorithm (in pseudo-code) for sorting through the possibilities. It also shows which flags need to be cleared and when.
With this approachable chunk of code at the ready, you should have no trouble converting it to a real working program, regardless of the language you prefer. Let's take a quick peek at it.
First thing to observe is that it makes a difference in what order you monitor the flags, at least for handling things efficiently. The code begins by checking !POR. If cleared, both !POR and !BOR are prepped for next time, and then you're free to do whatever else is needed at power-on.
Then we check to see if a watch dog timeout has occurred. I mentioned earlier that !TO is read-only, so how do we set it for next time? Simple; the CLRWDT command (one of the PIC's opcodes) takes care of that for us. Unfortunately, this also resets the prescaler and postscaler, so these need to reinitialized again. But after that, you're okay to process the watch dog reset.
Next, we see if an external reset has taken place on the !MCLR pin. You'll note that this is actually done by querying whether !BOR has remained high. In fact, what's going on here is that we're whittling down the possibilities step-by-step.
Anything left over must be a brown-out reset. Again, don't forget to set !BOR for next time.
Let's See lt in Action
It's one thing to read about PIC workings, but another altogether to see with your own eyes what actually transpires. Hence, I've put together a wonderful experiment for you to try out. It demonstrates all four types of resets with a straightforward program derived from the pseudo-code just described. Head to the workbench and give it a whirl now. It uses only generic components.
Here's the schematic for the test rig.
And the following photo shows what my breadboard looked like. Four different colored LEDs indicate power-on, brown-out, !MCLR and watch dog resets, respectively. The multimeter is there to monitor when the power supply drops enough to trigger a brown-out reset.
To run the experiment, you'll need the PIC Micro Pascal source code, of course. So, go get it now.
Begin by setting the pot to its highest level. This will provide the full +5V to the circuit. Then flip the power switch on. Observe that the red LED lights for one second, indicating a power-on reset as expected.
Next, lower the potentiometer level slowly. When the voltage from it drops below about +4V a brown-out reset is initiated; bring it back up again and the yellow LED lights for one second.
If you next press the Reset pushbutton, the green LED lights, indicating an !MCLR or external reset has transpired.
Finally, if you press the WDT Clear pushbutton repeatedly, the watch dog timer is staved off. But let it sit untouched for around 34 seconds, and a watch dog timer reset commands attention. The blue LED lights.
Of course, there are other niceties you can look into later, but you should now have a pretty good grasp of the four main PIC resets and how to use them. Best of all: that imposing data sheet should no longer seem so intimidating!