Comportamiento inusual o extraño: uint8_t en bucle for en avr MCU

Estoy aprendiendo a programar MCU con c

Estoy usando atmel studio 7, averdude, USBasp y Atmega16a

este es mi codigo

#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);
}

el bucle for nunca termina y cuando llega i=0al primer LED PORTApermanece encendido durante unos 14 segundos y luego se apaga durante aproximadamente el mismo tiempo y luego el bucle for comienza de nuevo sin llegar a

PORTC =1;
_delay_ms(1500);

cuando uso inten lugar de uint8_tfunciona bien

¿Alguien puede explicar por qué sucede esto?

Voto para cerrar esta pregunta como fuera de tema porque no se trata de electrónica. Parece pertenecer a Stack Overflow.
¿Desde cuándo las preguntas sobre programación integrada están fuera de tema?
@BrianCarlton Si se cierra, lo migraré benignamente a StackOverflow. Sin embargo, no voy a forzar esto.
@brain carlton Pensé que debido a que está incrustado en una pregunta relacionada, pertenecería a la electrónica, según usted, cualquier pregunta de programación, incluso si está relacionada con la electrónica, estaría en SOF, está bien, lo tengo. gracias
@MuhammadNour No se preocupe demasiado por esto. La frontera entre las preguntas de programación integrada y las preguntas de programación simple no está claramente delimitada. En el peor de los casos, su pregunta se migraría a StackOverflow. En este caso, pensó que la pregunta estaba incrustada, pero la respuesta resultó ser una programación menos simple ( signedvs. unsigned).

Respuestas (3)

Llegas al punto donde el valor de ies o.
i >= 0es true_
Intenta decrementar con i--. Tal vez, usted está esperando un número negativo. Pero ino está firmado, por lo que obtienes 255.
Sigue decreciendo hasta llegar a cero. Entonces todo se repite de nuevo.

Si iestuviera firmado , entonces el ciclo haría 9 iteraciones.

El siguiente código no tiene este efecto negativo. Note la desigualdad estricta. Este ciclo se iterará 8 veces.

for (uint8_t i = 8;  i > 0;  i--) { // strictly greater
    // [...]
}

"i >= 0" siempre es verdadero porque i no tiene signo.

Las maravillas de 0-1 = 255.

Si desea iterar i = 7, 6, ..., 0con una variable de índice sin signo, el patrón habitual es

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

aunque esto se ve raro la primera vez que lo ves. Algunas personas prefieren tener siempre bucles crecientes:

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

No puede usarlo i >= 0como prueba, porque los valores sin firmar se envuelven; decreciente 0da 255.

Si lo que quería hacer es iterar sobre i = 8, 7, ...,1, entonces solo tuvo un error tipográfico y la prueba de bucle debería haber sido i > 0.

O podrías hacer:for (uint8_t i = 8; i > 0; ++i) PORTA = (1 << (i-1));