Comportamiento extraño o extraño: uint8_t en for loop en avr MCU

5

Estoy aprendiendo a programar MCU con c

Estoy usando atmel studio 7, averdude, USBasp y Atmega16a

este es mi código

#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 terminó y cuando alcanza i=0 , el primer LED en PORTA permanece encendido durante unos 14 segundos y luego se apaga durante aproximadamente el mismo tiempo y luego el bucle for comienza nuevamente sin llegar a

PORTC =1;
_delay_ms(1500);

cuando uso int en lugar de uint8_t funciona bien

¿Alguien puede explicar por qué sucede esto?

    
pregunta Muhammad Nour

3 respuestas

14

Llegas al punto donde el valor de i es o .
i >= 0 es true .
Intenta disminuir con i-- . Tal vez, estás esperando un número negativo. Pero i no está firmado, así que obtienes 255 .
Sigue disminuyendo hasta llegar a cero. Luego todo vuelve a repetirse.

Si i estuviera firmado , entonces el bucle haría 9 iteraciones.

El siguiente código no tiene este mal efecto. Note la estricta desigualdad. Este bucle se repetirá 8 veces.

for (uint8_t i = 8;  i > 0;  i--) { // strictly greater
    // [...]
}
    
respondido por el Nick Alexeev
6

"i > = 0" siempre es cierto porque i no tiene firma.

    
respondido por el Peter Green
3

Si desea iterar sobre i = 7, 6, ..., 0 con 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 usar i >= 0 como prueba, porque los valores sin firmar se envuelven alrededor; al disminuir 0 se obtiene 255 .

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

    
respondido por el Hurkyl

Lea otras preguntas en las etiquetas