Pic16F88 delay routine

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

  1. Dodgydave

    Thread Starter Distinguished Member

    Jun 22, 2012
    4,967
    744
    I am trying to make a 1sec delay using a pic16f88 with the following>>

    int osc set to 8mhz,
    so does that mean each instruction cycle takes 1/2 micro-second 2 mhz clock cycles?

    so 250 x 250 x 32 =2000000 1/2 micro seconds( 1 second)

    and this is my programme

    DELAY_1S
    movlw .32
    movwf t3
    more1 movlw .250
    movwf t2
    more movlw .250
    movwf t1
    decfsz t1,f
    goto $-1
    decfsz t2,f
    goto more
    decfsz t3,f
    goto more1
    return


    will this work or not, or do you have an easier way?:confused:
     
  2. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    The instructions don't all take 1 instruction cycle, goto takes two and decfsz takes one or two. Also there are more than one instruction in each loop. That code will take several seconds assuming everything else is right.
    You can use trial and error along with the stopwatch in MPLab simulator.
    There is also a calculator here:
    http://www.golovchenko.org/cgi-bin/delay

    If accuracy is critical, don't forget the 4 cycles for the call and return.
     
  3. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    messy to adjust and to use.

    Better use the timer interrupt for instance to get 1/100 sec. ticks,
    and then use counter variable to accumulate timer ticks.

    In C this is just a few lines, in assembler, can become lenghty,
    if you use different delays. I had clocking distribution systems stretching over 3 pages or so.

    Imagine taking care about the cycles each time, and calculate the values!
     
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Here is an example. I also noticed that you are skimping on comments. Not a good practice
    Code ( (Unknown Language)):
    1.  
    2.     cblock 0x20
    3. Delay1                   ; Define two file registers for the
    4. Delay2                   ; delay loop
    5.      endc
    6.      
    7.      org 0
    8. Start:
    9.      bsf       STATUS,RP0          ; select Register Page 1
    10.      bcf       TRISC,0             ; make IO Pin B.0 an output
    11.      bcf       STATUS,RP0          ; back to Register Page 0
    12. MainLoop:
    13.      bsf       PORTC,0             ; turn on LED C0
    14. OndelayLoop:
    15.      decfsz    Delay1,f            ; Waste time.  
    16.      goto      OndelayLoop         ; The Inner loop takes 3 instructions per loop * 256 loopss = 768 instructions
    17.      decfsz    Delay2,f            ; The outer loop takes and additional 3 instructions per lap * 256 loops
    18.      goto      OndelayLoop         ; (768+3) * 256 = 197376 instructions / 1M instructions per second = 0.197 sec.
    19.                                    ; call it a two-tenths of a second.
    20.      
    21.      bcf       PORTC,0             ; Turn off LED C0
    22. OffDelayLoop:
    23.      decfsz    Delay1,f            ; same delay as above
    24.      goto      OffDelayLoop
    25.      decfsz    Delay2,f
    26.      goto      OffDelayLoop
    27.      goto      MainLoop            ; Do it again...
    28.      end
    29.      
    30.  
     
  5. Dodgydave

    Thread Starter Distinguished Member

    Jun 22, 2012
    4,967
    744
    Thanks for that this helps me, your delay uses 197376 cycles, so would preloading 10 to Delay1 add an extra 30cycles?

    So if i pre loaded files "Delay1 & Delay2" with say 10, how many more cycles would it take?

    if you can explain how to work it out it would be helpful to me?
     
    Last edited: Jun 26, 2012
  6. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    The example is taken from here http://www.microchip.com/Microchip.WWW.SecureSoftwareList/secsoftwaredownload.aspx?device=en023805&lang=en&ReturnURL=http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en023805## the Low Pin Count User's Guide. However the best teacher is often your self. And a very useful tool in self teaching is to learn how to do debugging. Like using the MPLAB software simulator single stepping, watches and different types of break points. Take a look at the first post here http://forum.allaboutcircuits.com/showthread.php?t=44852
     
  7. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    If you set the inner loop variable to 10 at some point before the loops then instead of counting down from 0 to 0 (it rolls over from 0 to 255 when counting down), it counts down from 10 to 0 so shortens the time by 3X245 cycles. If you set the inner loop variable each time it goes through the outer loop then the reduction gets multiplied by 256 (with some adjustment for the code that changes the counter).
    If you want to make it longer try adding a nop to after "OnedelayLoop" or before "decfsz Delay2,f"
    The first should make the delay about 33% longer, the second should add 256 cycles.

    The first time through the delay could take any time below the normal time because the variables are not initialised.
     
  8. Dodgydave

    Thread Starter Distinguished Member

    Jun 22, 2012
    4,967
    744
    Can some one help me solve this as i am banging my head ,its just a simple 1hz led flasher on pin RA0,

    i have built the asm file, programmed it and put the pic in the circuit board, all that happens is all the pins are at 2v op,with 2.6v ac signal , except the supply pins at 5volts .

    Is there some thing in the programme i have done wrong or are my pics faulty?? :mad:

    ;This is to flash an led on pin ra0 at 1hz



    LIST p=16F88 ;tell assembler what chip we are using
    #include <P16F88.inc> ;include the defaults for the chip
    ;set up config register

    __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO
    __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF

    org 0x0000 ;org sets the origin, 0x0000 for the 16F88,
    ;this is where the program starts running
    goto Loop

    cblock 0x20
    d1
    d2
    d3
    endc
    bsf STATUS, RP0 ;select bank 1
    movlw b'01110110' ;set osc to 8mhz
    movwf OSCCON
    movlw b'11000110' ;set up prescaler to 128 on Tmr0
    movwf OPTION_REG

    movlw b'00000000' ;set PortA all outputs
    movwf TRISA
    movlw b'11111111'
    movwf TRISB ;set PortB all inputs
    bcf STATUS, RP0 ;select bank 0
    clrf PORTA ;clear portA
    clrf PORTB

    Loop
    bsf PORTA,0
    ;set bit 0 on
    call Delay
    ;
    bcf PORTA,0
    call Delay ;set bit0 off
    goto Loop ;go back and do it again
    Delay

    ;delay of 500msec at 8mhz clock
    ;999997 cycles
    movlw 0x08
    movwf d1
    movlw 0x2F
    movwf d2
    movlw 0x03
    movwf d3
    Delay_0
    decfsz d1, f
    goto $+2
    decfsz d2, f
    goto $+2
    decfsz d3, f
    goto Delay_0
    ;3 cycles
    goto $+1
    nop

    return
    end
     
  9. absf

    Senior Member

    Dec 29, 2010
    1,490
    371
    Code ( (Unknown Language)):
    1. LIST p=16F88 ;tell assembler what chip we are using
    2. #include <P16F88.inc> ;include the defaults for the chip
    3. ;set up config register
    4.  
    5. __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO
    6. __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
    7.  
    8. org 0x0000 ;org sets the origin, 0x0000 for the 16F88,
    9. ;this is where the program starts running
    10. goto Loop
    11.  
    12. cblock 0x20
    13. d1
    14. d2
    15. d3
    16. endc
    17. bsf STATUS, RP0 ;select bank 1
    18. movlw b'01110110' ;set osc to 8mhz
    19. movwf OSCCON
    20. movlw b'11000110' ;set up prescaler to 128 on Tmr0
    21. movwf OPTION_REG
    22. [COLOR="Red"]
    23. movlw 0x00
    24. movwf ANSEL[/COLOR]
    25.  
    26. movlw b'00000000' ;set PortA all outputs
    27. movwf TRISA
    28. movlw b'11111111'
    29. movwf TRISB ;set PortB all inputs
    30. bcf STATUS, RP0 ;select bank 0
    31. clrf PORTA ;clear portA
    32. clrf PORTB
    33.  
    34. Loop
    35. bsf PORTA,0
    36. ;set bit 0 on
    37. call Delay
    38. ;
    39. bcf PORTA,0
    40. call Delay ;set bit0 off
    41. goto Loop ;go back and do it again
    42. Delay
    43.  
    44. ;delay of 500msec at 8mhz clock
    45. ;999997 cycles
    46. movlw 0x08
    47. movwf d1
    48. movlw 0x2F
    49. movwf d2
    50. movlw 0x03
    51. movwf d3
    52. Delay_0
    53. decfsz d1, f
    54. goto $+2
    55. decfsz d2, f
    56. goto $+2
    57. decfsz d3, f
    58. goto Delay_0
    59. ;3 cycles
    60. goto $+1
    61. nop
    62.  
    63. return
    64. end
    Port A is default to analog when pic is started up. Just add the 2 lines in red to initialize them to digital should solve your problem.

    Allen
     
    Last edited: Jun 29, 2012
  10. Dodgydave

    Thread Starter Distinguished Member

    Jun 22, 2012
    4,967
    744
    Tried the two lines movlw 0x0
    movwf ANSEL

    STILL NOT WORKING!
    all pins are sat at 2volts

    so what else is wrong?

    if you have a simple prog that works on the 16f88 to flash an led can you upload it
     
  11. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Still not using the simulator and stopwatch?
    Your goto $+2 lines make the delay much shorter than the goto $-2 that you probably intended.

    <ed> My mistake, the delay code works fine. </ed>
     
    Last edited: Jun 29, 2012
Loading...