Continue to Site

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.

  • 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.

delay code

Status
Not open for further replies.

savnik

Member
At the bellow code i want to set the variables Help1-Help2-Help3-Help4
for the delay 25,6 ms , but i don't know how.I use 16f88 and xtal 4 MHZ.Prescaler for TMR0 is 256.
Code:
Cycle 
    clrwdt            
    btfss INTCON,2     
    goto  Nothing 
    incf  Var1,F           
    bcf   INTCON,2                 
    goto  Nxt   
         
Nothing 
    nop           
    nop            
    nop  
                   
Nxt
    decfsz Help1,F
    goto   Cycle
    decfsz Help2,F
    goto   Cycle
    decfsz Help3,F
    goto   Cycle

Cycle2      
    btfss  INTCON,2 
    goto   Not2Do   
    incf   Var1,F 
    bcf    INTCON,2 
    goto   Nx       

Not2Do      
    nop               
    nop                
    nop                

Nx          
    decfsz Help4,F   
    goto   Cycle2  
    nop
    nop               
    nop
 
Last edited:
Using PicDel to calculate 25.6ms delay for 4MHz


Code:
;-------------------------------------------------------------
; Code generated by PDEL  ver 1.1  on 24-Jun-2009 at 08:06:16
; Description: Waits 25600 cycles
;-------------------------------------------------------------
PDelay  movlw     .191      ; 1 set number of repetitions (B)
        movwf     [COLOR="Red"]PDel0[/COLOR]     ; 1 |
PLoop1  movlw     .26       ; 1 set number of repetitions (A)
        movwf     [COLOR="Red"]PDel1[/COLOR]     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 cycle delay
        decfsz    [COLOR="Red"]PDel1[/COLOR], 1  ; 1 + (1) is the time over? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    [COLOR="Red"]PDel0[/COLOR],  1 ; 1 + (1) is the time over? (B)
        goto      PLoop1    ; 2 no, loop
        clrwdt              ; 1 cycle delay
        return              ; 2+2 Done
;-------------------------------------------------------------



Code requirements
-----------------
- Declaration of [COLOR="Red"]PDel0[/COLOR] (register) [COLOR="Red"](You may use Help_1)[/COLOR]
- Declaration of [COLOR="Red"]PDel1[/COLOR] (register) [COLOR="Red"](You may use Help_2)[/COLOR]
- 1 stack level

Example of use
--------------
call PDelay      ; Delay 25600 cycles (including call+return)
 
The delay code generators give you code for one specific delay using one specific clock frequency.

I prefer to use a more general purpose fixed delay subsystem that will work with almost any clock (4, 8, 12, 16, 20, etc.) and use delay parameters which can be specified in cycles, microseconds, or milliseconds. The subsystem uses 1 RAM variable and "overhead" is 9 words for the timing subroutine plus 4 words for each DelayCy() call.

Regards, Mike

Code:
;******************************************************************
;  K8LH DelayCy() subsystem macro generates four instructions     *
;******************************************************************
        [COLOR=Red]radix   dec[/COLOR]
clock   equ     4               ; 4, 8, 12, 16, 20 (MHz), etc.
usecs   equ     clock/4         ; cycles/microsecond multiplier
msecs   equ     clock/4*1000    ; cycles/millisecond multiplier

DelayCy macro   delay           ; 11..327690 cycle range
        movlw   high((delay-11)/5)+1
        movwf   delayhi
        movlw   low ((delay-11)/5)
        call    uDelay-((delay-11)%5)
        endm
;******************************************************************
        org     0x000
Example
        DelayCy(25600*usecs)    ; <- put simulator PC here
        goto    $               ; <- put simulator break point here

;******************************************************************
;  K8LH DelayCy() subsystem 16-bit timing subroutine              *
;  9 words, 1 RAM variable, 14-bit core                           *
        nop                     ; entry for (delay-11)%5 == 4     |B0
        nop                     ; entry for (delay-11)%5 == 3     |B0
        nop                     ; entry for (delay-11)%5 == 2     |B0
        nop                     ; entry for (delay-11)%5 == 1     |B0
uDelay  addlw   -1              ; subtract 5 cycle loop time      |B0
        skpc                    ; borrow? no, skip, else          |B0
        decfsz  delayhi,F       ; done?  yes, skip, else          |B0
        goto    uDelay          ; do another loop                 |B0
        return                  ;                                 |B0
;******************************************************************
The DelayCy() macro really isn't as complex as it looks. Basically it takes into account the instruction "overhead" of the macro and subroutine (11 cycles) and the 5 cycle subroutine loop time. The 'nop' instructions in front of the 5 cycle loop are used as subroutine entry points for delay values which are not multiples of 5 cycles.
 
Last edited:
savnik,

May I ask what range of frequencies you will be measuring with Timer 0? Is 25.6 msecs your total counter gate time? And do you need to recover the 1:256 Timer 0 prescaler value as part of the frequency count when you gate the T0CKI input off?

Mike, K8LH
 
savnik,

May I ask what range of frequencies you will be measuring with Timer 0? Is 25.6 msecs your total counter gate time? And do you need to recover the 1:256 Timer 0 prescaler value as part of the frequency count when you gate the T0CKI input off?

Mike, K8LH
I want to measure frequencies from 0,2 Mhz - 3 Mhz.
Yes the counter gate time is 25.6 msecs
And do you need to recover the 1:256 Timer 0 prescaler value as part of the frequency count
Yes
 
Well with a 3 MHz input signal you would overflow the 16 bit prescaler+tmr0 register pair in 21.845 msecs so you will need to use a pair of shorter delays totaling 25.6 msecs with a test for timer 0 overflow between them.

There's a trick to reading the contents of the prescaler. Let us know if you don't know how to do this.

Regards, Mike
 
Well with a 3 MHz input signal you would overflow the 16 bit prescaler+tmr0 register pair in 21.845 msecs so you will need to use a pair of shorter delays totaling 25.6 msecs with a test for timer 0 overflow between them.

There's a trick to reading the contents of the prescaler. Let us know if you don't know how to do this.

Regards, Mike
Thank you, yes i know the trick.
 
Good, you know the trick.

If it will help, here's an excerpt from a 50 MHz counter for 16F628A (or 12F683 with minor changes) where I need to test for TMR0 overflow which can occur at 1.31 msec intervals with a 50 MHz input.

Good luck on your project.

Regards, Mike

Code:
;
;  count frequency for precisely 200 msecs (5 Hz resolution)
;
NewCount
        clrf    TMR0            ; clear TMR0 and prescaler        |B0
        clrf    CountL          ; clear 24 bit counter variables  |B0
        clrf    CountH          ;                                 |B0
        clrf    CountU          ;                                 |B0
        movlw   200             ;                                 |B0
        movwf   MsecCtr         ; gate timer = 200 msecs          |B0
        movlw   TRISA           ;                                 |B0
        movwf   FSR             ; setup indirect access to TRISA  |B0
        bsf     INDF,4          ; TRISA.4 = 1, gate "on"          |B0
GateLoop
        btfsc   INTCON,T0IF     ; TMR0 overflow? no, skip, else   |B0
        incf    CountU,F        ; bump CountU                     |B0
        btfsc   INTCON,T0IF     ; TMR0 overflow? no, skip, else   |B0
        bcf     INTCON,T0IF     ; clear T0IF interrupt flag       |B0
        DelayCy(1*msecs-7)      ; delay 1 msec minus 7 cycles     |B0
        decfsz  MsecCtr,F       ; 200 msecs? yes, skip, else      |B0
        goto    GateLoop        ; loop again                      |B0
        bcf     INDF,4          ; TRISA.4 = 0, gate "off"         |B0
        btfsc   INTCON,T0IF     ; TMR0 overflow? no, skip, else   |B0
        incf    CountU,F        ; bump CountU                     |B0
        bcf     INTCON,T0IF     ; clear T0IF interrupt flag       |B0
;
;  capture 1:256 prescaler value
;
        movf    TMR0,W          ;                                 |B0
        movwf   CountH          ; save TMR0 value                 |B0
Flush   bsf     STATUS,RP0      ; bank 1                          |B1
        bcf     OPTION_REG,T0SE ; clock on rising edge            |B1
        bsf     OPTION_REG,T0SE ; clock on falling edge           |B1
        bcf     STATUS,RP0      ; bank 0                          |B0
        decf    CountL,F        ; decrement counter LSB           |B0
        movf    TMR0,W          ;                                 |B0
        xorwf   CountH,W        ; prescaler overflow into TMR0?   |B0
        bz      Flush           ; no, clock prescaler again       |B0
;
;  divide by 2 for 10 Hertz resolution
;
        clrc                    ; divide by 2 (10 Hz resolution)  |B0
        rrf     CountU,F        ;                                 |B0
        rrf     CountH,F        ;                                 |B0
        rrf     CountL,F        ;                                 |B0
;
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top