1

I'm programming an Arduino Nano so I belive that this question should be qualified for this SE.

I am trying to dim up an LED using a for loop in AVR assembly.

My problem is that the cycle is repeated twice before ending, while it is suppose to end after the first cycle.

A cycle is when the red_loop is repeated 256 times (to dim the led up). At that point, the value should overflow causing the variable to go back to 0. The code should stop there, but mysteriously, it does another cycle and then it stops.

Does anyone know why?

Here is my code :

.org 0x000
ldi r16, 0b111
out ddrb, r16
ldi r16, 0xff
out portb, r16
ldi r16, 0
; ff00 pin
; ff01 value
; ff02 led
ldi r16, 0b000
sts $ff00, r16
ldi r16, 0
sts $ff01, r16
red:
 ldi r16, 0b001
 sts $ff00, r16
red_loop:
 rcall pwm
 lds r16, $ff01
 inc r16
 sts $ff01, r16
 cpi r16, 0
 brne red_loop
end:
 rjmp end
pwm:
 ldi r24, 190
pwm_pre_loop:
 ldi r17, 0
pwm_loop:
 lds r16, $ff01
 cp r17, r16
 brge off
 cp r17, r16
 brlo on
pwm_loop_check:
 inc r17
 cpi r17, 0
 brne pwm_loop
 inc r24
 cpi r24, 0
 brne pwm_pre_loop
 ret
on:
 lds r16, $ff00
 sbrc r16, 0
 cbi portb, 0
 sbrc r16, 1
 cbi portb, 1
 sbrc r16, 2
 cbi portb, 2
 rjmp pwm_loop_check
off:
 lds r16, $ff00
 sbrc r16, 0
 sbi portb, 0
 sbrc r16, 1
 sbi portb, 1
 sbrc r16, 2
 sbi portb, 2
 rjmp pwm_loop_check
asked Oct 7, 2018 at 16:56
13
  • you did not say what cycle means, so i am assuming that it means red_loop ..... are you sure that the red_loop repeats only two times?.... i am not very familiar with avr assembly instructions, but it looks like the red_loop repeats a lot more than two times Commented Oct 7, 2018 at 18:02
  • 1
    AVR asembly is not Arduino Commented Oct 7, 2018 at 18:35
  • 1
    What kind of Arduino is that? Unless you have something like 64K of SRAM, $ff00 is going to be out of range. Commented Oct 7, 2018 at 19:55
  • I suggest re-writing this code in C and taking a look at the assembly output of the compiler as a reference. Also, it might be a good idea to feed this into a simulator. E.g. avr-asm-tutorial.net/avr_sim/index_en.html Commented Oct 7, 2018 at 20:59
  • 1
    @Juraj I am programming an Arduino Nano, so this question should be qualified for this site. Commented Oct 7, 2018 at 21:04

1 Answer 1

1

The problem is that the register r17, which you use as a PWM timing ramp, overflows twice every time you enter pwm_pre_loop:

  • when you increments it past 127, it overflows to −128
  • when you increment it past 255, it overflows to 0.

When using a counter the way you are using r17 here, you usually have it overflow only once per cycle: either you consider it holds a signed number which overflows from 127 to −128, or you consider it holds an unsigned number which overflows from 255 to 0. I guess the latter is more common. Your code is confused about that register's signedness:

  • The instruction brge (named "Branch if Greater or Equal (Signed)" in the instruction set datasheet) tests the S (sign flag) bit of the status register, which is useful for signed comparisons.

  • The instruction brlo ("Branch if Lower (Unsigned)") tests the carry flag, which is used for unsigned comparisons.

You should decide once on the signedness of the counter, and then use it consistently. Since here unsigned makes more sense, you can just replace brge by brsh ("Branch if Same or Higher (Unsigned)").

Or better yet, remove the second test, which is redundant:

pwm_loop:
 lds r16, value
 cp r17, r16
 brsh off ; if (r17 >= r16) goto off;
 rjmp on ; else goto on;

Note by the way that you can name your RAM variables. And you can use some of the other available registers instead of the RAM.

answered Oct 8, 2018 at 9:20

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.