Hallo zusammen, bitte nich steinigen ist mein erster Versuch damit.
Ich habe verschiedene Messwerte die ich in einer Struct ablegen möchte.
Es wird immer HI und LOW byte eingelesen. Den 16 bit wert möchte ich
dann
in Wert1 speichern und ausgeben wollen.
Ich würde gerne bq2084.V ausgeben wollen aber folgendes geht nicht.
Wert1 = bq2084.V;
Dort gibs nen ../main.c:300: error: incompatible types in assignment
Kann mir jemand helfen ?
Danke...
Jörg Esser schrieb:> in Wert1 speichern und ausgeben wollen.> Ich würde gerne bq2084.V ausgeben wollen aber folgendes geht nicht.> Wert1 = bq2084.V;> Dort gibs nen ../main.c:300: error: incompatible types in assignment>> Kann mir jemand helfen ?
Schaun wir uns die Dinge mal an:
> Wert1 = bq2084.V;
Welcher Datentyp steht links vom = ?
Da ist die Variable Wert1 und die hat den Datentyp uint16_t
Welcher Datentyp steht rechts vom = ?
Da ist die Variable bq2084.V
bq2084 ist vom Datentyp 'struct anonym' und innerhalb dieser Struct gibt
es einen Member V, der vom Datentyp be_int16_t (der ein typedef für eine
struct ist) ist.
Somit steht da, datentypmässig gesehen
uint16_t = be_int16_t;
Was lässt dich jetzt glauben, die beiden wären zuweisungskompatibel?
Links vom = steht ein primtiver Datentyp, der für einen 16 Bit Integer
ohne Vorzeichen steht, rechts vom = steht ein Datentyp der für eine
komplette Struktur steht.
Du musst mit Datentypen agieren, wie in der Physik mit Einheiten. WEnn
da zum SChluss rauskommt, dass du eine Formel gebaut hast, in der nach
AUflösen aller Datentypen rauskommt
Meter = Sekunden
dann hast du wohl was falsch gemacht. Einziger Unterschied: In C klopft
dir der Compiler auf die Finger, wenn du versuchst Äpfel mit Birnen zu
verrechnen.
Und wiedermal erkenne ich das Mathe nie meine Stärke war ;)
Für mich ist bq2084.mA ein be_unint16_t und nich bq2084.V
oder übersehe ich was ?
Struct be_unint16_t sind doch 2 mal uint8_t also ein uint16_t oder ?
Ich bin immer noch hilflos ;)
Thx,
Jörg
Jörg Esser schrieb:> Und wiedermal erkenne ich das Mathe nie meine Stärke war ;)
Da gehts nicht um Mathe.
Es geht ganz einfach darum, dass es in einer Programmiersprache wie C
nicht einfach nur darum geht links und rechts vom = einfach irgendwas
hinzuschreiben, sondern dass es neben den Variablennamen auch noch
Datentypen gibt, die zusammenstimmen müssen. So wie ein Stössel zwar in
ein Loch passt, aber eben nur dann wenn die Stösselform auch zur
Lochform passt.
> Für mich ist bq2084.mA ein be_unint16_t und nich bq2084.V> oder übersehe ich was ?
1
struct
2
{
3
be_unint16_tCharge_mA;
4
be_unint16_tCharge_Voltage;
5
be_int16_tmA;
6
be_unint16_tV;<-----------wasstehtdaalsDatentyp?
7
be_unint16_tTemp;
8
be_unint16_tFull;
9
}bq2084;
> Struct be_unint16_t sind doch 2 mal uint8_t also ein uint16_t oder ?
Nö.
2 uint8_t sind erst mal nur 2 uint8_t. Nicht mehr und nicht weniger. Das
du der Meinung bist, die beiden Bytes könnte man zu einem 16-Bit
Datenytp zusammenfassen, mag schon sein, interessiert aber den Compiler
nicht. Für den ist eine Struktur, die aus 2 uint8_t besteht noch lange
nicht dasselbe wie ein uint16_t
(Aber: Man kann Casten. Damit kann man den Compiler immer überstimmen,
indem man selber das Ruder in die Hand nimmt und die Datentypprüfung für
eine Operation abschaltet oder überstimmt oder eine Konvertierung in
Auftrag gibt)
Jörg Esser schrieb:> Struct be_unint16_t sind doch 2 mal uint8_t also ein uint16_t oder?
Das beide zufällig oder absichtlich die gleiche Anzahl Bits belegen,
macht sie noch nicht zuweisungskompatibel.
Karl Heinz Buchegger schrieb:> Somit steht da, datentypmässig gesehen> uint16_t = be_int16_t;
So ist es. Das geht halt nicht.
Oliver
> Für mich ist bq2084.mA ein be_unint16_t und nich bq2084.V> oder übersehe ich was ?
Habs jetzt erst gesehen. Da bin ich wohl bei
uint16_t = be_int16_t;
in die Falsche Zeile zum Copy&Paste gerutscht. Spielt aber keine Rolle,
denn am eigentlichen Prolem ändert das ja nichts. Ob be_uint16_t oder
be_int16_t spielt so gesehen keine Rolle. Beides sind Strukturen und
ganz sicher keine uint16_t.
Gut verstanden. Danke euch erstmal. Muss ich wohl nochmal was lesen und
lernen.
Kann es sein das man besser die Finger davon läßt damit man portierbar
bleibt?
Ich will das zwar zur Zeit nur auf einem attiny85 laufen lassen, aber
wenn
ich den Code mal woanders verwende stehen die Chancen gut das es nicht
wie vorhergesehen funktioniert. (Prozessor und Compilerabhängig.Casten
geht überall etc.)
Ich habe eigentlich nur damit angefangen um den Code besser lesbar zu
machen.
Und eventuell ein wenig komfortabler.
Jörg Esser schrieb:> Gut verstanden. Danke euch erstmal. Muss ich wohl nochmal was lesen und> lernen.>> Kann es sein das man besser die Finger davon läßt damit man portierbar> bleibt?
Ein weises Wort.
Denn: Wie genau die beiden Bytes in einem 16-Bit int im Speicher
abgelegt werden (in welcher Reihenfolge), wird von C nicht festgelegt.
Das entscheidet die Plattform (also im weitesten Sinne der Hersteller,
der die CPU gebaut hat).
Natürlich gibt es Mittel und Wege, wie man die Operation, so wie du sie
dir vorstellst, implementieren kann. Eine Möglichkeit, umcasten, wurde
ja schon genannt.
Wert1 = *(uint16_t*)&bq2084.V;
Der spingende Punkt ist dann eben: Jetzt bist du in der Pflicht. Der
Compiler ist aus dem Schneider (wie bei allen Casts). WEnn das auf einer
Plattform nicht funktioniert (aus welchen Gründen auch immer: wegen
Padding Bytes, wegen unterschiedlicher Endianess, ....), dann hast du
Mist gebaut und nicht der Compiler.
Die einzig mögliche tatsächlich portierbare Version hast du ja in deinem
Programm schon benutzt. Wenn du die nimmst, dann kann dir nie irgendwas
passieren. Du erkaufst dir das möglicherweise mit ein wenig erhöhter
Laufzeit, bist dafür aber unabhängig.
> Ich habe eigentlich nur damit angefangen um den Code besser lesbar zu> machen.> Und eventuell ein wenig komfortabler.
Tja. Das Mittel dazu führt aber eigentlich immer darüber, dass man sich
Funktionalität in Funktionen auslagert. Mit solchem klein/klein
Geplänkel erreicht man nicht sehr viel.
@all
Vielen Dank fürs erklären und die Entscheidungfindung.
@Bernd
Du kannst ja mal vorbeikommen und es dir anschauen ;)
Der Code is mir noch zu peinlich um ihn vorzuzeigen :)
Zuviele
#if 0
#endif
und
/*
*/
ausserdem total viel
//
Wenns mal fertig is stell ich es wohl hier rein.
Soll nen Lader für Li-Ion Akkus werden, die von einem bq2084
überwacht werden. Das alles mit einem kleinen attiny85 und
Kleinkram drumherum. Gespeist von einem AT Netzteil.
Gruss,
Jörg
Eine eigene Frage?
Dieser Thread ist über 14 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.