1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

PIC Delay calculator

Discussion in 'Microcontrollers' started by wmmullaney, Jan 12, 2008.

  1. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA
  2. Peter_wadley

    Peter_wadley New Member

    Joined:
    Mar 20, 2007
    Messages:
    376
    Likes:
    1
    It's a great tool for sure

    Saves alot of time!
     
  3. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA
    Yes it does, with this my binary clock's code should be a snap!
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,214
    Likes:
    640
    Location:
    Derbyshire, UK

    And both are mentioned lots of times all over these forums! :D

    The PICList one was around years before the EXE file one, and is the one I've always used (as mentioned in my tutorials).
     
  6. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA
    Oh, well i'd never seen it before.
     
  7. atferrari

    atferrari Well-Known Member

    Joined:
    Oct 8, 2003
    Messages:
    2,811
    Likes:
    121
    Location:
    Buenos Aires - Argentina
  8. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    You could also use a generic Delay subroutine and macro "front end" system that allows you to specify delays in cycles, microseconds, or milliseconds independent of Clock frequency.

    The 12 word 16 bit delay subroutine and macro "front ends" below can provide delays of 16..262159 cycles. And using the DelayCy() macro along with the msecs and usecs multipliers in the operand are especially handy for specifying delays plus or minus some number of cycles for precise isochronous timing.

    Food for thought. Regards, Mike

    Code (text):
    ;******************************************************************
    ;                                                                 *
    ;  DelayMS(), DelayUS(), DelayCy()    Mike McLaren, K8LH, Jun'07  *
    ;                                                                 *
    ;  a small 16-bit delay subroutine with macro "front ends" which  *
    ;  allow you to specify delays in msecs, usecs, or cycles.        *
    ;                                                                 *
    ;  requires the use of constant operands known at assembly time!  *
    ;                                                                 *
    ;  each delay macro call generates 4 instructions (for delays in  *
    ;  the ranges shown below).  longer delays up to several seconds  *
    ;  are possible but the macro produces 4 additional instructions  *
    ;  for every 262016 cycles in the delay.                          *
    ;                                                                 *
    ;     4 MHz, 1 cycles/usec, 16..262144 usecs, 1..262 msecs        *
    ;     8 MHz, 2 cycles/usec,  8..131072 usecs, 1..131 msecs        *
    ;    12 MHz, 3 cycles/usec,  6...87381 usecs, 1...87 msecs        *
    ;    16 MHz, 4 cycles/usec,  4...65536 usecs, 1...65 msecs        *
    ;    20 MHz, 5 cycles/usec,  4...52428 usecs, 1...52 msecs        *
    ;                                                                 *
    ;  here are some of the ways to generate a 1 millisecond delay;   *                                                               *
    ;                                                                 *
    ;       DelayMS(1)              ; delay 1 msec                    *
    ;       DelayUS(1000)           ; delay 1 msec                    *
    ;       DelayCy(1*msecs-2)      ; delay 1 msec minus 2 cycles     *
    ;       DelayCy(1000*usecs)     ; delay 1 msec                    *
    ;                                                                 *
    ;  use the DelayCy macro with the 'msecs' or 'usecs' multipliers  *
    ;  in the operand plus or minus some number of cycles to produce  *
    ;  precise clock independent isochronous timing.                  *
    ;                                                                 *
    ;******************************************************************
            radix   dec

    clock   equ     8               ; user clock frequency in MHz
    ;
    ;  DelayCy() operand multipliers
    ;
    usecs   equ     clock/4         ; cycles/microsecond multiplier
    msecs   equ     usecs*1000      ; cycles/millisecond multiplier
    ;                                                                 *
    ;  DelayMS(), DelayUS(), and DelayCy() macros                     *
    ;                                                                 *
    DelayMS macro   pDelay          ; milliseconds
            DelayCy(pDelay*msecs)   ; convert to cycles
            endm                    ;

    DelayUS macro   pDelay          ; microseconds
            DelayCy(pDelay*usecs)   ; convert to cycles
            endm

    DelayCy macro   pDelay          ; cycles (Tcy), minimum 16
            local   cycles
            cycles = pDelay
         while cycles > 262032
            movlw   high((262016-16)/4)+1
            movwf   TMRH
            movlw   low((262016-16)/4)
            call    DelayLo-(262016%4)
            cycles -= 262016
         endw
            movlw   high((cycles-16)/4)+1
            movwf   TMRH
            movlw   low ((cycles-16)/4)
            call    DelayLo-(cycles%4)
            endm
    ;                                                                 *
    ;  example code for simulation testing;                           *
    ;                                                                 *
    SimTest DelayCy(20*msecs)       ; remember to set 'clock' equate
            nop                     ; put simulator break point here
    ;                                                                 *
    ;******************************************************************
    ;                                                                 *
    ;  Delay(16..262159 Tcy) subroutine   Mike McLaren, K8LH, Jun'07  *
    ;                                                                 *
    ;  12 words, 1 RAM variable, 14-bit core                          *
    ;                                                                 *
    Delay.16
            nop                     ; entry point for delay%4 == 3    |B0
            nop                     ; entry point for delay%4 == 2    |B0
            nop                     ; entry point for delay%4 == 1    |B0
    DelayLo addlw   -1              ; subtract 4 cycle loop time      |B0
            skpnc                   ; borrow?  yes, skip, else        |B0
            goto    DelayLo         ; do another loop                 |B0
            nop                     ;                                 |B0
    DelayHi addlw   -1              ; subtract 4 cycle loop time      |B0
            decfsz  TMRH,F          ; done?  yes, skip, else          |B0
            goto    DelayLo         ; do another loop                 |B0
            goto    $+1             ; burn off 2 cycles               |B0
            return                  ;
    ;                                                                 *
    ;******************************************************************
     
    Here's an isochronous timing example. The first example uses the DelayMS() macro to generate a 1 msec delay for toggling the speaker pin. It doesn't take into account the 6 instruction cycles in the loop and will generate a slightly different tone for each Clock frequency. The second example uses the DelayCy() macro and the usecs or msecs multiplier in the operand and subtracts the 6 instruction cycles in the loop. The second example generates a precise 500 Hz tone no matter what Clock frequency you're using.

    Code (text):
    ;
    ;  key press beep
    ;
    ;  497.018 Hz --  4 MHz clock
    ;  498.504 Hz --  8 MHz clock
    ;  499.004 Hz -- 12 MHz clock
    ;  499.251 Hz -- 16 MHz clock
    ;  499.400 Hz -- 20 MHz clock
    ;
            bsf     Beep,5          ; do 32 msec switch press beep    |B0
    DoBeep  movf    PORTA,W         ; read port A                     |B0
            xorlw   1<<Spkr         ; toggle speaker bit              |B0
            movwf   PORTA           ; toggle speaker pin              |B0
            DelayMS(1)              ; delay 1 msec for 500 Hz tone    |B0
            decfsz  Beep,F          ; done?  yes, skip, else          |B0
            goto    DoBeep          ; loop (toggle Spkr pin again)    |B0
     
    Code (text):
    ;
    ;  key press beep
    ;
    ;  exact 500 Hz tone (any Clock frequency)
    ;
            bsf     Beep,5          ; do 32 msec switch press beep    |B0
    DoBeep  movf    PORTA,W         ; read port A                     |B0
            xorlw   1<<Spkr         ; toggle speaker bit              |B0
            movwf   PORTA           ; toggle speaker pin              |B0
            DelayCy(1*msecs-6)      ; delay 1 msec minus 6 cycles     |B0
            decfsz  Beep,F          ; done?  yes, skip, else          |B0
            goto    DoBeep          ; loop (toggle Spkr pin again)    |B0
     
     
    Last edited: May 6, 2008
  9. terry gao

    terry gao New Member

    Joined:
    Jan 14, 2008
    Messages:
    1
    Likes:
    0
    GOOD!Thank you!
     
  10. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA

    Thanks atferrari, too bad I don't have a pc LOL.:D

    Thanks Mike for the code.

    For whoever wants to know, I have most of my code down(For a clock), the next step is adding up all the instruction cycles and make a delay that is 60000000 cycles minus the total code cycles.

    I don't want my clock to be even a milisecond off every hour:p .
     
  11. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,214
    Likes:
    640
    Location:
    Derbyshire, UK
    I fear you are going to be GREATLY disappointed, your technique isn't likely to produce an accurate clock, and is going to be difficult to write as you have to ensure that ALL possible branches during the program take EXACTLY the same time.

    It's not impossible, and it has been done, but it's not the way to do it!.

    The far better way is to use timer2 to generate regular interrupts (tmr2 because it has many advantages over the others), and your interrupt routine increments registers and does the clock counting.
     
  12. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA
    alright, well it'll be accurate enough, off what, a minute a year?

    Just a few more questions, first, for a clock, is it ok to leave the PIC running for days? or weeks?

    Second, if the pic will run off of 3v, can I connect hight brightness blue leds directly to the pic?

    What is tmr2?

    I'm not very good with interrupts. Does anyone know of a good site that teaches you how to write the config word?
     
  13. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,214
    Likes:
    640
    Location:
    Derbyshire, UK
    I doubt you would get anywhere near that accuracy?.

    Yes, in many applications PIC's run 24 hours a day permanently.

    No, you should ALWAYS use current limiting of some kind.

    One of the three timer modules in most PIC's, it's useful because you can set it easily to give accurate repeatable interrupts.

    I don't see what the config word has to do with interrupts?, but the datasheet shows all the options, for 16 series PIC's it's pretty simple.
     
  14. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA
    Thanks Nigel.

    I didn't mean to run the two together.

    How accurate do you think it will be?
     
  15. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,214
    Likes:
    640
    Location:
    Derbyshire, UK
    Depends how accurately you write the code, like I said you've got to ensure that every single program branch throughout the entire program gets EXACTLY the same amount of time (this isn't easy - a LOT, LOT harder than an interrupt driven one).

    Here's some code I was playing with a year or two back, runs on a 16F876 at 20MHz.
     

    Attached Files:

  16. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA
    I'm just going to use the code I'v got.

    I read the datasheet. How do I do a config word? Is it done in hex? Can it be done in binary?

    What resistor value do you suggest as a current limiting resistor for high brightness blue leds with a pic running at 5v?
     
  17. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,214
    Likes:
    640
    Location:
    Derbyshire, UK
    Check any PIC code examples (like mine above), you can set it in hex (as I do), in binary, or (as many do) using long text strings full of AND'd from the include files.

    Use ohms law subtract the voltage drop of the LED from 5V to get the voltage, and decide what current you want, then apply ohms law to get the resistor.

    But it depends if you're multiplexing or not?.
     
  18. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA
    I'm not sure the voltage drop of the led, will 350 ohms be okay?

    Here's my clock code, how does it look?

    Code (text):

        ;********************
        ; Written by,       *
        ; William Mullaney  *
        ; On                *
        ; January 14, 2008  *
        ;                   *
        ; Binary Clock      *
        ; PIC16F628A        *
        ;********************
       
        LIST    p=16F628A
        include "p16f628a"
        __config 0x2118
       
        HOUR equ 20h
        MIN  equ 21h
        R1   equ 22h
        R2   equ 23h
        R3   equ 24h
       
        MOVLW    07h
        MOVWF    CMCON
        BSF      STATUS,    RP0
        MOVLW    b'11111111'
        MOVWF    TRISA
        MOVWF    TRISB
        BCF      STATUS,    RP0
       
    SHR BTFSS    PORTB,     08h
        GOTO     SHR
        MOVF     PORTA,     HOUR
       
    SMN BTFSS    PORTA,     08h
        GOTO     SMN
        MOVF     PORTB,     MIN
       
    CHK BTFSC    PORTA,     08h
        GOTO     CHK
       
        BSF      STATUS,    RP0
        MOVLW    b'00000000'
        MOVWF    TRISA
        MOVWF    TRISB
        BCF      STATUS,    RP0
       
    CLK CALL     DLY
        INCF     MIN,       1
        MOVF     MIN,       W
        BCF      STATUS,    C
        MOVLW    C3h
        BTFSS    STATUS,    C
        GOTO     PRT
        CLRF     MIN
        INCF     HOUR,      1
        MOVF     HOUR,      W
        BCF      STATUS,    C
        MOVLW    F3h
        BTFSS    STATUS,    C
        CLRF     HOUR
        INCF     HOUR,      1
       
    PRT MOVF     HOUR,      PORTA
        MOVF     MIN,       PORTB
        GOTO     CLK
       
    DLY CBLOCK
        R1
        R2
        R3
        ENDC
       
        MOVLW    22h
        MOVWF    R1
        MOVLW    CBh
        MOVWF    R2
        MOVLW    83h
        MOVWF    R3
       
    DY0 DECFSZ   R1,        F
        GOTO     $+2
        DECFSZ   R2,        F
        GOTO     $+2
        DECFSZ   R3,        F
        GOTO     DY0
        RETURN
     
    sorry it looks bad, something with my text editor.
     
  19. wmmullaney

    wmmullaney New Member

    Joined:
    Dec 11, 2006
    Messages:
    364
    Likes:
    6
    Location:
    USA

    Fixed a bug.
     
  20. David / W9GF

    David / W9GF New Member

    Joined:
    Apr 5, 2008
    Messages:
    17
    Likes:
    2
    Location:
    Dallas, Texas
    Excel Spreadsheet to help in calculating TIMER0 delays

    I created a small excel spreadsheet which i'm attaching that may be helpful in calculating the various delays available with a given clock frequency. All you need to enter is your clock frequency in mhz - everything else is calculated based on that.

    Enjoy!

    David

    Edit: An updated attachment is here: http://www.electro-tech-online.com/threads/pic-delay-calculator.35346/
     
    Last edited: Apr 9, 2008
  21. mike50

    mike50 New Member

    Joined:
    Jun 29, 2007
    Messages:
    103
    Likes:
    2
    Location:
    Rochester, Minnesota
    Here is a little program that will calculate the settings (prescale, postscale and PR2) for TMR2 to generate interrupts for whatever time interval you want. If it can generate settings for exactly what you want, it shows all the ways that can be achieved. If there are no settings to get exactly what you want it shows the closest values (one greater and one less than what you want).

    You run it as:

    TMR2 n

    where n is the timer interval you want in instruction cycles.

    examples:

    Code (text):
    C:>TMR2 10000
    10000 Prescaler 1:16 Postscaler 1:5  PR2 124
    10000 Prescaler 1:4  Postscaler 1:10 PR2 249

    C:>TMR2 1234
     1233 Prescaler 1:1  Postscaler 1:9  PR2 136
     1235 Prescaler 1:1  Postscaler 1:13 PR2  94
     

    The maximum value for n is 65536


    ---updated with program that doesn't require the C-runtime DLL---

    Mike
     

    Attached Files:

    • TMR2.zip
      File size:
      65.5 KB
      Views:
      186
    Last edited: Apr 9, 2008

Share This Page