hallo wie kann ich am effizientesten einen 32 bit wert, zb 1000100010001000....in 4 byte aufteilen, -> 10001000;10001000;.... Byte 4 ;Byte 3 besten dank tobias
Hi Tobias, Ich hab ein ähnliches Problem jedoch mit Word->2* byte Wenn du mit einem Basic Compiler arbeitet könntest du zuerst den Wert in einen 32 Byte String umwandeln, danach mit der Funktion Mid in 4 Teile einteilen(immernoch Strings). Und Schlussendlich mit einem Kleinen Progrämmchen, die Strings mit einsen und Nullen, wieder in Bytes umwandeln. Klingt zwar etwas kompliziert, sollte aber gehen.. MFG Nik
ich würde das ganze gerne in c oder sonst halt in assembler lösen. es gibt sicherlich einen mathematischen weg. weiss nur noch nicht wie. tobias
Probier mal, ein union zu definieren aus a.) 4 Bytes und b.) 1 long. Das gabs hier schonmal, schau mal das hier an: http://www.mikrocontroller.net/forum/read-1-27159.html#27159 Mit der String-Methode schaffst Du es sicher auch ins Guiness-Buch, aber sicher nicht für den effizientesten Code ;-) Stefan
Hi liesst du den Wert Seriell ein? oder hast du den schon irgendwie in einer 32 Bit Variabel? Also bei mir war das so, das der Sensor nen 32 Bit Wer ausgibt, Seriell, zum Clock bei jeder Flanke. Da hab ich mir in Assembler sowas gebastelt für: byteout: cpi r20 , 8 brsh j24to8_1 lsl r21 in r24 , PINC andi r24 , 0b00000001 or r21, r24 inc r20 rjmp bitout_out j24to8_1: cpi r20 , 16 brsh j24to8_2 lsl r22 in r24 , PINC andi r24 , 0b00000001 or r22, r24 inc r20 rjmp bitout_out j24to8_2: cpi r20 , 24 brsh bitout_out lsl r23 in r24 , PINC andi r24 , 0b00000001 or r23, r24 inc r20 bitout_out: ret Das speichert mir meinen Seriellen Wert in den Registern R21-R24 Vor diesem Programm ist nur noch ein klein bischen Code um mir meine HL und LH Flanke zu detektieren. Das hab ich jetzt hier mal weggelassen :) Gruss Darko
nein, ich lesen den wert nicht seriell ein. ich mache eine berechnung und das ergebniss ist dann ein long, und diesen long wert muss ich nun in 4byte aufteilen. tobias
Hi entweder über ein union (wobei ich da immer bedenken habe wegen der Portierung auf andere Systeme) oder aber: unsigned char b1,b2,b3,b4; unsigned long l; b1=l&0xff; b2=(l>>8)&0xff; b3=(l>>16)&0xff; b4=(l>>24)&0xff; Matthias
Hi! Du kannst das auch auf diese Weise Lösen:(nur so ne art Pseudo-Code) wert = (deine 32 bit zahl als long-variable) if wert = 4294967296 then firstbyte = 255 : secondbyte = 255 : thirdbyte = 255 : fourtbyte = 255wenn die zahl gleich die höchstmögliche ist dann alle bits auf 1 setzen 'wenn nicht dann alles Abklappern, bis der gewünschte wert ausgerechnet ist '/////////////////////////////////// 'erstes byte auffüllen if wert > 2147483648 then firstbyte = firstbyte + 128 : wert = wert -2147483648 if wert > 1073741824 then firstbyte = firstbyte + 64 : wert = wert - 1073741824 if wert > 536870912 then firstbyte = firstbyte + 32 : wert = wert - 536870912 if wert > 268435456 then firstbyte = firstbyte + 16 : wert = wert - 268435456 if wert > 134217728 then firstbyte = firstbyte + 8 : wert = wert - 134217728 if wert > 67108864 then firstbyte = firstbyte + 4 : wert = wert - 67108864 if wert > 33554432 then firstbyte = firstbyte + 2 : wert = wert - 33554432 if wert > 16777216 then firstbyte = firstbyte + 1 : wert = wert - 16777216 '////////////////////////////////// 'zweites Byte auffüllen if wert > 8388608 then secondbyte = secondbyte + 128 : wert = wert -8388608 if wert > 4194304 then secondbyte = secondbyte + 64 : wert = wert - 4194304 if wert > 2097152 then secondbyte = secondbyte + 32 : wert = wert - 2097152 if wert > 1048576 then secondbyte = secondbyte + 16 : wert = wert - 1048576 if wert > 524288 then secondbyte = secondbyte + 8 : wert = wert - 524288 if wert > 262144 then secondbyte = secondbyte + 4 : wert = wert - 262144 if wert > 131072 then secondbyte = secondbyte + 2 : wert = wert - 131072 if wert > 65536 then secondbyte = secondbyte + 1 : wert = wert - 65536 '////////////////////////////////// 'drittes Byte auffüllen if wert > 32768 then thirdbyte = thirdbyte + 128 : wert = wert -32768 if wert > 16384 then thirdbyte = thirdbyte + 64 : wert = wert - 16394 if wert > 8192 then thirdbyte = thirdbyte + 32 : wert = wert - 8192 if wert > 4096 then thirdbyte = thirdbyte + 16 : wert = wert - 4096 if wert > 2048 then thirdbyte = thirdbyte + 8 : wert = wert - 2048 if wert > 1024 then thirdbyte = thirdbyte + 4 : wert = wert - 1024 if wert > 512 then thirdbyte = thirdbyte + 2 : wert = wert - 512 if wert > 256 then thirdbyte = thirdbyte + 1 : wert = wert - 256 '////////////////////////////////// 'viertes Byte auffüllen if wert > 128 then fourtbyte = fourtbyte + 128 : wert = wert -128 if wert > 64 then fourtbyte = fourtbyte + 64 : wert = wert - 64 if wert > 32 then fourtbyte = fourtbyte + 32 : wert = wert - 32 if wert > 16 then fourtbyte = fourtbyte + 16 : wert = wert - 16 if wert > 8 then fourtbyte = fourtbyte + 8 : wert = wert - 8 if wert > 4 then fourtbyte = fourtbyte + 4 : wert = wert - 4 if wert > 2 then fourtbyte = fourtbyte + 2 : wert = wert - 2 if wert > 1 then fourtbyte = fourtbyte + 1 : wert = wert - 1 So. Nun sind in firstbyte, secondbyte, thirdbyte und fourtbyte die entsprechenden Werte als Dezimalzahl gespeichert. MFG NIK P.S. In Fourthbyte ist das niederwertigste Byte gespeichert(mit werten bis zu 255)
Hi @Nik du erhälst heute den "viel Text, wenig Sinn" Award :-) Was du da machst ist im Prinzip die fortgesetzte Division durch zwei. Wenn man das schon so machen will (will man aber nicht) dann in einer Schleife. Matthias
Hi @Matthias Sorry, hab von C echt überhaupt keeeeine Ahnung, desshalb wusste ich auch überhaupt nicht was du da in deinem Code geschrieben hast ;-) MFG Nik
Hallo! Will hier auch mal meinen Senf dazugeben: Man könnte nach rechts shiften (lsl) und wenn eine 1 rechts herausfällt, dann sollte ein Flag gesetzt werden (glaube es ist das Carry-Bit, bin aber gar nicht sicher...). In diesem Fall ist kann man dan das entsprechende Bit im Byte auf eins setzen und das macht man 32 Mal...
Hallo Nik, Hallo tobias, bevor Ihr loprogrammiert, solltet Ihr Euch erstmal überlegen, wie es denn in Eurem MC aussieht. Die 32Bit kann Euer MC ja nicht am Stück speichern ich nehme an, Ihr arbeitet auf Atmel). Wie macht er es dann? Richtig, er speichert es in 4 Bytes ab ... Im Prinzip liegt also irgendwo im MC Euer Ergebnis schon fix und fertig drin, wenn Ihr es schafft, auf diese 4 Byte Eures Long einzeln zuzugreifen, dann habt Ihr schon gewonnen - ohne eine einzige Berechnung auszuführen. Die "schönste" Lösung ist dabei meiner Meinung die Union. Aber was ist das? Ihr erklärt Eurem Compiler, dass Er auf Eure Long nicht nur als Long, sondern auch anders, nämlich als 4 Bytes, zugreifen kann. Im Programm könnt Ihr dann entweder auf die Long oder auf eins der 4 Bytes zugreifen, je nachdem, welchen Namen Ihr hinschreibt. Ihr werded am Anfang zwar etwas mehr Verständnis-Zeit brauchen, aber die lohnt sich, glaubts mir! Stefan P.S.: Die Lösung von Matthias hat sicher auch ihre Berehtigung, ich denke aber nicht, dass Ihr Euch in naher Zukunft mit Portierungsfragen rumärgern müsst ...
hallo stefan die lösung mit einer union wäre das idealle. ich habe jedoch noch nie etwas mit einer union gemacht. ich habe auch nach dem alten tread gesucht der oben erwähnt wird. habe jedoch das beispiel 32bit zu 4x 8byte nicht gefunden. vieleicht kannst du mir ja noch einen tip geben. danke tobias
typedef union { unsigned char b[4]; unsigned long l; } typ_mixed; int main(void){ typ_mixed mylong; volatile unsigned long ergebnis; mylong.b[0] = 0; /* unteres Byte = 0 */ mylong.b[1] = 1; /* zweites Byte = 1 */ mylong.b[2] = 2; /* drittes Byte = 2 */ mylong.b[3] = 3; /* oberes Byte = 3 */ /************************************ mylong als Long gesehen ist jetzt: 0 + 1 * 256 + 2 256 256 + 3 256 256 * 256 *************************************/ ergebnis = mylong.l; return(0); }
Hallo zusammen, ich versuche mich gerade in der Assembler-Programmierung eines AVR. Dabei würde ich gerne bis zu 24 Stunden lang per Timer-Overflow-Interrupt Millisekunden zählen. Dazu brauche ich auch einen 32bit-Wert. Für die Erzeugung des 1ms Taktes habe ich den Timer 0 und besagten Interrupt verwendet (klappt auch). Wie lege ich in Assembler eine 32bit-Variable an? oder muss ich 4 Variable definieren und diese auf Überlauf überwachen um dann die nächst zu erhöhen? Gruß Jörg
Es gibt noch so eine ähnlich Lösung wie die Unions. Weiß nicht ob das auf nem ATMEL geht, aber unter Windows-C++ hab ichs mal gemacht. long l; long * pl = &l; wenn man jetzt auf das erste byte zugreifen will einfach so: (byte*)pl; für das zweite ((byte*)pl) + 1; usw... so hat man dann die Adressen der einzelnen Byte Variablen, mit denen man arbeiten kann. mfg Michael
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.