Sample Program

Let us write a program, where we will turn on the WDT, and let the PIC perform a function. We will first of all periodically clear the WDT, to show that the program works, and then remove the CLRWDT command to show that the PIC will indeed reset.

The program I have chosen is the one used in tutorial 9 where we cause a row of LEDs to light up one at a time from left to right, then right to left. The circuit is shown below, and with the RC values shown will give us a clock frequency of 8KHz. This clock speed will allow us to actually see the LEDs moving one by one. I chose this program because it is slow enough for us to play with the WDT, and you can easily see when the PIC is reset. I have removed the original comments, and I have replaced them with a description of the WDT lines, a running total of the time from the start (assuming a 8KHz clock), and the number of clock cycles at each line.

tut13


TIME equ 9FH ; Variable for the delay loop.
PORTB equ 06H ; Port B address.
TRISB equ 86H ; Port B Tristate address.
PORTA
equ 05H ; Port A address.
TRISA equ 85H ; Port A Tristate address.
STATUS equ 03H ; Page select register.
COUNT1 equ 0CH ; Loop register.
COUNT2 equ 0DH ; Loop register.

bsf STATUS,5 ; 1 cycle, 0.5mS
movlw
00H ; 1 cycle, 1.0mS
movwf
TRISB ; 1 cycle, 1.5mS
movlw
00H ; 1 cycle, 2.0mS
movwf
TRISA ; 1 cycle, 2.5mS
bcf
STATUS,5 ; 1 cycle, 3.0mS
movlw
00H ; 1 cycle, 3.5mS
movwf
PORTA ; 1 cycle, 4.0mS

; Start of main program

RUN

movlw 01H ; 1 cycle, 4.5mS
movwf PORTB ; 1 cycle, 5.0mS
call DELAY ; 2 cycles, 486mS
call DELAY ; 2 cycles, 967mS

; Move the bit on Port B left, then pause.

rlf PORTB,1 ; 1 cycle, 967.5mS
call DELAY ; 2 cycles, 1.45S
call DELAY ; 2 cycles, 1.93S
rlf PORTB,1 ; 1 cycle, 1.93S
call DELAY ; 2 cycles, 2.41S
call DELAY ; 2 cycles, 2.89S
rlf PORTB,1 ; 1 cycle, 2.89S
call DELAY ; 2 cycles, 3.37S
call DELAY ; 2 cycles, 3.85S
rlf PORTB,1 ; 1 cycle, 3.85S
call DELAY ; 2 cycles, 4.34S
call DELAY ; 2 cycles, 4.82S
rlf PORTB,1 ; 1 cycle, 4.82S
call DELAY ; 2 cycles, 5.30S
call DELAY ; 2 cycles, 5.78S
rlf PORTB,1 ; 1 cycle, 5.78S
call DELAY ; 2 cycles, 6.26S
call DELAY ; 2 cycles, 6.74S
rlf PORTB,1 ; 1 cycle, 6.74S
call DELAY ; 2 cycles, 7.22S
call DELAY ; 2 cycles, 7.70S
rlf PORTB,1 ; 1 cycle, 7.70S

; Now move onto Port A, and move the bit left.

rlf PORTA,1 ; 1 cycle, 7.70S
call DELAY ; 2 cycles, 8.19S
call DELAY ; 2 cycles, 8.67S
rlf PORTA,1 ; 1 cycle, 8.67S
call DELAY ; 2 cycles, 9.15S
call DELAY ; 2 cycles, 9.63S
rlf PORTA,1 ; 1 cycle, 9.63S
call DELAY ; 2 cycles, 10.11S
call DELAY ; 2 cycles, 10.59S
rlf PORTA,1 ; 1 cycle, 10.59S
call DELAY ; 2 cycles, 11.07S
call DELAY ; 2 cycles, 11.55S

; Move the bit back on Port A

rrf PORTA,1 ; 1 cycle, 11.55S
call DELAY ; 2 cycles, 12.04S
call DELAY ; 2 cycles, 12.52S
rrf PORTA,1 ; 1 cycle, 12.52S
call DELAY ; 2 cycles, 12.99S
call DELAY ; 2 cycles, 13.48S
rrf PORTA,1 ; 1 cycle, 13.48S
call DELAY ; 2 cycles, 13.96S
call DELAY ; 2 cycles, 14.44S
rrf PORTA,1 ; 1 cycle, 14.44S

; Now move the bit back on Port B

rrf PORTB,1 ; 1 cycle, 14.44S
call DELAY ; 2 cycles, 14.92S
call DELAY ; 2 cycles, 15.40S
rrf PORTB,1 ; 1 cycle, 15.40S
call DELAY ; 2 cycles, 15.89S
call DELAY ; 2 cycles, 16.37S
rrf PORTB,1 ; 1 cycle, 16.37S
call DELAY ; 2 cycles, 16.84S
call DELAY ; 2 cycles, 17.33S
rrf PORTB,1 ; 1 cycle, 17.33S
call DELAY ; 2 cycles, 17.81S
call DELAY ; 2 cycles, 18.29S
rrf PORTB,1 ; 1 cycle, 18.29S
call DELAY ; 2 cycles, 18.77S
call DELAY ; 2 cycles, 19.25S
rrf PORTB,1 ; 1 cycle, 19.25S
call DELAY ; 2 cycles, 19.73S
call DELAY ; 2 cycles, 20.22S
rrf PORTB,1 ; 1 cycle, 20.22S
call DELAY ; 2 cycles, 20.70S
call DELAY ; 2 cycles, 21.18S

goto RUN ; 2 cycles, 21.18S

; Subroutine to give a delay between bit movements.
;Total of 957 cycles, 480mS

DELAY
movlw TIME ; 1 cycle
movwf COUNT1 ; 1 cycle

LOOP1 ;
decfsz COUNT1 ; 9F x 1 cycle + 1 cycle = 160 cycles
goto LOOP1 ; 9E x 2 cycles = 316 cycles
movwf COUNT1 ; 1 cycle

LOOP2 ;
decfsz COUNT1 ; 9F x 1 cycle + 1 cycle = 256 cycles
goto LOOP2 ; 9E x 2 cycles = 316 cycles

return ; 2 cycles

END ;

With an 8KHz clock, it takes just under 1 second for the next LED illuminates, and it takes a total of about 21 seconds to run from one end to the other and back again i.e. to go through the routine once only. The delay routine takes 480mS, and we are calling it twice before moving the bit on the ports. Now, we need to periodically reset the WDT. The largest time we can set the WDT is 2.3 seconds, and the next one down form this is 1.1 seconds. We have two options here. We could make a call to a subroutine to clear the WDT after the two delays have finished, or we could incorporate the CLRWDT within the delay itself. I have decided, for no real reason at all, to incorporate the CLRWDT within the delay loop.

TIME equ 9FH ; Variable for the delay loop.
PORTB equ 06H ; Port B address.
TRISB
equ 86H ; Port B Tristate address.
PORTA
equ 05H ; Port A address.
TRISA
equ 85H ; Port A Tristate address.
STATUS equ 03H ; Page select register.
COUNT1
equ 0CH ; Loop register.
COUNT2
equ 0DH ; Loop register.

OPT equ 81h ; Option Register to control the WDT

;*************Set up the ports, WDT and prescaler******************

clrf 01h ;Clear TMR0
bsf STATUS,5 ;Switch to bank 1
clrwdt ;reset the WDT and prescaler
movlw b’1101’ ;Select the new prescaler value and assign
movwf OPT ;it to WDT


movlw 00H
; Now set up the ports
movwf TRISB
;
movlw 00H
;
movwf TRISA
;
bcf STATUS,5
;Come back to bank 0

movlw 00H ;
movwf PORTA
;

;*************Start of main program*****************************

RUN

movlw 01H ;
movwf PORTB ;
call DELAY ;
call DELAY ;

; *************Move the bit on Port B left, then pause.**************

rlf PORTB,1 ;
call DELAY ;
call DELAY ;
rlf PORTB,1 ;
call DELAY ;
call DELAY ;
rlf PORTB,1 ;
call DELAY ;
call DELAY ;
rlf PORTB,1 ;
call DELAY ;
call DELAY ;
rlf PORTB,1 ;
call DELAY ;
call DELAY ;
rlf PORTB,1 ;
call DELAY ;
call DELAY ;
rlf PORTB,1 ;
call DELAY ;
call DELAY ;
rlf PORTB,1 ;

; *************Now move onto Port A, and move the bit left.***********

rlf PORTA,1 ;
call DELAY ;
call DELAY ;
rlf PORTA,1 ;

<!– /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:”"; margin:0in; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:”Times New Roman”; mso-fareast-font-family:”Times New Roman”;} @page Section1 {size:8.5in 11.0in; margin:1.0in 1.25in 1.0in 1.25in; mso-header-margin:.5in; mso-footer-margin:.5in; mso-paper-source:0;} div.Section1 {page:Section1;} –>

call DELAY ;
call DELAY ;
rlf PORTA,1 ;
call DELAY ;
call DELAY ;
rlf PORTA,1 ;
call DELAY ;
call DELAY ;

;************** Move the bit back on Port A************************

rrf PORTA,1 ;
call DELAY ;
call DELAY ;
rrf PORTA,1 ;
call DELAY ;
call DELAY ;
rrf PORTA,1 ;
call DELAY ;
call DELAY ;
rrf PORTA,1 ;

;****************** Now move the bit back on Port B******************

rrf PORTB,1 ;
call DELAY ;
call DELAY ;
rrf PORTB,1 ;
call DELAY ;
call DELAY ;
rrf PORTB,1 ;
call DELAY ;
call DELAY ;
rrf PORTB,1 ;
call DELAY ;
call DELAY ;
rrf PORTB,1 ;
call DELAY ;
call DELAY ;
rrf PORTB,1 ;
call DELAY ;
call DELAY ;
rrf PORTB,1 ;
call DELAY ;
call DELAY ;

goto RUN ;

; ******************Subroutine to give a delay between bit movements.******

DELAY

movlw TIME ;
movwf COUNT1 ;

LOOP1
;
decfsz COUNT1 ;
goto LOOP1 ;
movwf COUNT1 ;

LOOP2 ;
decfsz COUNT1 ;
goto LOOP2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This part resets the WDT
;;
;;Comment out or remove this command to see the WDT ;;
;; in action. It should reset the PIC
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

clrwdt ;This simply resets the WDT.


;***************Return from our original DELAY routine***************

return ;

END ;

If you comment out, or remove the CLRWDT command, you will find that the PIC will not go past lighting the second LED. This is because the WDT is resetting the PIC. With the CLRWDT in place, the program works as it should