Internal Timer , The Watchdog Timer

Watchdog Timer

now look at an internal timer, it is called a Watchdog Timer

what is a Watchdog Timer?

Suppose you have written a program that is continuously running on a PIC.  Now, you want to make sure that this program is always running, and that no matter what happens it will never stop.  The first thing you would have, of course, is a loop back at the end of the program that brings us back to the start of the program.  But consider this case.  Let us say that the PIC is monitoring an input.  When this input goes high, it jumps to another part of the program and waits for another pin to go high.  If the second pin doesn’t go high, the PIC will just sit there and wait.  It will only exit if the second pin goes high.  Let us consider another example.  Suppose you have written a program.  You have compiled it successfully, and you have even simulated it over and over again using a simulator such as MPLAB.  Everything seems to work fine.  You program the PIC and place it into a circuit.  However after a long period of time, the program gets stuck somewhere and the PIC gets caught in a loop.  What’s needed in both cases is some kind of  reset if the program gets stuck.  This is the purpose of a watchdog circuit.

A watchdog circuit is nothing new.  Many microprocessors and microcontrollers have them.  But how does it work?  Well, inside the PIC there is a resistor/capacitor network.  This provides a unique clock, which is independent of any external clock that you provide in your circuit.  Now, when the Watchdog Timer (abbreviated to WDT) is enabled, a counter starts at 00 and increments by 1 until it reaches FF.  When it goes from FF to 00 (which is FF + 1) then the PIC will be reset, irrespective of what it is doing.  The only way we can stop the WDT from resetting the PIC is to periodically reset the WDT back to 00 throughout our program.  Now you can see that if our program does get stuck for some reason, then the WDT will not be set.  The WDT will then reset the PIC, causing our program to restart from the beginning.

In order to use the WDT, we need to know three things.  First, how long have we got before we need to reset the WDT, secondly how do we clear it.  Finally, we have to tell the PIC programming software to enable the WDT inside the PIC.  Let’s look at these separately.

WDT Times

 The PIC data sheet specifies that the WDT has a period from start to finish of 18mS.  This is dependant several factors, such as the supply voltage, temperature of the PIC etc.  The reason for the approximation is because the WDT clock is supplied by an internal RC network.  The time for an RC network to charge depends on the supply voltage.  It also depends on the component values, which will change slightly depending on their temperature.  So, for the sake of simplicity, just take it that the WDT will reset every 18mS.  We can, however, make this longer.  Inside the PIC is a thing called a Prescaler.  We can program this prescaler to divide the RC clock.  The more we divide the RC clock by, the longer it takes for the WDT to reset.

The prescaler is located in the OPTION register at address 81h, bits 0 to 2 inclusive.  Below is a table showing the bit assignments with the division rates and the time for the WDT to time out:




WDT Time

























Remember these times are irrespective of your external clock frequency.  Think of these times as real time, rather than clock times.  To help make this clear, let us suppose we want the WDT to reset our PIC after about half a second as a failsafe.  The nearest we have is 576mS, or 0.576 seconds.  All we do is send b’101’ to our OPTION register, as follows:

movlw              b’101’  ;This is 0x05 in Hex
movwf              81h      ;This is the Option Register 

Simple, really.  Now,  there is a catch.  By default the prescaler is assigned to the other internal timer.  This means that we have to change the prescaler over to the WDT.   First, we have to reset the other counter to 0 first.  We then have to change to Bank 1 to assign the prescaler to the WDT and to set up the time, and then come back to Bank 0.  The code is below, where xx is the prescaler time:

bcf                 STATUS,0       ;make sure we are in bank 0
clrf                 01h                   ;address of the other timer – TMR0
bsf                STATUS,0       ;switch to bank 1
clrwdt                                     ;reset the WDT and prescaler
movlw           b’1xxx’             ;Select the new prescaler value and assign
movwf          OPTION           ;it to WDT
bcf                STATUS,0      ;come back to bank 0

The CLRWDT command above is how we clear the WDT before it resets the PIC.  So, all we need to do is calculate where in our program the WDT will time out, and then enter the CLRWDT command just before this point to ensure the PIC doesn’t reset.  If your program is long, bear in mind that you may need more than one CLRWDT.  For example, if we use the default time of 18mS, then we need to make sure that the program will see CLRWDT every 18mS.

So now we come to the point where we need to work out how long our code takes in real time.  The principle is very simple, but could cause you to pull your hair out!

Instruction Timing 

As you are probably already aware, the PIC takes the external clock timing and divides it by 4.  This internal time is called an instruction cycle.  Now if we have, say, a 4MHz xtal connected to the PIC, internally the PIC will run at 1MHz.  In timing terms, this is 1/(4MHz/4) = 1uS.  Now, some instructions take just one instruction cycle to complete, i.e. 1uS using a 4MHz crystal, while others take two cycles – 2uS – to complete.  The data sheet tells us how many cycles each instruction takes.  The easiest way to remember this is quite simple.  Assume ALL instructions take 1 cycle.  But, if an instruction causes the program to go somewhere else, then it will take 2 cycles.  Let me give you a couple of examples.  The movwf command takes only one cycle, because it is only moving data from one place to another.  The goto command takes 2 cycles, because it is causing the Program Counter (PC) to go elsewhere in the program.  The RETURN command takes 2 cycles, because it is causing the PC to go back in the program.  I think you can see the pattern here.  However, there are four commands which can take 1 or 2 cycles.  These are DECFSZ, INCFSZ, BTFSC and BTFSS.  These commands have one thing in common.  They will skip the next instruction is a certain condition is met.  If that condition is not met, then the next instruction will be carried out.  For example, the DECFSZ command will decrement the value stored in the F register by 1.  If the result is not 0, then the next instruction will be executed.  This instruction therefore takes 1 cycle.  If the result is 0, then the next instruction will be skipped, and the one following that will be executed.  In this instance the instruction takes 2 cycles.  The reason is that the instruction alters the value of the PC.  It needs one cycle to carry out the function, and it will need another to alter the PC by an extra one. 

To clarify this, let us look at a sample code, and work out how many instruction cycles it takes.

            movlw              02
            movwf              COUNT
loop     decfsz              COUNT
            goto                 loop

Our first instruction simply moves the value 02 into w.  This does not cause the program to off course, therefore it is only 1 cycle.  The next instruction is similar, in as much that it moves the contents of the w register into COUNT.  Again, this will be 1 cycle.  Now, the next instruction will first decrement COUNT by 1.  This is 1 cycle.  It will then do a test to see if COUNT is equal to 0.  At this stage it doesn’t, and so we move onto the next instruction.  The next instruction is a goto statement, and so is 2 cycles long.  We come back to our decfsz instruction, which decrements COUNT by 1 again.  This is another instruction cycle.  It does a test to see if COUNT is equal to 0.  This time it does, and so the next instruction is skipped.  To skip the next instruction requires another cycle.  We reach the end of the program.  So in total, with the value 02 placed into COUNT, this program will take a total of 7 cycles.  If we were using a 4MHz crystal for our clock, then the program will take: 

1/(4MHz/4) = 1uS per cycle, therefore 7 cycles takes 7 x 1uS = 7uS.

 So you can see that it can get a little confusing when you have instructions like DECFSZ.

Programmer Software

 Inside the PIC there are things called ‘Fuses’.  These are not the same as the fuses you would find in a mains plug, but electronic switches which are ‘blown’ by the programmer.  Now, one of these fuses has to be ‘blown’ in order  for the WDT to operate.  There are two ways of doing this.  One way is to write a couple of lines at the beginning of your program to tell the PIC programming software to enable or disable certain fuses.  The other way is to tell the PIC programming software manually which fuses to enable.  We will look at getting your program to instruct the programming software in a later tutorial, when we look at including other files and macros.  To tell the programming software manually, varies from program to program.  The documentation that came with the programmer should tell you how to do this.  As I am using the PICALLW software, which is linked on my main page, I will explain how to do change fuses within this program.  The fuses are configured by pressing the F3 key, or clicking on the ‘Config’ button.  Then you can select the fuse you want enabled, in this case the WDT, by clicking on the box next to it.

Keywords : Pic, 16f84, Interrupt, Tutorial, Timer, Watchdog
Writer : delon  |
19 Feb 2006 Mon   
No Comments