Forum: Mikrocontroller und Digitale Elektronik C Vorzeichenproblem?!


von Tanja (Gast)


Lesenswert?

Hallo,
wenn ich einen long long signed int mit z.B. -942314646 angebe, bekomme 
ich auf dem Display den richtigen Wert ebenso bei +6865654655 z.B.

Nun nutze ich einen STM32F373 mit einem 16BIT ADC
Lese ich nun diesen 16ADC Wet in die long long signed INT sollten dort 
Werte von -32xxx bis + 32xxx angezeigt werden
Die Werte beginnen aber mit 32768 dann zählt er bis 65xxx hoch und 
beginnt erneut von 32768 ?!?


Arbetie ich dagegen mit einem signend Int arbeite zeigt er auch die 
-32xxx bis +32xxx richtig an?!?!

Auch wenn ich dann versuche diese Werte darauffolgend mit Wert1=Wert2 
von signed int in long long signed int zu convertieren tritt der Fehler 
auf?!

Da ich Zahlen, wenn ich sie direkt eingebe ja auch korrekt konvertieren 
kann, vermute ich das der ADC irgendwas übermittelt was da ein PRoblem 
macht ..nur was?!?

: Gesperrt durch User
von STK500-Besitzer (Gast)


Lesenswert?

caste einfach den Wert richtig.

von Tanja (Gast)


Lesenswert?

toller..danke ..eine Antwort wie man sie hier gewohnt ist!!
Kack Forum

von Tanja (Gast)


Lesenswert?

Falls das mal jemand anders sucht..was der Tolle tippgeber meint ist..
c = (char)i;


Eine Erklärung warum  es falsch ist oder was dann da genau passiert oder 
wieso habe ich jetzt leider nicht parat vielleicht hat das ja einer der 
Schlaumeier und kann damit zukünftig anderen helfen die das gleiche 
Problem haben

von Tanja (Gast)


Lesenswert?

aber trotzdem danke, zumindest lag es daran

von jolle (Gast)


Lesenswert?

Tanja schrieb:
> Kack Forum

 ..eine Antwort wie man sie von dir gewohnt ist!!
Eine völlig richtige Antwort hat eine Beschimpfung zur Folge...

von Sascha_ (Gast)


Lesenswert?

Unwahrscheinlich schlau erstmal alle zu beleidigen bevor man die 
gleichen Leute nach Hilfe fragt.

Aber muss schon richtig sein, Frauen sind ja die mit dem Gespür für 
Menschen und Gefühle. Diese Empathie-Antennen. Haben Männer nicht.

von jolle (Gast)


Lesenswert?

Ja klar.

Tanja schrieb:
> Lese ich nun diesen 16ADC Wet in die long long signed INT sollten dort
> Werte von -32xxx bis + 32xxx angezeigt werden

-32000 ... +32000 passen selbstverständlich in eine Variable vom Typ 
char.

Tanja schrieb:
> Falls das mal jemand anders sucht..was der Tolle tippgeber meint ist..
> c = (char)i;

Tanja schrieb:
> aber trotzdem danke, zumindest lag es daran

:-D

von STK500-Besitzer (Gast)


Lesenswert?

Tanja schrieb:
> Eine Erklärung warum  es falsch ist oder was dann da genau passiert oder
> wieso habe ich jetzt leider nicht parat vielleicht hat das ja einer der
> Schlaumeier und kann damit zukünftig anderen helfen die das gleiche
> Problem haben

Aus dem ADC kommen zwei Byte.
Die haben kein Vorzeichen.
Das Vorzeichen deiner Long Long signed int steckt im obersten Bit der 
Variable. Das wird aber nie erreicht, wenn man dem Compiler nicht 
bescheid sagt (castet).
Der füllt dann einfach die fehlende Speicherplätze mit Nullen auf.
War das jetzt umfangreich genug?
Wenn jemand einfach nur einen Begriff in die Runde schmeißt, ist das 
i.d.R. eine Aufforderung, diesen zu googlen.

von Nop (Gast)


Lesenswert?

äh.. wenn man einen ADC mit 16bit ausliest, dann ist das normal ein 
uint16_t, von 0 bis 64k. Um daraus überhaupt ein vorzeichenbehaftetes 
Etwas zu machen, muß man das erstmal nach int32_t casten und dann 32k 
subtrahieren.

von 1N 4. (1n4148)


Lesenswert?

> äh.. wenn man einen ADC mit 16bit ausliest, dann ist das normal ein
> uint16_t, von 0 bis 64k.

Was steht im Datenblatt?

von Sascha_ (Gast)


Lesenswert?

jolle schrieb:
> Ja klar.
>
> Tanja schrieb:
>> Lese ich nun diesen 16ADC Wet in die long long signed INT sollten dort
>> Werte von -32xxx bis + 32xxx angezeigt werden
>
> -32000 ... +32000 passen selbstverständlich in eine Variable vom Typ
> char.

Ich kann mich irren, aber imho ist char 8Bit lang.

von jolle (Gast)


Lesenswert?

Sascha_ schrieb:
> Ich kann mich irren, aber imho ist char 8Bit lang.
Ich habe nur das Smiley ;-) vergessen, sorry.

von Nop (Gast)


Lesenswert?

1N 4. schrieb:

> Was steht im Datenblatt?

Also bei STM32, worauf ich so programmiere, steht im Datenblatt, daß 
VSSA (0V) bis VDDA (3.3V) auf 0 bis 4095 gemappt wird. Gut, das sind 
12bit, aber das Prinzip ist dasselbe.

von Tanja (Gast)


Lesenswert?

das
c = (char)i;
ist lediglich ein Beispielt wie gecastet wird ihr Pfeifen.
Wenn jemand sowas fragt, wird er Anfänger sein, da ist sowas  hilfreich.
Und neun, es gibt auch  noch eine Welt ohne google, was manche hier wohl 
schon nicht mehr hinbekommen

von Tanja (Gast)


Lesenswert?

Ein Casting verbietet dem Compiler gewissermaßen den Mund, um uns 
hilfreiche Tipps zu geben. Castings sind also so selten wie nur 
irgendwie möglich einzusetzen und wenn man gezwungen ist, sie 
einzusetzen, dann mit äußerster Vorsicht.


daher hatte ich es bislang auch nie verwendet, in pascal ging es 
eigentlich immer so

von Tanja (Gast)


Lesenswert?

verstehen tu ich es dennoch nicht..
Ich hatte auch adc16bit = leseadc * 0.00366;
eingegeben, laut meiner ganzen Bücher hier, wird dann autmatisch i 
double umgewandelt und das ist ja mit Vorzeichen, somit wäre doch 
eigentlich gar kein cast mehr erforderlich?!

von STK500-Besitzer (Gast)


Lesenswert?

Tanja schrieb:
> Ich hatte auch adc16bit = leseadc * 0.00366;
> eingegeben, laut meiner ganzen Bücher hier, wird dann autmatisch i
> double umgewandelt und das ist ja mit Vorzeichen, somit wäre doch
> eigentlich gar kein cast mehr erforderlich?!

Es gibt zig verschiedene Integer-Wertebereiche angefangen beim byte 
(unsigned char, signed char) weiter über 2-byte-breite Zahlen (int16_t, 
uint16_t) usw..., aber nur zwei Fließkomma-Wertebereiche (float und 
double), deren Wertebereich i.d.R. dem Compiler extern vorgeben wird.

Nop schrieb:
> Um daraus überhaupt ein vorzeichenbehaftetes
> Etwas zu machen, muß man das erstmal nach int32_t casten und dann 32k
> subtrahieren.

Sicher? Wenn man einen 16-Bit-Wert auf int16_t, sollten die Bits auch 
einfach übersetzt werden. Da käme aber Quatsch bei raus, sofern der ADC 
nicht auf das Vorzeichen achtet...

von öde Ode (Gast)


Lesenswert?

Tanja schrieb:
> Hallo,
> wenn ich einen long long signed int mit z.B. -942314646 angebe, bekomme
> ich auf dem Display den richtigen Wert ebenso bei +6865654655 z.B.
>
> Nun nutze ich einen STM32F373 mit einem 16BIT ADC
> Lese ich nun diesen 16ADC Wet in die long long signed INT sollten dort
> Werte von -32xxx bis + 32xxx angezeigt werden
> Die Werte beginnen aber mit 32768 dann zählt er bis 65xxx hoch und
> beginnt erneut von 32768 ?!?

Das kann man so nicht pauschal sagen, das kommt daraufan wie der ADC 
konfiguriert ist. Manche knallen 2erkomplement aus, andere nicht. 
Right/Left assignment kann auch ein Thema sein. 
Beitrag "Verständnisfrage Zweierkomplement bei ADC"


> Arbetie ich dagegen mit einem signend Int arbeite zeigt er auch die
> -32xxx bis +32xxx richtig an?!?!
Nein, die letzten drei Stellen sind nicht gleich wie deine "xxx" 
Schreibweise andeutet.

von Walter S. (avatar)


Lesenswert?

Tanja schrieb:
> Ich hatte auch adc16bit = leseadc * 0.00366;
> eingegeben

wie sind den adc16bit und leseadc deklariert bzw. welchen Wertebereich 
haben sie?

von Jim M. (turboj)


Lesenswert?

Tanja schrieb:
> Da ich Zahlen, wenn ich sie direkt eingebe ja auch korrekt konvertieren
> kann, vermute ich das der ADC irgendwas übermittelt was da ein PRoblem
> macht ..nur was?!?

Dein Problem ist, dass Du hier vergessen hast den Source Code zu posten. 
Prosa hilft nix, wie man leicht an den Beiträgen hier sieht.

Es ist weiterhin hilfreich wenn man als Programmierer das 
Zweierkomplement erkennen kann.

Solange man noch mit Dingen wie korrektem Casting und Vorzeichen auf 
Kriegsfuß steht, lohnt sich auch ein C-Compiler für den PC. Dort geht es 
mit dem Debugging viel leichter.

In Falle vom OP ist vermutlich das Datenregister vom ADC im C-Header als 
uint16_t oder uint32_t deklariert, was für einen single-Ended ADC auch 
korrekt wäre - aber bei differentieller Ansteuerung halt nicht.

von Tanja (Gast)


Lesenswert?

Der Wertebereich geht laut Datenblatt wie gesagt von -32xxx bis 
+32xxxder Source ist unbedeuted genauso wie der Schaltplan.
Es geht um die theoretische Grundlage.
Und in all meinen Büchern steht wenn ein long dabei ist wird sowiso 
implizit gecastet.
Es gibt wohl eine Ausnahme, bei Variablen...allerdings steht noch nich 
wie genau...
Also ist ADC=var_ADC * 0.232;
eine solche Ausnahme!?!
den ADC ist ja entweder ene Variable oder eine Funktion

von Tanja (Gast)


Lesenswert?

und dieses Beispiel ist doch falsch?!
http://www.improgrammer.net/type-casting-c-language/

da sollte doch %f verwendet werden und 20.0 rauskommen?!?

von STK500-Besitzer (Gast)


Lesenswert?

Tanja schrieb:
> Also ist ADC=var_ADC * 0.232;

0.232 ist ein double. Das sagt dem Compiler, dass alle Zahlen in der 
Rechnung als double zu verarbeiten sind (Teilergebnisse können auch 
Integer sein).

> eine solche Ausnahme!?!
Hier ist kein expliziter Cast notwendig.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Tanja schrieb:
> Der Wertebereich geht laut Datenblatt wie gesagt von -32xxx bis
> +32xxxder Source ist unbedeuted

Lieber Troll (Stefan? Thomas? Beliebiger Frauenname?),

der Source ist mitnichten unbedeutend, weil im Source Dein Fehler 
liegt.

von Tanja (Gast)


Lesenswert?

wie sind den adc16bit und leseadc deklariert bzw. welchen Wertebereich
haben sie?

na als double, wobei e ssich bei leseadc ja auch gleich um den 
funktionsaufruf leseadc(1) handeln könnte, also direkt den ADC Wert 
liefert und keine Variable darstellen könnte z.B: sollte ja beides gehen 
oder offenbar ebena uch nicht.
Nervig finde ich, das es in Pascal nur ein richtig oder falsch gibt, in 
C aber eine Antwort sich über etliche Seiten hinziehen kann...dafür das 
C in vielen Büchern als einfche Sprache bezeichnet wird, ist es 
lächerlich

von Tanja (Gast)


Lesenswert?

"Solange man noch mit Dingen wie korrektem Casting und Vorzeichen auf
Kriegsfuß steht"

wir würde mir das da helfen..da würde es ja funktionieren..es geht ja 
mit fiktiven Verten nur eben nicht wenn der echte ADC Wert kommt
Also wäre das PC Programm genau das Gegenteil von hilfreich, da man 
dieses PRoblem dort nie hätte ..womöglich..

von Tanja (Gast)


Lesenswert?

und nein, inder der selbstgeschreibene leseadc routine verwende ich auch 
etnweder double oder long

von Tanja (Gast)


Lesenswert?

was haben denn verscheine Namen mit Troll zu tun? Hast Du was getrunken, 
vielleicht schreibe ich von 2 Rehcnern aus und bin beidemale als 
GAST!!!! angemeldet!!

von Tanja (Gast)


Lesenswert?

"der Source ist mitnichten unbedeutend, weil.."

nö..alles steht ja da..es geht ja auch mit casten..die frage lautet 
wieso geht es implizit nicht!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Tanja schrieb:
> nö..alles steht ja da..es geht ja auch mit casten..die frage lautet
> wieso geht es implizit nicht!

Du bist offensichtlich nicht an einer Lösung Deines Problems 
interessiert.


> was haben denn verscheine Namen mit Troll zu tun? Hast Du was getrunken,
> vielleicht schreibe ich von 2 Rehcnern aus und bin beidemale als
> GAST!!!! angemeldet!!

Du kannst Dich noch nicht mal darauf einigen, welche Email-Adresse Du 
hier angibst.

Umgangsformen hast Du auch keine.

Und damit bist Du hier fehl am Platz.

: Bearbeitet durch User
von STK500-Besitzer (Gast)


Lesenswert?

Tanja schrieb:
> wieso geht es implizit nicht!

Weil es alles Integerzahlen sind - egal, ob mit oder ohne Vorzeichen.
Deswegen macht man ja auch ganz gerne ein "L" an kleine Zahlen in 
Definitionen, damit der Wertebereich bei Rechnungen beibehalten wird.

von Tanja (Gast)


Lesenswert?

wenn der Moderator sich mal an der Diskussion beteiligen würde oder 
ansonsten ebsser raushalten könnte und den Thrat der momentan gut läuft 
nicht weiter zumüllen könnte..DANKE!
@STK
Wenn ich doch aber adc=leseadc*0.02323; schreibe ist 0.232 kein Integer 
und laut den Lehrbüchern sollte dann der Compiler Implizit mit double 
arbeiten

von MaWin. (Gast)


Lesenswert?

Tanja schrieb:
> nö..alles steht ja da..es geht ja auch mit casten..die frage lautet
> wieso geht es implizit nicht!

Wir sollen also einen Fehler in deinem Code finden, ohne den Code zu 
kennen.

von Tanja (Gast)


Lesenswert?

Da haste Deinen Kot!!
 signed int  adc16bit=0.0;
 float adc16bit_float=0.0;

int adc_read_16Bit(void){
SDADC1_CR2.B23=1; //RSWSTART Starte ADC Wandlung
while (REOCF_bit == 0){};
adc16bit_float = (SDADC1_RDATAR+32768)* 0000.5394907207596029);
}


Aber genau das habe ich weiter oben bereits beschrieben....

von 1N 4. (1n4148)


Lesenswert?

Dann bleib einfach bei Pascal oder Rüdiger wenn du dich mit C nicht 
verstehst.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Tanja schrieb:
> wenn der Moderator sich mal an der Diskussion beteiligen würde oder
> ansonsten ebsser raushalten könnte und den Thrat der momentan gut läuft
> nicht weiter zumüllen könnte..DANKE!

Jetzt reichts.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.