Ich lerne das Programmieren von MCU mit c
Ich verwende Atmel Studio 7, Averdude, USBasp und Atmega16a
das ist mein 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);
}
Die for-Schleife wurde nie beendet und wenn sie i=0
die erste LED erreicht, PORTA
bleibt sie etwa 14 Sekunden lang an und schaltet sich danach etwa zur gleichen Zeit aus, und danach beginnt die for-Schleife erneut, ohne sie zu erreichen
PORTC =1;
_delay_ms(1500);
wenn ich int
stattdessen benutze uint8_t
, funktioniert es gut
kann jemand erklären warum das passiert?
Sie kommen an den Punkt, an dem der Wert von i
ist o
.
i >= 0
ist true
.
Sie versuchen mit zu dekrementieren i--
. Vielleicht erwarten Sie eine negative Zahl. Aber i
ist unsigniert, also bekommt man 255
.
Es wird weiter dekrementiert, bis Sie auf Null kommen. Dann wiederholt sich alles noch einmal.
Wenn i
es signiert wäre, würde die Schleife 9 Iterationen machen.
Der folgende Code hat diesen negativen Effekt nicht. Beachten Sie die strikte Ungleichung. Diese Schleife wird 8 mal durchlaufen.
for (uint8_t i = 8; i > 0; i--) { // strictly greater
// [...]
}
"i >= 0" ist immer wahr, weil i vorzeichenlos ist.
0-1 = 255
.Wenn Sie i = 7, 6, ..., 0
mit einer Indexvariablen ohne Vorzeichen iterieren möchten, ist das übliche Muster
for (uint8_t i = 8; i-- > 0; ) {
PORTA = (1 << i);
_delay_ms(100);
}
obwohl das auf den ersten Blick komisch aussieht. Einige Leute ziehen es vor, immer ansteigende Schleifen zu haben:
for (uint8_t ii = 0; ii < 8; ++ii) {
uint8_t i = 7 - ii;
PORTA = (1 << i);
_delay_ms(100);
}
Sie können nicht i >= 0
als Test verwenden, da vorzeichenlose Werte umlaufen; dekrementieren 0
ergibt 255
.
Wenn Sie über iterieren wollten i = 8, 7, ...,1
, dann hatten Sie nur einen Tippfehler, und der Schleifentest hätte sein sollen i > 0
.
for (uint8_t i = 8; i > 0; ++i) PORTA = (1 << (i-1));
Brian Carlton
Adam Haun
Nick Alexejew
Muhammad Nur
Nick Alexejew
signed
vs.unsigned
).