5
\$\begingroup\$

I am learning programming MCU with c

I am using atmel studio 7, averdude, USBasp and Atmega16a

this is my code

#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>


int main(void) {

DDRA = 0xff;
DDRC = 0xff;

while (1) {
    for (uint8_t i = 8; i >= 0; i--) {
        PORTA = (1 << i);
        _delay_ms(100);
    }

    PORTC = 1;
    _delay_ms(1500);
}

return (0);
}

the for loop never finished and when it reaches i=0 the first LED in PORTA stays on for about 14 seconds and turn off after that for about the same time and after that the for loop starts again without reaching

PORTC =1;
_delay_ms(1500);

when I use int instead of uint8_t it works fine

can someone explain why is this happening ?

\$\endgroup\$
  • 5
    \$\begingroup\$ I'm voting to close this question as off-topic because not about electronics. Appears to belong on Stack Overflow. \$\endgroup\$ – Brian Carlton Oct 28 '15 at 1:19
  • 2
    \$\begingroup\$ Since when are embedded programming questions off-topic? \$\endgroup\$ – Adam Haun Oct 28 '15 at 12:02
  • \$\begingroup\$ @BrianCarlton If it gets closed, I'll benignly migrate it to StackOverflow. Not going to force this, though. \$\endgroup\$ – Nick Alexeev Oct 28 '15 at 22:20
  • \$\begingroup\$ @brain carlton I thought because it is embedded related question it would belongs to electronics, according to you any programming questions even if it is related to electronics would be on SOF, ok got it. thanks \$\endgroup\$ – Muhammad Nour Oct 29 '15 at 12:36
  • 1
    \$\begingroup\$ @MuhammadNour Don't worry too much about this. The border between embedded programming questions and plain programming questions is not clearly demarcated. In the worst case, your question would be migrated to StackOverflow. In this case, you thought that the question was embedded, but the answer turned out to be more a less plain programming (signed vs. unsigned). \$\endgroup\$ – Nick Alexeev Nov 3 '15 at 3:57
14
\$\begingroup\$

You arrive to the point where the value of i is o.
i >= 0 is true.
You try to decrement with i--. Perhaps, you are expecting a negative number. But i is unsigned, so you get 255.
It keep decrementing until you get to zero. Then everything repeats again.

If i were signed, then the loop would make 9 iterations.

The following code does not have this ill effect. Notice the strict inequality. This loop will iterate 8 times.

for (uint8_t i = 8;  i > 0;  i--) { // strictly greater
    // [...]
}
\$\endgroup\$
5
\$\begingroup\$

"i >= 0" is always true because i is unsigned.

\$\endgroup\$
  • 1
    \$\begingroup\$ The wonders of 0-1 = 255. \$\endgroup\$ – Tom Carpenter Oct 28 '15 at 0:31
3
\$\begingroup\$

If you wanted to iterate over i = 7, 6, ..., 0 with an unsigned index variable, the usual pattern is

for (uint8_t i = 8; i-- > 0; ) {
    PORTA = (1 << i);
    _delay_ms(100);
}

although this looks weird the first time you see it. Some people prefer to always have increasing loops:

for (uint8_t ii = 0; ii < 8; ++ii) {
    uint8_t i = 7 - ii;
    PORTA = (1 << i);
    _delay_ms(100);
}

You can't use i >= 0 as the test, because unsigned values wrap around; decrementing 0 gives 255.

If what you meant to do is to iterate over i = 8, 7, ...,1, then you just had a typo, and the loop test should have been i > 0.

\$\endgroup\$
  • \$\begingroup\$ Or you could do: for (uint8_t i = 8; i > 0; ++i) PORTA = (1 << (i-1)); \$\endgroup\$ – m.Alin Oct 28 '15 at 12:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.