Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] Pic16f84a watchdog timer

Not open for further replies.


Newbie level 2
May 11, 2015
Reaction score
Trophy points
Activity points
Hello All,

I am new to this forum and trying to get a better understanding of WDTs. I need to write a code to generate a .48 second (480 mS) WDT, but looking at all the literature concerning the PIC16 there are only 8 options to set the WDT at. I understand that a 1:32 WDT rate equates to 576 mS (Bit: 100) which is CLOSE to 480 mS, however the next rate below 1:32 WDT= 280 mS (Bit: 011), but I'm not sure how I code it to 480 mS. One thing that is required in the delay code is to call three loops (inner, middle and outer), so do I call the three loops at different rates that would equal 480 mS? I've been trying to read a variety of sources to explain this better, but can't quite get a grasp of it. One sample code I saw that is written for .48 seconds is listed below but I don't understand how this calls a .48 second delay. Why code 0X4F to execute 29 times and code 0X7E to execute 126 times?

Any help in explaining this so I can understand would be greatly appreciated!

Code ASM - [expand]
        CLRF    COUNT2
        CLRF    COUNT3
        MOVLW    0X7E                    
        MOVWF   COUNT3                  
        MOVLW    0X4F                    
        MOVWF   COUNT2                   
        MOVLW    0X4F                    
        MOVWF   COUNT1                   
        DECFSZ  COUNT1,F                
        GOTO    LOOPIN                    ; This will be executed 29 times
        DECFSZ  COUNT2,F                 
        GOTO    LOOPMID                 ; This loop will be executed 29 times
        DECFSZ  COUNT3,F                 
        GOTO    LOOPOUT                 ; This loop will be executed 126 times

Last edited by a moderator:

WDT is not a precise timer to use it that way. It is intended to reset your chip if program hungs or wake it up after some time of sleep.

You could select the value that is greater than the period you call your critical code, and inside the critical code use the CLRWDT instruction.

Once the PSA bits of the OPTION_REG is configured and WDT enabled then PIC will reset whenever the time reaches the WDT time. Default is 18 ms. So, if configured for 18 ms then PIC will reset every 18 ms. So you have to use

asm clrwdt
in the code such that WDT is cleared before it can reset the PIC. This way PIC keeps running all the time and if program executions stucks at some place then WDT overflows and resets the PIC.

I think you may be confusing the WDT with a normal timer or timing routine. The WDT is a hardware timer with it's own clock that (if enabled) forces the PIC to reset rather like you had powered it off and on again. It can't be used as a method of creating a delay because there is no way of resuming when time is up, it always goes back to the reset vector. To prevent it resetting the PIC you have to stop it reaching maximum count by using the 'clrwdt' instruction within the timeout period.

If you want to create delays using hardware, you need to use a timer. There is only one in the 16F84A which is one of the more serious limitations of that device but it can still be used. You set it up with the counting rate you want by using configuring the prescaler, taking into account the clock frequency you are using, then load it with the number of remaining counts before it overflows. It will count up by itself, even if the rest of your program is doing something else. When it overflows it goes back to zero and also sets the interrupt flag in INTCON. So you can tell when the delay has finished by either reading the timer and waiting for it to hold zero, or by checking the interrupt flag or, if you have inerrupts enabled, you can make it jump automatically to your interrupt handler code.

The method you show is creating the delay using nested loops. If you flow chart it you will see that the innermost loop "LOOPIN" just counts down to zero then drops one off the variable "count2" then it repeats. When "count2" has also reached zero it drops one off "count3" and so on. When all of them are zero the delay is finished. Each instruction takes a certain number of clock cycles to complete so by loading the variables with appropriate starting values you can set how many times it loops and hence how long it takes overall.


Yes, I need to use the nested loop for .48 seconds, but I am not how the individual's whose code I listed above came up with the hex addresses of 0X7E and 0X4F.


They are not addresses. The 'movlw' translates as "MOVe Literal to W register", it takes the value given in the instruction and loads it into the W register. It is the starting value for the counters. Because the 'decfsz' instructionis being used, the value counts down to zero before 'dropping through' to the instruction below it.


If your crystal frequency is 4 Mhz then instruction clock will be 4 Mhz / 4 = 1 MHz and T instruction cycle will be 1 / 1 MHz = i us. So, one nop instuction takes 1 us. Make a loop using nop so that you get 480 ms delay.

Not open for further replies.

Part and Inventory Search

Welcome to