Tiny15 ASM. Code not executing properly.

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi folks, trying to learn assembly so making a simple exposure controller for my Canon 350D.

I`m currently in the "have no idea what i`m doing"-stage, so this is probably a very simple error.

This code should turn on PB4 after 1sec, but it takes roughly 25secs before it is turned on. If i put the SBI inside the interrupt, It does turn on correctly.

Anyone got a tip for totally blank asm-guy??

; ============================================
;   R E G I S T E R   D E F I N I T I O N S
; ============================================
;
; [Add all register names here, include info on
;  all used registers without specific names]
; Format: .DEF rmp = R16
.DEF tmp = R16 ; Multipurpose register
.DEF Counter1 = R17 ; Low byte of Counter1
.DEF Second = R18 ; Counts number of seconds
.DEF Minute = R19 ; Counts the number of minutes


; ============================================
;   R E S E T   A N D   I N T   V E C T O R S
; ============================================
;
.CSEG
.ORG $0000
    rjmp Main ; Reset vector
    reti ; Int vector 1
    reti ; Int vector 2
    reti ; Int vector 3
    reti ; Int vector 4
    rjmp TIMER0_OVF ; Int vector 5
    reti ; Int vector 6
    reti ; Int vector 7
    reti ; Int vector 8
;
; ============================================
;     I N T E R R U P T   S E R V I C E S
; ============================================
;
; [Add all interrupt service routines here]
;
TIMER0_OVF:
    inc Counter1 ; Increment counter
    cpi Counter1,25 ;
    breq Increment_Seconds ; Branch to exit interrupt
    rjmp T0_Done; Exit interrupt

Increment_Seconds:
    ldi Counter1, 0; Reset counter1
    inc Second ; Increment number of seconds
    cpi Second, 60; Compare second to 60sec
    breq Increment_Minutes ; Branch if equal
    rjmp T0_done

Increment_Minutes:
    ldi Second, 0
    inc Minute;
    rjmp T0_done

T0_done:
reti
; ============================================
;     M A I N    P R O G R A M    I N I T
; ============================================
;
Main:
; [Add all other init routines here]
        
    ldi tmp, 0x05;
    out TCCR0, tmp; Prescaler 1024 on Timer0
    ldi tmp, 0x10;
    out DDRB, tmp; PB4 Output to shutter release;
    ldi tmp, 0x0F;
    out PORTB, tmp; ; Enable internal pullups on PORTB inputs

    ldi tmp, (1 << TOIE0)
    out TIMSK, tmp ; Enable timer0 overflow interrupt
    sei
;
; ============================================
;         P R O G R A M    L O O P
; ============================================
;
Loop:
    cpi Second, 0x01;
    breq Turn_on_led;
    rjmp Loop;
    
Turn_on_led:
    sbi PORTB, PORTB4 
    rjmp Loop ; go back to loop
;
; End of source code

rjmp Loop;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

This code should turn on PB4 after 1sec, but it takes roughly 25secs

What is F_CPU?

The interrupt will be called at a frequency of F_CPU/256/1024. So if F_CPU is 1MHz then the interrupt will occur at 1E6/356/1024=3.814Hz. As you count the counter up to 25. The seconds increment will happen at 1/25th of this. So 0.1526Hz which is a period of 6.5536 seconds. If you say it takes 25s (could it really be 26.214s?) then it suggests that the F_CPU is 1/4 of 1MHz. I wonder if you are trying to use a 2MHz crystal but have CKDIV8 set perhaps?

BTW for this kind of thing CTC mode makes things MUCH easier!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, the F_CPU is constant 1.6MHz internal on this chip. And there is no CKDIV8 either.

The prescaler were supposed to be 256, forgot to change back the code after som testing.
So i got, 1600000/256/256 = 24.414hz, after 25 interrupts it should end up at 1.024sec.

It seems that the time is varying a bit too, just measured ~23secs from reset to the led turning on.

I agree about the CTC mode beeing better, but high precision is really not necessery as the exposures is in the range of 30-600secs. The temperature swing will most likely cause more drift than the 2.5% error anyway.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't see any init of Second (R18)

or counter1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm intrigued. Almost all AVRs have either a 1MHz int RC or an 8MHz RC divided by 8 as default, making either 1MHz (approx). Those that don't tend to have a 9.6MHz RC divided by 8 to give 1.2Mhz. So which model has a 1.6MHz internal oscillator?

Enquiring minds need to know!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The tiny15 is one of a kind!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

and that is why tiny25 45 85 can be programmed to 6.4MHz with that the timer with PLL can reach the same speed 25.6 MHz.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Doh! I just realised it says "tiny15" in the thread title. :oops:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You don't save SREG when entering ISR.
Since you do a compare in ISR this might change the state of SREG and bite you in the main loop.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Added the register init and saving/restoring SREG, works a treat. Thanks all, would NEVER have tought of that myself!! :)