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=0
al primer LED PORTA
permanece 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 int
en lugar de uint8_t
funciona bien
¿Alguien puede explicar por qué sucede esto?
Llegas al punto donde el valor de i
es o
.
i >= 0
es true
_
Intenta decrementar con i--
. Tal vez, usted está esperando un número negativo. Pero i
no está firmado, por lo que obtienes 255
.
Sigue decreciendo hasta llegar a cero. Entonces todo se repite de nuevo.
Si i
estuviera 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.
0-1 = 255
.Si desea iterar 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 usarlo i >= 0
como prueba, porque los valores sin firmar se envuelven; decreciente 0
da 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
.
for (uint8_t i = 8; i > 0; ++i) PORTA = (1 << (i-1));
brian carlton
Adán Haun
Nick Alexeev
muhammad nour
Nick Alexeev
signed
vs.unsigned
).