Forum: Compiler & IDEs Wert wird falsch angezeigt


von gast1 (Gast)


Lesenswert?

Hallo,

Bei meiner Funktion kommt manchmal ein falscher Wert heraus. Der 
Interrupt ruft die Funktion sensorwert() auf. Der Wert der vom SPI 
empfangen wird ist in Ordnung. Aber der echte_wert der angezeigt wird 
ist manchmal falsch.

Wenn der analog_digital ca. 212 ist zeigt es mir manchmal -1, -1.4 oder 
30 an obwohl es 4,9 anzeigen sollte.

Wo kann da der Fehler liegen?

1
char char_analog_digital[6];
2
char char_echter_wert[6];
3
unsigned char analog_digital;
4
5
void sensorwert(void)
6
{
7
  float gemessener_wert;  
8
  float echter_wert;
9
  int i;
10
11
  for(i=0; i<=1; i++)
12
  {
13
    PORTB &= 0xFE; //  /CS auf 0 setzen
14
15
    analog_digital= SPI_MasterTransmit('0');
16
17
    PORTB |= 0x01;
18
  }
19
20
  gemessener_wert = (2.25*analog_digital)/255 + 0.4; 
21
  echter_wert = 15/(gemessener_wert + 0.05) - 1.5;
22
  
23
  echter_wert = echter_wert*10;
24
25
  itoa (analog_digital, char_analog_digital, 10);
26
  itoa (echter_wert, char_echter_wert, 10);

MfG

von gast1 (Gast)


Lesenswert?

Wenn ich das Board flashe wird der richtige Wert angezeigt. Sobald aber 
das Board vom Stromkreis genommen wird und der uC neu gestartet wird 
zeigt es den falschen Wert an.

von Klaus W. (mfgkw)


Lesenswert?

Vielleicht das eine oder andere volatile vergessen?

Wenn in einem Interrupt globale Variablen geändert werden
und im restlichen Programm gelesen werden (oder umgekehrt),
kann es sonst schief gehen, wenn der Compiler zu schlau ist.

von Karl H. (kbuchegg)


Lesenswert?

gast1 schrieb:
> Wenn ich das Board flashe wird der richtige Wert angezeigt. Sobald aber
> das Board vom Stromkreis genommen wird und der uC neu gestartet wird
> zeigt es den falschen Wert an.

Das klingt stark nach nicht initialisierten Variablen

von gast1 (Gast)


Lesenswert?

Wenn ich das volatile hinzufüge ändert das nichts.

Wieso ist das initialisieren wichtig, die Werte werden ja überschrieben.

von Mark B. (markbrandis)


Lesenswert?

Hm, wenn SPI_MasterTransmit() immer etwas Vernünftiges liefert, dann 
sollte das innerhalb des gezeigten Codes eigentlich passen...

von Karl H. (kbuchegg)


Lesenswert?

gast1 schrieb:
> Wenn ich das volatile hinzufüge ändert das nichts.
>
> Wieso ist das initialisieren wichtig, die Werte werden ja überschrieben.

Im gezeigten Codestück schon.
Aber der Fehler kann auch ganz woanders sitzen und die misinterpretierst 
die Symptome.

Was mir am gezeigten Code zb nicht gefällt ist, dass weder 
analog_digital noch echter_wert ein int sind, du aber itoa benutzt. Das 
ist prinzipiell schon ok, der jeweilige Wert wird bei der Übergabge in 
einen int überführt, sofern der Compiler einen Prototypen für itoa 
gesehen hat. Aber hat er das? Wir sehen die notwendigen #include nicht.

Wie geht es dann eigentlich im Code weiter?
Ein gern gemachter Fehler ist zb, dass der Programmierer vergisst, dass 
Ausgaben übereinander geschrieben werden.
Steht am LCD zb 123 und lautet die nächste auszugebende Zahl 58 und wird 
diese linksbündig über die 123 drüber geschrieben, dann steht auf dem 
LCD 583 und die Verwunderung ist groß, wo diese Zahl herkommt, da so 
große Zahlen gar nicht auftreten können.

Fazit: Es gibt viele Möglichkeiten, was falsch sein kann. Und oft werden 
die Symptome falsch interpretiert.

von gast1 (Gast)


Lesenswert?

>wenn SPI_MasterTransmit() immer etwas Vernünftiges liefert, dann
>sollte das innerhalb des gezeigten Codes eigentlich passen...

SPI_MasterTransmit() liefert mir immer einen Wert zwischen 0-255


>dass weder analog_digital noch echter_wert ein int sind, du aber itoa benutzt.

Naja ich musste aus einem char ein char array machen. Soviel ich hier im 
Forum mitbekommen habe ist ein unsigned char ein uint_8.

Was wäre dein Vorschlag. Wie könnte ich am besten den empfangen 
char-Wert in einen char-array wandeln, für die Display-Ausgabe.

>Wir sehen die notwendigen #include nicht.

Die #include sind eigentlich vorhanden.


>Wie geht es dann eigentlich im Code weiter?

Es wird ein Timer-Interrupt ausgelöst wo das Display gelöscht wird die 
Funktion-Sensorwert ausgeführt wird und Interrupt=1; gesetzt wird.

Wenn Interrupt==1 wird der Sleep-Modus in der main()-Funktion 
abgebrochen und alle Display-Anagaben neu gesetzt bzw. die 
Display-Funktionen ausgeführt.

von Karl H. (kbuchegg)


Lesenswert?

gast1 schrieb:

>>Wir sehen die notwendigen #include nicht.
>
> Die #include sind eigentlich vorhanden.
>
>
>>Wie geht es dann eigentlich im Code weiter?
>
> Es wird ein Timer-Interrupt ausgelöst wo das Display gelöscht wird die
> Funktion-Sensorwert ausgeführt wird und Interrupt=1; gesetzt wird.


OK. Dann winke ich mal etwas kräftiger mit dem Zaunpfahl:

Zeige deinen kompletten Code (oder zumindest die kompletten 
Ausschnitte). Beschreibe nicht deinen Code, sondern ZEIGE ihn.
Das ist für dich einfacher (dank Copy&Paste) und wir sehen vollständigen 
Code und müssen uns nicht auf deine Beschreibungen verlassen, was deiner 
Meinung nach passieren müsste.

von gast1 (Gast)


Angehängte Dateien:

Lesenswert?

Hier ist der gesamte Code.

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
Noch kein Account? Hier anmelden.