Forum: Mikrocontroller und Digitale Elektronik Datentypen, komische Werte kommen raus


von Matze05 (Gast)


Lesenswert?

Hallo,

ich habe große probleme mit den verschiedenen Datentypen.

temp1 = 650*500;      /
lcd_gotopos(2,3); lcd_writezahl (temp1);   //Ausgabe der GradZahl

Auf dem LCD wird -2680 ausgegeben, das verstehe ich nicht

#include <stdint.h>

unsigned long int temp1;  //das ist meine Deklaration
oder muss ich uint32_t   schreiben,

habe aber schon verschiedenste Datentypen ausprobiert und der atmega 32 
AVR5 rechnet nicht mehr richtig.

Was ist denn da nur los?

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ganzzahlige_.28Integer.29_Datentypen

muss ich hier die GCC Entsprechung programmieren?


Viele GRüße,

Matthias.
von Peter II (Gast)


Lesenswert?

die Frage ist welchen Datentype wird denn in lcd_writezahl verwendet?
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Matze05 schrieb:
> Auf dem LCD wird -2680 ausgegeben, das verstehe ich nicht
> lcd_writezahl()
Vieleicht kann die Funktion gar keine long-Zahlen ausgeben?
von Matze05 (Gast)


Lesenswert?

ok, dann schaue ich mal da nach, darauf wäre ich nie gekommen.

ebend kam bei meiner Rechung 650*100 -2680 raus
Datentyp war uint16_t

ich schau mal nach


hier der Auszug

habe meine Variable im Programm auch auf int32_t eingestellt, hat nichts 
geholfen

ich werd verrückt, das ging doch eigentlich bis jetzt immer

void lcd_writezahl (int32_t zahl)
{
int32_t output;




if (zahl <0)
  {
  lcd_writechar('-');
  zahl*=-1;        //positive Zahl
  }

output=zahl;


//Hundertausender-Dezimalstelle oder Leerzeichen
if (zahl>=100000)
{
lcd_writechar (0x30+output/100000);
output=output%100000;
}

//Zehntausender Dezimalstelle oder Leerzeichen
if (zahl>=10000)
{
lcd_writechar (0x30 + output/10000);
output=output%10000;
}

//Tausender Dezimalstelle oder Leerzeichen
if (zahl>=1000)
{
lcd_writechar (0x30+ output/1000);
output=output%1000;
}


//Hunderter Dezimalstelle oder Leerzeichen
if (zahl>=100)
{
lcd_writechar (0x30 +output/100);
output=output%100;
}


//Zehner Dezimalstelle oder Leerzeichen
if (zahl>=10) lcd_writechar (0x30 + output/10);

lcd_writechar(0x30+output % 10);

}
von Matze05 (Gast)


Lesenswert?

Lothar Miller schrieb:
> Matze05 schrieb:
>> Auf dem LCD wird -2680 ausgegeben, das verstehe ich nicht
>> lcd_writezahl()
> Vieleicht kann die Funktion gar keine long-Zahlen ausgeben?


gebe ich die REhcnung ein, dann kommt -5 raus.

temp1 = 650*500/500;      // A/D-Wert in Spannung umrechnen (AREF=5V, 10 
Bit A/D-Wandler: 2^10=1024)
lcd_gotopos(2,3); lcd_writezahl (temp1);   //Ausgabe der GradZahl
von Matze05 (Gast)


Lesenswert?

diese REchung

motorstrom=(((shuntwert-basisshuntwert+5)*54000/1024)*10)/45; 
//+3=Korrekurfaktor, um den richtigen Stromwert zu erreichen

funktioniert auch, es wird ein Strom von z.B. 500mA am Display 
ausgegeben

unsigned int long motorstrom;
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Matze05 schrieb:
> if (zahl>=100000)
Schreib da mal besser 100000UL
von Matze05 (Gast)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Matze05 schrieb:
>> if (zahl>=100000)
> Schreib da mal besser 100000UL

Hallo,

danke für den Tipp.

habe UL hinter dieser Zahl in LCD_tools geschrieben.

650*50=32500, das macht er noch

aber 650*51=-32386

uint32_t   temperatur;

habe es aber direkt so geschrieben

lcd_gotopos(2,3); lcd_writezahl(650*51);   //Ausgabe der GradZahl

weiß nicht, ob man dann noch eine Variable deklarieren muss?

ist die LCD Tools nicht richtig geschrieben?

soweit kenne ich mich nämlich auch nicht aus.

lcd_gotopos(4,12); lcd_writezahl(20*54000)

dann gibt er anstatt1080000

:80000 aus

Viele GRüße
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Machs so:
 lcd_writezahl(650UL*51);   //Ausgabe der GradZahl
Und so:
 lcd_writezahl(20*54000UL)
Denn sonst wird die Berechnung in der Klammer mit 16 Bit ausgeführt.
von Matze05 (Gast)


Lesenswert?

vielen vielen Dank,

es hat geklappt.

weiß zwar nicht wieso ich es so machen muss, aber es geht.

Viele Grüße,
Matthias.
von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

> weiß zwar nicht wieso ich es so machen muss,

steht doch da:

Denn sonst wird die Berechnung in der Klammer mit 16 Bit ausgeführt.
von Matze05 (Gast)


Lesenswert?

Wegstaben Verbuchsler schrieb:
> weiß zwar nicht wieso ich es so machen muss,
>
> steht doch da:
>
> Denn sonst wird die Berechnung in der Klammer mit 16 Bit ausgeführt.

Hi,

ja das steht da. :-)
aber wie man darauf kommt und wo ich das nachlesen kann, das dann in 
32bit gerechnet wird und warum bei mir ansonsten nur in 16bit gerechnet 
wird, obwohl ich 32 bit variablen angegeben habe.

viele Grüße,

matthias.
von Helfer (Gast)


Lesenswert?

Matze05 schrieb:
> aber wie man darauf kommt und wo ich das nachlesen kann, das dann in
> 32bit gerechnet wird und warum bei mir ansonsten nur in 16bit gerechnet
> wird, obwohl ich 32 bit variablen angegeben habe.

Zum einen ist im ANSI C Standard definiert:

# an integer constant takes on the minimum type necessary to be 
accurately represented, (possibly) starting as int and increasing from 
long to unsigned long.

# n ANSI C, an integer constant may be followed by:

    * a 'u' or 'U' to indicate an unsigned constant, like 33u
    * a 'ul' or 'UL' to indicate an unsigned long constant, like 32767ul


Zum anderen muss man dazu wissen, wie breit int auf der jew. Plattform 
ist. avr-gcc verwendet normalerweise 16 bit für den int.

HTH. :)
von Karl H. (kbuchegg)


Lesenswert?

Matze05 schrieb:
> Wegstaben Verbuchsler schrieb:
>> weiß zwar nicht wieso ich es so machen muss,
>>
>> steht doch da:
>>
>> Denn sonst wird die Berechnung in der Klammer mit 16 Bit ausgeführt.
>
> Hi,
>
> ja das steht da. :-)
> aber wie man darauf kommt und wo ich das nachlesen kann,

Das sollte eigentlich in deinem C-Buch stehen.

> das dann in
> 32bit gerechnet wird und warum bei mir ansonsten nur in 16bit gerechnet
> wird, obwohl ich 32 bit variablen angegeben habe.

Weil es dem Compiler völlig wurscht ist, an welche Variable du das 
Ergebnis einer Berechnung zuweist. Für die Berechnung von

     a  operation b

ist einzig und alleine der Datentyp von a bzw. der Datentyp von b 
ausschlaggebend.


     650*51


650 ist ein int. 51 ist ein int. Also wird eine int*int Multiplikation 
gemacht.

http://www.mikrocontroller.net/articles/FAQ#Datentypen_in_Operationen
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.