Hallo Ich habe folgendes Problem. Ich versuche mich an einer Analog/Digitalwandnlung. Hierbei habe ich das Problem das mir der Mikrocontroller(Atmega644) bei z.B. 2 V am Eingang auch 2000 mV angibt aber wenn ich den Eingang low lasse (gemessen 0.3 V ) er mir trotzdem angibt zB. 1500 mV. Ich benutze einen Externen 14,7456 MHZ. Als Kanal übergebe ich zB. 0 (für PortA Pin0). Die Referenzspannung beträgt 3,3 V. long ReadAnalog(uint8_t mux) { if((mux > -1) | (mux < 8)){ uint8_t i; uint16_t result; ADMUX = mux; // Kanal waehlen ADMUX |= (1<<REFS0); // AVCC als Referenz (3,3 V) ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // ADCSRA |= (1<<ADSC); while ( ADCSRA & (1<<ADSC) ) { ; // auf Abschluss der Konvertierung warten } result = ADCW; result = 0; char zwischenspeicher[10]; for( i=0; i<4; i++ ) { ADCSRA |= (1<<ADSC); while ( ADCSRA & (1<<ADSC) ) { ; } result += ADCW; ltoa(result,zwischenspeicher,10); ausgabe(zwischenspeicher); ausgabe(" "); } ADCSRA &= ~(1<<ADEN); result /= 4; return ((result * 3.30 /1024.00)*1000); } // Ende if((mux>-1) | (mux < 8)) } Bei "ausgabe(zwischenspeicher);" gibt mir der Mikrocontroller schon 300,600,900,1200 an. Wobei mich hierbei stört das 300 von 1024=3,3V schon um die 1 V sind .(Die anderen sind aufaddierungen von 300 was auch so sein sollte Jemand ne idee? Vielen dank im Vorraus Alex
Alex wrote:
> aber wenn ich den Eingang low lasse (gemessen 0.3 V ) er mir trotzdem
Heißt das, der Eingang ist unbeschaltet? In dem Fall kann der Eingang
jeden Spannungspegel annehmen. Solche Messungen können höchstens
sinnvoll sein, wenn man gerne Zufallszahlen erzeugen möchte.
Jup habe den Fehler. Liegt nicht an der Software sondern an der Hardware.. Benutze keine Pull Up/Down Widerstände. Danke für die schnelle Hilfe
Bist du sicher dass die Zeile wirklich macht was du dir vorgestellt hast? -> if((mux > -1) | (mux < 8)){ z.B. wenn du jetzt 100 als mux übergibst.
Gast wrote: > Bist du sicher dass die Zeile wirklich macht was du dir vorgestellt > hast? > -> if((mux > -1) | (mux < 8)){ > > z.B. wenn du jetzt 100 als mux übergibst. Zufällig funktioniert das, aber nur, weil mux vom Typ uint8_t ist (also unsigned) und deshalb (mux > -1) immer false ergibt. Sinnvoller wäre es auf jeden Fall, einfach if (mux < 8) zu schreiben.
Es ist wohl eher immer true, da jeder Wert den mux annehmen kann größer als -1 ist.
Gast wrote: > Es ist wohl eher immer true, da jeder Wert den mux annehmen kann größer > als -1 ist. Ne, eben nicht. mux ist 1 byte lang, folglich wird der Compiler für den Vergleich die -1 als Bytewert verwenden. In Hexadezimalschreibweise ist das 0xff. Zufällig ist dies genau gleich dem größten Wert, den eine Variable vom Typ uint8_t - wie mux - annehmen kann. Deshalb kann mux niemals größer als -1 sein. Klingt verrückt, ist aber so.
Andreas Vogt wrote: > Gast wrote: >> Es ist wohl eher immer true, da jeder Wert den mux annehmen kann größer >> als -1 ist. > > Ne, eben nicht. mux ist 1 byte lang, folglich wird der Compiler für den > Vergleich die -1 als Bytewert verwenden. In Hexadezimalschreibweise ist > das 0xff. Zufällig ist dies genau gleich dem größten Wert, den eine > Variable vom Typ uint8_t - wie mux - annehmen kann. > Deshalb kann mux niemals größer als -1 sein. Klingt verrückt, ist aber > so. Die Conclusio ist zwar richtig, aber die Begründung ist falsch. Es geht nicht um bytewert oder wordwert. Es geht um Signedness. mux > -1 ist ein Ausdruck, in dem 2 Datentypen gemischt werden. mux ist ein uint8_t, also wohl ein unsigned char -1 ist ein int. Genauer: ein signed int Die C Regeln schreiben jetzt vor, dass alles auf die Länge des größten gemeinsamen Datentyps gebracht werden muss. Das wäre jetzt erst mal 16 Bit, für den int. Aus dem uint8_t wird also ein uint16_t. Jetzt steht da ein unsigned Typ einem signed Typ gegenüber und in dem Fall sagen die C-Regeln, dass alles auf unsigned gebracht wird. mux bleibt so wie es war, während -1 zu einem unsigned wird. Bei Benutzung von 2-er Komplementregeln (was wir mal vorraussetzen können), ist der zu -1 gehörende unsigned Wert 65535 Und jetzt hast du Recht. mux wird wohl nie größer als 65535 sein. Vor allen Dingen gibt es keinen unsigned 16 Bit Wert der größer als 65535 sein kann. (Der Optimizer des Compilers könnte die Erweiterung von 8 auf 16 Bit spritzen, allerdings bleibt das Problem nach wie vor, dass in ein und derselben Expression ein unsigned mit einem signed Datentyp gemischt wird. Und in dem Fall gewinnt immer unsigned)
Karl heinz Buchegger wrote: > -1 ist ein int. Genauer: ein signed int Ist das irgendwo festgelegt? Könnte der Compiler nicht auch ein signed char daraus machen? Karl heinz Buchegger wrote: > Jetzt steht da ein unsigned Typ einem signed Typ gegenüber und in dem > Fall sagen die C-Regeln, dass alles auf unsigned gebracht wird. Ich habe arbeite gerade einem C++ Projekt für einen ATmega mit der Winavr Toolchain. Da habe ich mal gehässigerweise folgendes Kompilieren lassen:
1 | uint8_t mcucsr = MCUCSR; |
2 | if (mcucsr > -2) |
3 | __asm__ volatile("nop"); |
Im resultierenden .lss-File sieht man, dass die if-Abfrage komplett wegomptimiert wird, und dass das nop bedingungslos ausgeführt wird. Offenbar ist der gcc - jedenfalls bei der Verarbeitung von cpp-Dateien - der Ansicht, dass ein unsigned immer größer ist, als ein negativer Wert. Eine Umwandlung von signed auf unsigned scheint hier gar nicht stattzufinden. Karl heinz Buchegger wrote: > (Der Optimizer des Compilers könnte die Erweiterung von 8 auf 16 Bit > spritzen, allerdings bleibt das Problem nach wie vor, dass in ein und > derselben Expression ein unsigned mit einem signed Datentyp gemischt > wird. Und in dem Fall gewinnt immer unsigned) Was genau meinst Du damit? Dass der Compiler den signed Wert einfach als unsigned betrachtet? Das tut gcc in meinem Beispiel offensichtlich nicht. edit Alles Quark, Du hast Recht. In meinem Beispiel wird die if-Abfrage deshalb wegoptimiert, weil ein Wert mit der Länge von einem Byte nie größer sein kann als eine zwei Byte lange -2, die als unsigned betrachtet wird.
wieso sollte mux auf unsigned int erweitert werden? Im Gegenteil wird aus mux ein signed int, womit der Vergleich immer true ist. Erwähnenswert wäre noch if((mux > -1) | (mux < 8)) Die bitweise Veroderung der beiden Vergleiche, was ebenfalls funktioniert, aber tunlichst nicht zu Gewohnheit werden sollte. Kann üble Fehler ergeben, die man nicht mehr sieht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.