1

I have this code - all LEDs are turn on and off every 1 second (using MPLAB X IDE, assembler, oscillator frequency is 4MHz):

#include <p16f84a.inc>

    __CONFIG _WDTE_OFF & _PWRTE_OFF & _CP_OFF & _FOSC_HS

;General registers for delay
CounterA equ h'0c'
CounterB equ h'0d'
CounterC equ h'0e'

    org 0

Start:
    ; select bank 1
    bsf STATUS, RP0
    ; set port B as output
    movlw b'00000000'
    movwf TRISB
    ; select bank 0
    bcf STATUS, RP0

MainLoop:
    ; turn on LEDS
    movlw b'11111111'
    movwf PORTB
    call Delay_1s
    movlw b'00000000'
    movwf PORTB
    call Delay_1s
    goto MainLoop ;Repeat

Delay_1s:
    movlw d'6'
    movwf CounterC
    movlw d'24'
    movwf CounterB
    movlw d'168'
    movwf CounterA
loop:
    decfsz CounterA,1
    goto loop
    decfsz CounterB,1
    goto loop
    decfsz CounterC,1
    goto loop
    return

    end

Could someone explain how the Delay_1s is working? I have tried to multiply 168 * 24 * 6 = 24192 µS, but that is incorrect, I should get 1000000 µS..

EDIT:

I'm getting closer - decfsz CounterA,1 takes 1 µS, and goto loop takes 2 µS to process. So I think the answer should look like (168 * 3) * (24 * 3) * (6 * 3) = 653184 µS. Of cource I should add 6 µS while setting values to CounterA, CounterB and CounterC. Is there something I missing?

EDIT2:

I've added time valus to each operation below. Do I understand it right?

Delay_1s:
    movlw d'6' ; 1µS
    movwf CounterC ; 1µS
    movlw d'24' ; 1µS
    movwf CounterB ; 1µS
    movlw d'168' ; 1µS
    movwf CounterA ; 1µS
loop:
    decfsz CounterA,1 ; 1µS
    goto loop ; 2µS (the same while skipping)
    decfsz CounterB,1 ; 1µS
    goto loop ; 2µS (the same while skipping)
    decfsz CounterC,1 ; 1µS
    goto loop ; 2µS (the same while skipping)
    return ; 1µS ??
2
  • 1
    Been a while since I've done much PIC assembler, but I think the trick might be that for example CounterA will only be 168 first time then 256 the second time because it doesn't get reset. Does that add up if you work it out that way? Commented May 9, 2014 at 9:54
  • Yes, it could be - if CounterA and CounterB starts from 256 (CounterC only going to zero and then routine returns) - then the result is 390150, and if I multiply it by 3µS - then I get 1,170450 Sec Commented May 9, 2014 at 10:08

2 Answers 2

1

Sorry that I'm not good at explaining, but I hope this will give you some clue:

  Using a 4MHz Xtal OSC 
  Set OPTION_REG to b'11010100'
                     'xxxxx100' = 1 instruction :32 uSeconds
        32 uSeconds *    250 = 8 milliseconds
        8 milliseconds * 125 = 1 second 
        PORTB (all outs)     = B'00000000'                   

EIGHT_MS   EQU  0x10

INIT
      BSF  STATUS, RP0
      MOVLW      B'11010100'
      MOVWF      OPTION_REG
      MOVLW      B'00000000'
      MOVWF      TRISB
      BCF  STATUS, RP0
      CLRF       PORTB
      RETURN
START
L0    CLRF  TMR0
L1    MOVF  TMR0, W
      XORLW .250
      BTFSS STATUS, Z
      GOTO  L1
      CLRF  TMR0
      INCF  EIGHT_MS 
      MOVF  EIGHT_MS, W
      XORLW .125
      BTFSS STATUS, Z
      GOTO  L1
      CALL  LIGHT_LED
      GOTO  L1      

LIGHT_LED
      ...
      CALL DELAY
      ...

      RETURN


MAIN  
      CALL INIT
      CALL START
      GOTO MAIN
Sign up to request clarification or add additional context in comments.

Comments

1

I have reviewed this program and found that the number of cycles this routine spends is 1,003,827 which is equivalent to 1.003827 seconds.

I did it by three different methods and I have always got the same result.

Method 1: A formula Method 2: A simulation in Python Method 3: Using the MPLAB simulator, setting breakpoints and observing the cycle counter before and after the function call.

The formula is deduced as follows

Let's first ask ourselves how many cycles a program like the following takes:

loop: decfsz x, f This line runs x times, x-1 times does not jump and 1 time jumps, so the number of cycles is x-1) +2 goto loop This runs x-1 times so cycles are 2 (x-1) in total, cycles are (x-1) + 2 + 2 (x-1) = 3x-1 cycles

Let's consider that x is between 1 and 256 (includes 1 and 256, if x is 0, it equals 256)

So the number of cycles of the complete program is

Counter cycles A The first time when B has its initial value 3A-1 The following times of counter B (B-1) * (3 * 256-1) The next times of counter C (C-1) * 256 * 767 Counter B cycles The first time when C is 6 3B-1 The following times of C (C-1) * 767 Counter C cycles The first and only time 3C-1 The call, the Return and 6 initialization lines 10 ------------------------- total: 3A + 770B + 197 122C-197879

Substituting A for 168, B = 24 and C = 6 gives the value of 1,003,837 better values ​​would have been A = 172 B = 19 C = 6 which produces 999,999 adding a nop in variable initialization would give 1,000,000

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.