Berechnugsproblem

OP #2449138
Lesenswert?

Hallo liebe Gemeinde,

Ich bin an einem Punkt angekommen wo ich einfach nicht mehr weiter weis 
(wahrscheinlich ist es ein ganz dummer fehler den ich einfach übersehe).

Kurz zur Hardwar:

STK500 Mit Atmega 16 und 16MHZ Quarz
LM335 an PORTA.1 (Anschluss überprüft und gemessen, stimmt alles)
Poti an PORTA.0

ADC Einstellungen:
128 Prescaler = 125KHz
AVCC als Ref

Ansonsten nutz ich den ADC Code aus dem Tutorial.

Ich versuche nun seit ein paar Tagen die gemessene Temperatur an meinen 
PC zu senden, aber es kommen immer die falschen Werte.

Habe schon einiges ausprobiert aber es will einfach nicht.

Der Poti soll zu testzwecken nur eine LED Dimmen was auch einwandfrei 
funktioniert, desweiteren hab ich noch ein wenig mit Interrupts 
experementiert was auch einwandfrei klappt, nur der Richtige Temp Wert 
will nicht.

Was auch extrem komisch ist, wenn ich simuliere werden die variablen 
nicht initialisiert (Wenn ich simuliere setze ich die Werte auf z.B 610 
o.ä) und der Simulator springt kurz in die if Abfrage und arbeitet da 
drei Zeilen ab obwohl er das nicht soll.

Achso nutze AVR Studio 5

Anbei der Code.

Hoffe einer hat ne Idee warum ich immer die Falschen werte bekomme.

Danke!
Angehängte Dateien:
#2449159
Lesenswert?

> acttemp = (ADC_Read_Avg(1,4)*1000);

ADC_Read_Avg liefert zb einen Wert von 600.
Mal 1000 macht dann 600000. UNd das ist zu viel. Bei 65535 ist Schluss.

Das du das Ergebnis danach an einen long zuweist, ist uninteressant. Die 
Berechnung wird in int gemacht, weil

* ADC_Read_Avg einen int (unsigned) liefert    und
* 1000  ebenfalls ein int ist

Damit stehen die beiden Teilnehmer an der Multiplikation fest, beide 
sind int  (bzw. unsigned int), daher wird eine 16 Bit int Multiplikation 
gemacht.

Wenn du eine long Multiplikation erzwingen willst (weil du sie brauchst, 
damit das Ergebnis noch darstellbar ist), dann musst du einen der 
Teilnehmer als long ausführen. Die 1000 würden sich anbieten
1
  acttemp = (ADC_Read_Avg(1,4)*1000L);


> (wahrscheinlich ist es ein ganz dummer fehler den ich einfach übersehe).

In Berechnungen müssen alle Zwischenwerte im gültigen Wertebereich 
liegen. Auch der Wert der rechten Seite einer Zuweisung ist erst mal nur 
ein Zwischenwert, der dann an das Ziel zugewiesen wird.
#2449168
Lesenswert?

>
>  long tempout = 0;
> ...
>      itoa(tempout,Buffer,10);


No.
Wie das "i" in "itoa" schon sagt, ist die Funktion itoa für int 
zuständig. Du hast keinen int, du hast einen long! Die dafür zuständige 
Funktion heißt ltoa, mit einem "l" am Anfang,wie "long"

(und für unsigned int würde die Funktion utoa heissen. "u" wie "unsigned 
int")
#2449171
Lesenswert?

>      itoa(tempout,Buffer,10);
>      for (int a=0;a<3;a++)            // Wert auf UART ausgeben
>      {
>        uart_putchar(Buffer[a]);
>        if (a == 1)
>        {
>          uart_putchar(44);          // Leerzeichen ausgeben
>        }
>      }

Woher weißt du, dass dein Ergebnisstring 3 Zeichen umfasst? Was ist mit 
negativen Temperaturen? Was ist mit einstelligen Temperaturen?

Das ist ein bischen sehr brutal, was du da machst.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren