mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bitblöcke auslesen


Autor: Toby Meier (toby_sx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich würde gerne möglichst effizient CAN Nachrichten auswerten. Diese
bestehen immer aus 1..8 zusammenhängenden Bytes. Beispielsweise kann ein
Signal bei bit 2 starten und 10bit lang sein. Ich wollte nun
schrittweise immer zwei Byte (damit maximal 16Bit breite Worte) mit
einem Short-Zeiger auswählen und dann mit entsprechender Maskierung
verUNDen. Leider lässte der kompiler die conversion von char* zu short
int* nicht zu.

Folgendes wollte ich also tun:

short * block;
char msg[]="ABCDEFG";

/*lenght soll die länge meine wortes in bit angeben, starbit ist
selbsterklärend*/

block = &msg; // also damit sollte der short auf das untere Byte zeigen
block = block & ((short)(pow(2,length) << startbit));

nun sollte eigentlich meine nachrichtig fertig maskiert in block stehen,
sodass ich diese nur wieder um startbit in die gegenrichtung shiften
müsste.

gibt es vielleicht eine elegantere lösung, um aus einem 2er Byteblock
einen beliebig langen (max16) bitblock zu lesen?

grüße und danke für ideen,
toby

Autor: Briegel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
Deklariere doch einfach ein bitfield Typen. Das ist imho die Art, sowas 
zu tun.

Autor: Toby Meier (toby_sx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, aber das hilft mir nicht viel weiter. Ich kann doch bits aus 
bitfelder nicht mit einem befehl beschreiben, jedenfalls steht das 
nirgends in den definitionen...

für den fall ich hätte ein bitfeld mit b0 bis b7 wäre ein befehl:

bitfeld.b0 = 0x41; recht brauchbar, wenn er die anderen bits nach b0 
überschreiben würde. funktioniert aber nicht.
Weitere tips?

gruß,
toby

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
2 Sachen:

1.
pow() ist eine float-Funktion, d.h. es dauert ewig lange und kostet zich 
kB Code. Beschäftige dich besser mal mit Schiebeoperatoren.

2.
Die Byteorder in mehrbytigen Variablen ist nicht definiert.
Was auf der einen CPU mit dem einen Compiler funktioniert, kann Dir mit 
ner anderen großen Mist produzieren.
Daher macht man es üblicher Weise kompatibel:
short val = byte_low | (byte_high << 8);



Um nun z.B. die Bits 2..9 zu extraieren, maskiert man oben und schiebt 
nach unten:
val9_2 = (val & (1 << 9 + 1) - 1) >> 2;


Peter

Autor: Toby Meier (toby_sx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter!

Vielen Dank für die Hilfe, die Möglichkeiten der Bitoperationen habe 
ich, wie es scheint, nicht ausgenutzt.

Ich versuche gerade die Bitextraktion zu verstehen. Irgendwie steh ich 
auf dem Schlauch.

val9_2 = (val & (1 << 9 + 1) - 1) >> 2;

Wie läuft dieser Vergleich ab? wozu die -1? Welche Operation hat vorrang 
in der klammer?


vielleicht ist es einfach schon ein bisschen spät! Auf jeden Fall 
funktioniert es schon mal!

Gruß,
Toby

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie läuft dieser Vergleich ab

In diesem Ausdruck ist kein einziger Vergleich!

  >>  bedeutet 'bitweise nach rechts schieben'
  <<           'bitweise nach links schieben'

  i = k << 2;

der Inhalt wird also um 2 Bits nach links verschoben und das
Ergebnis wird i zugewiesen.

Zu deinem ursprünglichen Ansatz:
> leider .. char* zu short int* nicht zu.

Ja, klar. Ein Pointer auf int ist nunmal kein Pointer auf char.
Wenn du allerdings sicher bist, dass du genau das willst,
dass der Compiler so tut, als ob der Pointer auf char
einer auf int wäre, kannst du ihn immer überstimmen: mit
einem Cast

block = (short*) &msg;

Aber Vorsicht: Ein Cast ist eine Waffe. Effektiv schaltest du
damit das Typ-Prüfsystem des Compilers ab und zwingst ihn die
Zuweisung wider besseren Wissens zu akzeptieren. Der Programmierer
sollte also besser wissen was er hier tut.

Die Anmerkungen bezüglich Nicht-Portabilität gelten natürlich
weiterhin.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> aber was macht die -1?

Probiers doch einfach aus!
Hinweis: Du musst dir das binär, also auf Bitebene ansehen.

Die Fragestellung lautet: wenn du eine Binärzahl hast
die eine 2-er Potenz ist ( 1 << x liefert logischerweise
immer eine 2-er Potenz) und dann 1 davon abziehst, wie
sieht dann das Ergebnis aus, welchem Muster folgt es?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.