Tmr0 delay routine not working

Thread Starter


Joined Jun 22, 2012
Trying to get a delay using the tmr0 on the pic16f628a,i can make a delay ok without it, but how do you use the TMR0, prescaler set to tmr0 at 1/16 at 4mhz clock, this is my programme>>


cblock 0x20
d1 ; working variable,
d2 ; working variable,
d3 ; used by delay function
d4 ; used by delay fucnction
; Define bank select pseudo instructions to make code more readable
#define bank0 bcf STATUS,RP0 ; Sel Bank 0
#define bank1 bsf STATUS,RP0 ; Sel Bank 1

RESET_VECTOR org 0x000

movlw b'00000111' ; disable comparators by setting CM2:CM0 == 111
movwf CMCON ; See 16F628A datasheet section 10.0
bank1 ; set to register bank 1

movlw b'10000011' ;set prescaler to tmr0 at 1/16 clock, pull ups off
clrf TRISA ; set PORTA as output
clrf TRISB ; set PORTB as output

bank0 ; set to register bank 0

bsf PORTB,3
bcf PORTB,4
call delay
bcf PORTB,3
bsf PORTB,4
call delay
goto start

delay ;delay of 500msec
movlw .125 ;osc at 4mhz so 1usec instruction speed
movwf d1 ;tmro set to 1/16 prescaler so 16us X 250=4msec
; 4msec X 125 = 500msec or 1/2 sec.
movlw .5 ;preload tmr0 with 5
movwf TMR0
movf TMR0,f ;move tmr0 through w reg
btfss STATUS,Z ;has it gone to zero
goto $-1 ;no do it again
decfsz d1,f ;yes decrease file d1
goto more ;do it 125 times


Last edited:


Joined Sep 7, 2009
I think it might work if you change goto $-1 to goto $-2 and movf TMR0,f to movf TMR0, W
There's a slight problem in that every time you write to the timer, the prescaler count gets reset (not the 1/16 prescaler value) and also the timer then stops incrementing for 2 instruction cycles.
Something like this (needs a little tweaking to get it perfect).

Rich (BB code):
;trying to count 500000 instruction cycles = 31250 * 16 = (122 * 256 + 18) * 16
    movlw d'256'-d'18'   ;initial timer value makes first timer rollover happen after 18*16 instruction cycles
    movwf TMR0
    movlw d'123'
    movwf d1
    movf TMR0, W            ;this section needed so that TMR0=0 
    btfsc STATUS, Z            ;is only tested once per rollover
    goto pre_delay_loop
    movf TMR0, W
    btfss STATUS, Z
    goto delay_loop
    decfsz d1, F
    goto pre_delay_loop
Last edited: