Archiv verlassen und diese Seite im Standarddesign anzeigen : uint16_t größte Variable?
Hallo,
heute war ich wieder fleißig am proggen, leider hab ich etwa 2h durch einen wirklich dummen Fehler verloren :(
Ich habe den Wert vom Timer1 eines Mega8 ausgelesen. Timer1 = 16bit. Gespeichert habe ich den Wert in uint32_t.
Warum jetzt 32bit? Ganz einfach, ich wollte noch einen festen Wert dazumultiplizieren und ein uint32_t sollte ja theoretisch über 4Mrd speichern können.
NOOOOP!!! Das Ding läuft genauso wie ein uint16_t bei 65535 über!!!
WAS SOLL DAS???
mfg
NOOOOP!!! Das Ding läuft genauso wie ein uint16_t bei 65535 über!!!
WAS SOLL DAS???
Wenn das wirklich so ist, arbeitet dein Compiler nicht standardkonform oder er hat einen kapitalen Bug. Um das erste auszuschließen, kannst du ja mal in die stdint.h schauen. Da muß so etwas drin stehen wie:
/* Maximum of unsigned integral types. */
# define UINT8_MAX (255)
# define UINT16_MAX (65535)
# define UINT32_MAX (4294967295U)
Wenn du das findest, sollte sich der Compiler an den C Standard halten und du hast einen Compiler-Bug gefunden.
MfG Klebwax
ich wollte noch einen festen Wert dazumultiplizieren und ein uint32_t sollte ja theoretisch über 4Mrd speichern können.
Ich habe die Regeln zur Typumwandlung nicht präsent, vermute aber folgendes: "Fester Wert" ist eine Konstante, damit int und 16-Bit breit. TCNT1 ist ebenfalls 16-Bit breit. Also bekommst du eine 16-Bit-Multiplikation, die läuft über und das Ergebnis landet in deiner 32-Bit-Variablen.
Grüße,
Markus
Ich arbeite mit dem Atmel Studio 6.1.2674 - SP1
In der stdint.h
#define INT32_MAX 0x7fffffffLL
#define INT32_MIN (-INT32_MAX - 1LL)
#define UINT32_MAX (__CONCAT(INT32_MAX, U) * 2ULL + 1ULL)
#else /* !__USING_MINT8 */
#define INT32_MIN (-INT32_MAX - 1L)
Ich habe die Regeln zur Typumwandlung nicht präsent, vermute aber folgendes: "Fester Wert" ist eine Konstante, damit int und 16-Bit breit. TCNT1 ist ebenfalls 16-Bit breit. Also bekommst du eine 16-Bit-Multiplikation, die läuft über und das Ergebnis landet in deiner 32-Bit-Variablen.
Ich habe die 32bit Variable extra mit 65500 initialisiert und dann hochgezählt und musste feststellen, dass diese bei 65535 überläuft. Also nur 16bit.
mfg
Ich habe die 32bit Variable extra mit 65500 initialisiert und dann hochgezählt und musste feststellen, dass diese bei 65535 überläuft. Also nur 16bit.
Quelltext bitte. Ich bin fast geneigt zu wetten, dass dein Debugging-Code einen Fehler hat. In der Größenordnung printInt(uint16_t) oder so ;)
Grüße,
Markus
Da ich es schon anders gelöst habe, habe ich den genauen nicht mehr, aber das Prinzip war genau so:
uint32_t myVar = 65500;
char tmp[12] = {0};
while(1) {
sprintf(tmp, "%u", myVar);
lcd_string(tmp);
myVar++;
}
EDIT: Ich verwende einen Mega8, falls das einen Unterschied macht.
mfg
sprintf(tmp, "%u", myVar);
%u ist 16 Bit breit, nimm Mal %uu ...
Grüße,
Markus
Die Ausgabe funktioniert jetzt, aber die anfängliche Berechnung ist immer noch falsch :(
Die sieht so aus:
#define TICK 32
uint32_t myVar = 0;
ISR(...) {
myVar = TCNT1;
TCNT1 = 0;
myVar *= TICK;
...
}
mfg
hi,
evtl.: myVar*=(uint32_t)TICK;
mfg
Achim
Die Ausgabe funktioniert jetzt, aber die anfängliche Berechnung ist immer noch falsch :(
Was passiert? Das myVar 32-Bit breit ist, muss die Multiplikation auch mit 32-Bit erfolgen. Das sollte so eigentlich stimmen ...
Du könntest Mal probieren, "#define TICK 32UL" zu schreiben (das hat die gleiche Wirkung wie der Vorschlag von Achim), ggf. bekommst du Probleme wegen unsigned*signed, aber ich bezweifle das.
Grüße,
Markus
SprinterSB
10.09.2013, 21:04
Einige von Atmel verbreitete Distributionen von avr-gcc enthalten fehlerhafte 32 = 16*16 routinen, siehe z.B.
http://gcc.gnu.org/PR52474
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.