RET after doing BRCC

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

I wrote this short code for a delay (in processor cycles), but after doing BRCC, RET won't work, here is my code: 

setup:
	ldi r16, 0x20
	ldi r17, 0
	out DDRB, r16
loop:
	out PORTB, r17
	push r16
	ldi r16, 0xFF
	rcall delay
	pop r16
	out PORTB, r16
	rjmp loop
delay: ;1(ldi) + 3(rcall) + 4(ret) + 1(carry set) + n * 2(carry clear) cycles
	dec r16
	brcc delay
	ret

 

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

RET relies on the stack being set - is it?

 

(or in other words, is this a modern AVR that sets SP to RAMEND at power on or is it an old model where it defaulted to 0x00(00) and you need to set it manually?)

 

EDIT: BTW I would put at least one line of white space after the "RJMP loop" line so that it's clear that the code at "delay:" is a sub-routine and not just a continuation of the main loop code

EDIT2, if you want to see both states of R16 then don't you need to delay after BOTH of the OUT instructions? Also why all that messing with PUSH and POP when you have 32 registers (16 of them easily LDIable) to hold states?

Last Edited: Mon. Dec 4, 2017 - 05:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I'd go with:

setup:
    ldi r16, 0x20
    ldi r17, 0
    ldi r18, 0xFF ; delay counter (no need to set multiple times)
    out DDRB, r16
loop:
    out PORTB, r17
    rcall delay
    out PORTB, r16
    rcall delay
    rjmp loop

delay: ;1(ldi) + 3(rcall) + 4(ret) + 1(carry set) + n * 2(carry clear) cycles
    dec r18
    brcc delay
    ret

Only thing is that even at 1MHz that delay is SO short that if the outputs are LEDs you aren't going to see anything as it will be switching on/off so fast it will look like it's just on half the time constantly. Maybe consider:

delay: ;1(ldi) + 3(rcall) + 4(ret) + 1(carry set) + n * 2(carry clear) cycles
        ldi r19, 255
delay1:
        dec r19
        brne delay1
	dec r18
	brcc delay
	ret

which delays roughly 255*255 times the number of cycles in that.

Last Edited: Mon. Dec 4, 2017 - 05:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This still doesn't work though, it just gets stuck in the delay loop and i know it because when i remove the BRCC it starts working again, also i don't need the delay for LEDs, i'm trying to get a 350 nanosecond delay for ws2812 and also i am using an arduino nano so it should be running at 16MHz

Last Edited: Mon. Dec 4, 2017 - 05:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The "DEC" instruction doesn't affect the "C" flag. You have an infinite loop if carry is clear before the loop starts.

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

aj22r wrote:

This still doesn't work though...

 

How do you know it doesn't work?

 

How have you set SP?

 

What chip are you using?

 

How are you clocking your chip?

 

Why not just use...

 

NOP

NOP

NOP

NOP

NOP

 

(or however many you need)

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

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

Thanks, it works now with SUBI r18, 1

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

Note: DEC does not affect the C bit.

 

Edit: Just realized I missed Post #5...

 

David

Last Edited: Mon. Dec 4, 2017 - 06:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aj22r wrote:
Thanks, it works now with SUBI r18, 1

Next time, show a COMPLETE test program so that we do not need to guess...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

aj22r wrote:

...i'm trying to get a 350 nanosecond delay for ws2812 and also i am using an arduino nano so it should be running at 16MHz

 

You cannot get a 350ns delay at 16MHz.

 

16MHz = 62.5ns. 350/62.5 = 5.6. So you can either have (6 x 62.5) = 375ns or (5 x 62.5) = 312.5ns.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

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

Just a note to say that this was a perfect case, already at post #1, for debugging in the simulator of Atmel Studio. The reason the branch was not taken would likely have been obvious within minutes. I.e.:

 

- Wooot? No branch!?!

[run again]

- Wooot? No Carry flag?!

[goes to check insstruction set manual]

- Ach! Need subi!

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

note that "dec" does set the zero flag, so you could change the "brcc" to "brne" in the original code, and have it work (one loop less, of course, but the same overall range.)