Hallo! Ich programmiere gerade einen Atmega 32 und irgendwie will mein Programm nicht so richtig das tun was ich will. Hier mal mein Code: Erklärung: verz() ist lediglich eine while Schleife für delay und die if- Schleife ruft ein Menü auf, das in einer anderen Funktion deklariert wird (hier lässt sich auch die Variable moment ändern). moment ist eine globale Variable, die zu Beginn des Programms zum testen auf 50 gsetzt wird. Berechnet wird eine "simple" Geradengleichung: drehmoment = moment/512*adcergebnis-moment; adcergebnis ist die Auswertung des Analogports( liegt zwischen 0 und 1024), typ int moment ist ein faktor der zwischen 1 und 5000 liegen kann, typ int drehmoment stellt das Ergebnis dar -> long, da in der rechnung kurzzeitig mehr speicher benötigt werden könnt als von einer normalen int drehmoment wird anschließend noch in einen string verwandelt, um dieses auf dem Display ausgeben zu können. Leider funktioniert das ganze nicht - und ich finde meinen Denkfehler nicht! Bei Werten für das Moment bis ca. 10 funktioniert es noch wie es soll - darüber nicht mehr, bzw ab Werten ca. 100 stürzt das Display ab und dann irgendwann auch der Atmega!? Was mach ich falsch.. Herzlichen Dank! Gruß
> drehmoment stellt das Ergebnis dar -> long, da in der rechnung > kurzzeitig mehr speicher benötigt werden könnt als von einer normalen > int Das interessiert den Compiler aber beim Bearbeiten der Berechnung herzlich wenig, wenn deine Ergebnisvariable vom Typ long ist. Der Compiler richtet sich nach den Datentypen der an der Operation beteiligten Operanden. Und da die alle int sind, wird auch die Berechnung in int gemacht. Erst das komplette Endergebnis wird dann nach long umgewandelt weil es ja einem long zugewiesen werden soll. Wenn du den Compiler dazu zwingen willst, die Berechnung im Zahlenraum für long durchzuführen, dann muss eine an der Operation beteiligte Komponente vom Typ long sein. drehmoment = ((long)adcergebnis * moment) / 512; Jetzt wird die ganze Berechnung in long durchgeführt.
Also ein paar Kleinigkeiten fallen mir an dem Code beim Drübersehen
schon mal auf:
1. Benutze keine Bezeichner, die mit einem Underscore ("_") beginnen.
Die sind für den Compiler reserviert.
2. Nimm für die Mittelwertbildung vom ADC-Ergebnis besser eine
Zweierpotenz für die Anzahl der Werte. Da fällt dem Prozessor die
Division leichter. Division durch 10 ist erheblich komplizierter als
Division durch 8 oder 16.
3.
> ADMUX != (1 << REFS0)|( 1 << REFS1);
Das kann so nicht gehen. Befasse Dich mal mit der Bedeutung des
logischen Negierungs-Operators "!". Sonst hast Du immer 0 in ADMUX
stehen.
tbc...
AH - schon mal danke für die Tipps! -> Wurde gerad abgeändert. @ johnny m. 3. -> da hab ich wohl nen schreibfehler gemacht: das ! solte ein | sein :) Nachdem ich mal eure Tipps beachtet habe, geht der ganze vorgang bei 50 z.b. wunderbar wie gewollt. Nur wenn ich den wert im Programmablauf ändere (> 10) und dann wieder aus meinem Menü rausgehe - also zurück in die Berechnung - stürzt erimmer noch ab!?
Dann wirst du halt noch wo einen Fehler haben :-) Heisse Kandidaten sind, wie immer, Array Überläufe.
Hi! Ich hab jetzt mal die Funktion für das entsprechende Untermenü angehängt. Ich habe davor einfach auch das Menü getestet und da hat er mir immer die richtigen Werte "gespeichert". Das Untermenü setzt sich so zusammen, dass man in der sog. reihe 3 werte und beim Faktor 4 Werte auswählen kann. Das Produkt aus beidem ist dann die globale Variable moment. Wäre super wenn mal jemand kurz drüberschauen könnte, ob er nen Fehler entdeckt. (ich hoffe es ist halbwegs verständlich geschrieben - ich bin aber auch dankbar für Hinweise für efektiveres programmieren!) Danke schon mal :)
Auf den ersten Blick fällt nur auf, daß deine arrays, in die du mit itoa schreibst, aller sehr klein sind. itoa kann aus einem int nunmal mit -32768 max. 6 Zeichen erzeugen, dazu kommt dann noch die /0 am Ende, ergibt 7. Du musst dir also schon sehr sicher sein, wenn du deine arrays kleiner als 7 dimensionierst. Eine Frage am Rande: Wo kann man eigentlich die prellfreien Taster kaufen? Oliver
Hi! also in itoa werden ja nur die jeweiligen werte der anderen arrays geschrieben -> daher ist das längste array dann 5 zeichen lang.. Wegen den tastern: dadurch dass ich immer ne gewisse wartezeit nach einem tasterdruck einhalte, habe ich dadurch bisher keine Probleme! Funktioniert sogar sehr gut wie ich finde.. Und es gibt auch schon entprellte Taster zu kaufen ( die die ich im moment verwende haben keine solche Entprellung).. Naja - ich probier ma nch weiter oder widme mich erst mal der nächsten Aufgabe... :) MFG und Danke P.S. Danke - ihr hattet Recht - habs grad gesehen: hab leider 1 Array genau 1 zu kurz gemacht -> wie peinlich:) Danke für eure Hilfe...
"Danke - ihr hattet Recht - habs grad gesehen: hab leider 1 Array genau 1 zu kurz gemacht -> wie peinlich:)" Willkommen im Club :-) Oliver
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.