Tmr0 delay routine not working

Discussion in 'Programmer's Corner' started by Dodgydave, Jun 30, 2012.

  1. Dodgydave

    Thread Starter Distinguished Member

    Jun 22, 2012
    4,969
    744
    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>>


    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _LVP_OFF

    cblock 0x20
    d1 ; working variable,
    d2 ; working variable,
    d3 ; used by delay function
    d4 ; used by delay fucnction
    endc
    ;------------------------------------------------------------------------------------
    ; 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
    movwf OPTION_REG
    clrf TRISA ; set PORTA as output
    clrf TRISB ; set PORTB as output

    bank0 ; set to register bank 0



    start
    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.
    more
    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


    return

    end
     
    Last edited: Jun 30, 2012
  2. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    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).

    Code ( (Unknown Language)):
    1. delay
    2. ;trying to count 500000 instruction cycles = 31250 * 16 = (122 * 256 + 18) * 16
    3.     movlw d'256'-d'18'   ;initial timer value makes first timer rollover happen after 18*16 instruction cycles
    4.     movwf TMR0
    5.     movlw d'123'
    6.     movwf d1
    7. pre_delay_loop
    8.     movf TMR0, W            ;this section needed so that TMR0=0
    9.     btfsc STATUS, Z            ;is only tested once per rollover
    10.     goto pre_delay_loop
    11. delay_loop
    12.     movf TMR0, W
    13.     btfss STATUS, Z
    14.     goto delay_loop
    15.     decfsz d1, F
    16.     goto pre_delay_loop
    17.     return
     
    Last edited: Jun 30, 2012
  3. Dodgydave

    Thread Starter Distinguished Member

    Jun 22, 2012
    4,969
    744
    Well i fixed my timer routine it was the line MOVF TMRO,F SHOULD HAVE BEEN MOVF TMRO,W . Doh!
     
Loading...