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.

Pulse generation measurement in simulation mode (ASM)

Status
Not open for further replies.

augustinetez

Active Member
Quick question regarding where to measure # of cycles/pulse duration during simulation of some code (example below) - mainly to make sure I'm doing it right -the brain is on holiday and something is niggling that the below might not be 100% accurate.

Scenario: Pulse overall is 1 second divided in to 'mark' of 100mS and 'space' of 900mS generated by a delay loop in the PIC.
Pulse is output by setting & clearing PORTA,0.

Please note that the code below has not been fine tuned for the 900mS space duration.

I have been measuring the 100mS using breakpoints in the Oshonsoft sim at line 2 & line 19 and the overall duration of 1 Second from line 2 until it loops back to line 1.

My reasoning for measuring at those points is that PORTA doesn't change state until after it processes the BSF/BCF commands and that the total duration measurement of 1Sec is from the moment PORTA goes high to the point immediately before it goes high on the next loop through.
Code:
   p6a
1     bsf    PORTA,0
2    movlw    D'3'        ;PIC Time Delay = 0.09999980 s with Osc = 20MHz
3    movwf    CounterC
4    movlw    D'138'
5    movwf    CounterB
6    movlw    D'84'
7    movwf    CounterA
    loop6
8    decfsz    CounterA,1
9    goto    loop6
10    decfsz    CounterB,1
11    goto    loop6
12    decfsz    CounterC,1
13    goto    loop6
14    NOP
15    NOP
16    btfss    PORTA,3        ; is switch pressed?
17    goto    incrat
18    bcf    PORTA,0

19    movlw    D'23'        ;PIC Time Delay = 0.90000040 s with Osc = 20MHz
20    movwf    CounterC
21    movlw    D'213'
22    movwf    CounterB
23    movlw    D'21'
24    movwf    CounterA
    loop6a
25    decfsz    CounterA,1
26    goto    loop6a
27    decfsz    CounterB,1
28    goto    loop6a
29    decfsz    CounterC,1
30    goto    loop6a
31    goto    p6a
 
I normally use timer1 to count cycles but it's limited to 65536 cycles which is too short in your case.

Mike.
 
Just had to look at a more modern pic to see what SMT is. Even at 24 bit it can't manage 900mS at 20MHz!!!! Actually, at Fosc/4 it can.

Mike.
 
Just had to look at a more modern pic to see what SMT is. Even at 24 bit it can't manage 900mS at 20MHz!!!! Actually, at Fosc/4 it can.

Mike.
Depends how you set it, I'm using it for measuring up to over 10 seconds (times out at 15 seconds) with 1uS resolution and a 32MHz processor. Can't do it at 64MHz though, not and get direct 1uS resolution.

So 900mS at 20MHz is simple.

Be aware though, it's very complicated and confusing.
 
There are times when a "cycle accurate" fixed delay subsystem comes in handy (see below)...

Stay safe. Cheerful regards, Mike, K8LH

Code:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        include <P16F628A.inc>
        errorlevel -302         ; suppress bank warnings
        list st=off             ; suppress symbol table
        radix   dec             ; default radix = decimal

  __CONFIG _LVP_OFF & _WDT_OFF & _INTOSC_OSC_NOCLKOUT & _MCLRE_OFF

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;            variables            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        cblock  0x70            ; common RAM
delayhi                         ; DelayCy() subsystem variable
        endc

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  K8LH DelayCy() subsystem macro generates four instructions     ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        radix dec
clock   equ     4               ; 4, 8, 12, 16, 20 (MHz), etc.
usecs   equ     clock/4         ; cycles/microsecond multiplier
msecs   equ     usecs*1000      ; cycles/millisecond multiplier
dloop   equ     16              ; loop size (minimum 5)
;
;  -- loop --  -- delay range --  -- memory overhead ----------
;  5-cyc loop, 11..327690 cycles,  9 words (+4 each macro call)
;  6-cyc loop, 11..393226 cycles, 10 words (+4 each macro call)
;  7-cyc loop, 11..458762 cycles, 11 words (+4 each macro call)
;  8-cyc loop, 11..524298 cycles, 12 words (+4 each macro call)
;
DelayCy macro   cycles          ; range, see above
    if (cycles<11)|(cycles>(dloop*65536+10))
        error " DelayCy range error "
    else
        movlw   high((cycles-11)/dloop)+1
        movwf   delayhi
        movlw   low ((cycles-11)/dloop)
;       rcall   uLoop-(((cycles-11)%dloop)*2)    ; (18F version)
        call    uLoop-((cycles-11)%dloop)        ; (16F version)
    endif
        endm

;******************************************************************
;  reset vector                                                   *
;******************************************************************
        org     0x000
loop
        bsf     PORTA,0         ; RA0 = 1                         |B0  <-- breakpoint here
        DelayCy(100*msecs-3)    ; 100-msecs minus 3 cycles        |B0
        btfss   PORTA,3         ; switch press? no, skip, else    |B0
        goto    incrat          ; branch (exit loop)              |B0
        bcf     PORTA,0         ; RA0 = 0                         |B0  <-- breakpoint here
        DelayCy(900*msecs-3)    ; 900-msecs minus 3 cycles        |B0
        goto    loop            ;                                 |B0
incrat

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  K8LH DelayCy() subsystem 16-bit uLoop subroutine               ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

a = dloop-1
    while a > 0
        nop                     ; (cycles-11)%dloop entry points  |
a -= 1
    endw
uLoop   addlw   -1              ; subtract 'dloop' loop time      |
        skpc                    ; borrow? no, skip, else          |
        decfsz  delayhi,F       ; done?  yes, skip, else          |
;       bra  uLoop-dloop*2+10   ; do another loop (18F version)   |
        goto uLoop-dloop+5      ; do another loop (16F version)   |
        return                  ;                                 |
 
Last edited:
Hi Mike.

Now that looks interesting, might have a play with that later.

Actually, seeing part of it rewritten by someone else points out a minor error - PORTA,0 is not cleared if it detects a switch push and jumps out - note to self fix that :)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top