Hallo zusammen, ich benötige mal wieder Hilfe aus der µC-Gemeinde. Folgendes Problem: Ich habe 4 Variablen Byte1 bis Byte4 vom Typ Int. Diese 4 Variablen beinhalten Hex-Zahlen, bspw. A0. Außerdem habe ich eine Funktion in der ich diese 4 Bytes mit einander verketten möchte zu einer Variablen X, damit ich diese Variable X als Rückgabewert wieder herausgeben kann aus der Funktion. Noch zur Info: Ich arbeite mit dem TASKING VX-toolset V3.1 Alle Bibliotheken und Headerdateien sind natürlich vorhanden die ich dafür brauche nur bei mir will der einfach nicht X wiedergeben, da ich es bisher mit einem Array versucht habe. Außerdem wäre es nicht schlecht, wenn man mit der zurück gegebenen Variablen X auch die einzelnen Bytes wieder extrahieren kann zur eventuellen Weiterverarbeitung oder Auswertung. Danke schon mal im Voraus Gruß, Josef
Joey T. schrieb: > Ich habe 4 Variablen Byte1 bis Byte4 vom Typ Int. > Diese 4 Variablen beinhalten Hex-Zahlen, bspw. A0 nein machen sie nicht, ein INT wert kann keine Hexzahlen enthalten. HEX ist eine Darstellungsform. Sie kann maximal in einem String stehen. Also bitte noch mal von vorne: Was willst du haben, möglichst mit Beispiel?
Ok, eine dezimale zahl kann als binäre zahl dargestellt werden. unterteile ich diese binäre zahl in ihre nibbel, kann man direkt nibbelweise die hexadeziamle darstellung ablesen. ob hexadezimal oder binär sind also nur unterschiedliche betrachtungsweisen des selben bitmusters.
Joey T. schrieb: > Ich habe 4 Variablen Byte1 bis Byte4 vom Typ Int. Sind das jetzt Bytes oder Int. Wenn Int welcher Wertebereich? Mit oder ohne Vorzeichen? Du musst präzise sein.
Ok, mein Fehler, nochmal von vorn: Ich habe 4 Variablen Byte1 bis Byte4 vom Typ char und beinhalten jeweils eine Zahl die nicht größer als 1 Byte ist (max. Wertebereich von char). Diese sind nicht mit einem Vorzeichen behaftet. Diese 4 Werte erhalte ich aus einer Unterfunktion, die ich 4 mal aufgerufen haben und den Byte1 bis Byte4 jeweils zugewiesen habe. Jetzt möchte ich eigentlich nur diese 4 Werte mit einander verketten in einer Variablen und diese als Rückgabewert aus der Funktion wiedergeben. Mit diesem Rückgabewert muss aber noch weitergearbeitet werden, wobei die Werte Byte1 und Byte2 zusammen gehören und Byte3 mit Byte4. Die Anordnung wäre diese: 0bXXXXXXXX XXXXXXXX => 0bByte2 Byte1. Könnte man dafür einfach das Byte2 um 8 Bits nach links verschieben und dann mit Byte1 addieren? Ein Beispiel: Rückgabewert Hauptfunktion(a,b) { Byte1 = Unterfunktion(x); Byte2 = Unterfunktion(y); Byte3 = Unterfunktion(z); Byte4 = Unterfunktion(a); /* Variable_K soll nun diese 4 Werte mit einander verketten und als Rückgabewert aus der eigentlichen Fuunktion kommen. */ return Variable_K; } Nun möchte ich mit diesem Wert weiter arbeiten, bspw. möchte ich das kombinierte Byte1 und Byte2 mit einem Wert vergleichen. Gleiches gilt für das kombinierte Byte3 und Byte4. Danke im Voraus Gruß, Josef
Zwei 8-Bit-Werte lassen sich selbstverständlich zu einem 16-Bit-Wert zusammenfassen: uint8_t a = 0x12; uint8_t b = 0x23; uint16_t x; x = (a << 8) + b; Allerdings: Wenn Deine Funktion Deine vier Werte zu zweien zusammenfasst, aber nur einen davon zurückgibt, kannst Du außerhalb der Funktion nichts mit dem anderen Wert anstellen, der ist dann weg.
Rufus Τ. Firefly schrieb: > Allerdings: Wenn Deine Funktion Deine vier Werte zu zweien > > zusammenfasst, aber nur einen davon zurückgibt, kannst Du außerhalb der > > Funktion nichts mit dem anderen Wert anstellen, der ist dann weg. Dem bin ich mir auch bewusst. Was ich sagen wollte ist, dass ich schon alle 4 Werte aus der Funktion erhalten möchte. Ich habe das mit dem kombinieren der Bytes gesagt, damit es klar ist wie ich weiter arbeiten möchte mit den Werten. Ich könnte mir das so vorstellen: long int Variable_K = (Byte4<<24)+(Byte3<<16)+(Byte2<<8)+Byte1; Diese Variable_K könnte ich dann doch als Rückgabewert nutzen, wenn natürlich meine Funktion auch mit dem gleichen Rückgabetyp definiert wird!? Frage ist nun, wenn ich bspw. die kombinierten Bytes4 und 3 mit dem Wert 0xA1B2 vergleichen möchte? Mir würde jetzt nur spontan einfallen, so wie ich es erstellt habe, so mache ich es auch wieder rückwärts. sprich Variable_K >> 16;
Wenn Du sagst, das die einzelnen chars zusammengehören, dann mache es doch mit einer Union:
1 | typedef union |
2 | {
|
3 | uint32_t as_uint32; |
4 | int32_t as_int32; |
5 | uint16_t as_uint16[2]; // avr uses little endian - LSB is uint16[0] |
6 | int16_t as_int16[2]; |
7 | uint8_t as_uint8[4]; // avr uses little endian - LSB is uint8[0] |
8 | int8_t as_int8[4]; |
9 | struct // if code runs on other endianess - change here |
10 | {
|
11 | uint8_t lolo8; |
12 | uint8_t lohi8; |
13 | uint8_t hilo8; |
14 | uint8_t hihi8; |
15 | };
|
16 | } t_data32; |
17 | |
18 | t_data32 foo; |
Dann kannst Du auf die 4 Werte wie folgt zugreifen:
1 | // Byteweise
|
2 | bar = foo.as_int8[0]; |
3 | bar = foo.as_int8[1]; |
4 | bar = foo.as_int8[2]; |
5 | bar = foo.as_int8[3]; |
6 | |
7 | // Als uint16_t
|
8 | bar = foo.as_uint16[0]; |
9 | bar = foo.as_uint16[1]; |
10 | |
11 | // usw
|
So geht's auch: char nByte[4] = {0x11, 0x22, 0x33, 0x44}; int* nX = (int*) nByte; short* nSlow = (short*) nByte; short* nShigh = (short*) (nByte + 2); void Funktion(<Para>) { nByte[0] = Unterfunktion(x); nByte[1] = Unterfunktion(y); nByte[2] = Unterfunktion(z); nByte[3] = Unterfunktion(a); } Joey T. schrieb: > Frage ist nun, wenn ich bspw. die kombinierten Bytes4 und 3 mit dem Wert > 0xA1B2 vergleichen möchte? if (*nShigh == 0xA1B2) { } mfg.
Habe es jetzt erst mal so gelöst, wie ich es in meinem letzten Post gesagt habe. long int Funktion(q,w) { char Byte1 bis 4; long int Variable_K; Byte1 = Unterfunktion(x); Byte2 = Unterfunktion(y); Byte3 = Unterfunktion(z); Byte4 = Unterfunktion(a); return Variable_K = (Byte4<<24)+(Byte3<<16)+(Byte2<<8)+Byte1; } if(((Funktion(h,j))>>16) == 0xA1B2) { } So funktioniert es auch. Ich finde aber den Ansatz von Thomas Eckmann auch ganz gut. Nach meinem Verständnis von dem was ich gerne haben möchte, müsste das ja wie folgt aussehen: XXXX Funktion(q,w) { char nByte[4] = {0x11, 0x22, 0x33, 0x44}; int* nX = (int*) nByte; short* nSlow = (short*) nByte; short* nShigh = (short*) (nByte + 2); nByte[0] = Unterfunktion(x); nByte[1] = Unterfunktion(y); nByte[2] = Unterfunktion(z); nByte[3] = Unterfunktion(a); return QQQQ; } Meine Frage ist jetzt, wie müsste der Rückgabetyp und Returnwert definiert sein, damit ich nach dem Funktionsaufruf bespw.: if(*nShigh == 0xA1B2){} durchführen kann?
Joey T. schrieb: > return Variable_K = (Byte4<<24)+(Byte3<<16)+(Byte2<<8)+Byte1; Bist Du sicher, daß das funktioniert? Ich vermute daß der Rückgabewert immer kleiner als 65536 ist. Die Rechenoperationen werden auf int durchgeführt und da ergeben Schiebeoperationen mit 16 oder mehr Bits immer 0. Du müsstest die einzelnen Variablen schon auf long casten, damit es korrekt ist.
Volkmar Dierkes schrieb: > Bist Du sicher, daß das funktioniert? Ich vermute daß der Rückgabewert > immer kleiner als 65536 ist. Die Rechenoperationen werden auf int > durchgeführt und da ergeben Schiebeoperationen mit 16 oder mehr Bits > immer 0. > > Du müsstest die einzelnen Variablen schon auf long casten, damit es > korrekt ist. Nehme meine Aussage zurück. War zusehr auf AVR fixiert, da Du im Forum PC-Programmierung gepostet hast, nehme ich mal an, das dort standardmäßig nicht mit int sondern long gerechnet wird, und dann tritt der Fehler nicht auf.
Joey T. schrieb: > Meine Frage ist jetzt, wie müsste der Rückgabetyp und Returnwert > definiert sein, damit ich nach dem Funktionsaufruf bespw.: char nByte[4] = {0x11, 0x22, 0x33, 0x44}; int* nX = (int*) nByte; short* nSlow = (short*) nByte; short* nShigh = (short*) (nByte + 2); void Funktion(<Para>) { nByte[0] = Unterfunktion(x); nByte[1] = Unterfunktion(y); nByte[2] = Unterfunktion(z); nByte[3] = Unterfunktion(a); } Das Byte-Array wird global angelegt und der Zugriff erfolgt dann mit verschiedenen Pointern immer auf die gleiche Speicherstelle. Je nach Pointertyp können dann 1, 2 oder 4 Bytes gelesen werden. Um mit nShigh auf Byte 2 und 3 zuzugreifen, muß der Pointer dann um 2 erhöht werden. Die Daten werden einfach ins globale Array geschrieben und sind auch nur einmal vorhanden. Deshalb hat die Funktion, die die Daten mit Unterfunktion() abholt, auch keinen Rückgabewert. Du kannst das Byte-Array aber auch als Parameter an Funktion() übergeben. Dann kann dieses in der aufrufenden Funktion lokal angelegt sein. void Funktion(<Para>, char* nArray) { ... } In Funktion() darfst du das nicht packen, da die Variable nByte, die einzige Variable, die angelegt wird, auf dem Stack liegt und nach Beendigung der Funktion nicht mehr da ist. Volkmar Dierkes schrieb: > Die Rechenoperationen werden auf int > durchgeführt und da ergeben Schiebeoperationen mit 16 oder mehr Bits > immer 0. Ich gehe davon aus, daß das ein 32-Bit Rechner ist, bei dem int 32 Bit lang ist. Sonst muß man natürlich statt int long nehmen. mfg.
Volkmar Dierkes schrieb: > Die Rechenoperationen werden auf int durchgeführt und da ergeben > Schiebeoperationen mit 16 oder mehr Bits immer 0. Das kommt auf die Größe von int an. Joey ist etwas inkonsistent, was seine Angaben betrifft. Einerseits postet er unter "PC-Programmierung", andererseits schreibt er von einem Tasking-Compiler. Die Zielarchitektur fehlt, oder hab ich sie nur übersehen? Wie dem auch sei: Bei diesem Compiler kann sizeof(int) unterschiedlich groß sein, je nach Prozessor. Prinzipiell ist der Cast aber eine gute Idee, denn dann geht's mit jeder Architektur.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.