Forum: Mikrocontroller und Digitale Elektronik Bitlogik - Bitmasken - universelle Zuweisung


von daniel (Gast)


Lesenswert?

Hi,

ich suche nach einer Moeglichkeit fuer eine Bitzuweisung wo ich mit 
einer Maske mehrere Bits auswaehle und durch logische Kombinationen nur 
ein definiertes Bit dieser Maske, mit einer Funktion steuere. Dies soll 
in eine Zusweisung passen, also eine Kombination der Klammerung ist 
moeglich. Diese Zuweisung erfolgt in einer hoeheren 
Programmiersprache(Sructured Text (PLC),C)[sollte aber auch von C in ST 
uebersetzbar sein ;)] Wichtig ist,dass an dem Funktionsaufruf im 
nachhinein nichts mehr geaendert werden soll. (Kann nichts mehr 
veraendert werden)

Ich denke da an die Moeglichkeit das 2 Informationen in der Maske 
stecken. Die eine Information ist definiert und zwar das alle Bits eines 
Prozesses in der Maske nacheinander zu folgen haben.
Die andere Information ist eben die, dass die selektierten Bits "1" und 
die Anzahl durch die Maske bekannt sind.
Leider will mir dafuer die Loesung nicht einfallen. Denn ich denke, es 
ist die Auswertung der Stelle dieser maskierten Bits nicht in einer 
logischen Kombination (auch mit Klammerung) und in einer Zuweisung 
durchfuehrbar. Stimmt diese Annahme,oder gibt es da doch eine 
Moeglichkeit?

Beispiel:

- 2 Funktionen nutzen 1 Byte
- dieses Byte definiert Bits an einem Port
- dieses Byte selbst stellt eine Bitmaske dar
- aus diesem Byte sollen die Informationen fuer die einzelnen Bits 
entschluesselt werden
die Funktion:
- benoetigt eine Maske
- benoetigt eine Information fuer die maskierten Bits der Maske

func asdf(mask = LogicCombinatedBitmask ( zuweisung kann logische 
Kombinationen enthalten), value = LogicCombinatedValue(nur das 
definierte bit aus der Bitmask soll den Wert 1 enthalten))
die funktion "asdf" steht selbst in einer funktion "qwer" welche nur 
die Bitmaske durchreichen soll. Intern kann die Funktion "qwer" aber 
Konstanten zur logischen Kombination enthalten.

der zugriff soll dann wiefolgt aussehen:
Prozess1 mit mask = 00111000;
Prozess2 mit mask = 00000111;

function "qwer" wird von mit Prozess 2 aufgerufen.
in dieser wird dann irgendwo die function "qwer" aufgerufen, mit der 
Bedigung das nur Bit2 der Bitmaske von Prozess 2 gesetzt/rueckgesetzt 
werden soll.
Das heisst in der function "qwer" soll die function "asdf" mit der logik 
zuweisung so angesteuert werden dass sie nur das Bit 2 der Maske von 
Prozess2 setzt oder ruecksetzt, Bit 1 und Bit 3 aber unbehandelt 
bleiben.

Ist dies durch logische Kombination, auch auf beiden Eingangsvariablen 
Mask und Value, in einer Zuweisung (eine fuer jeweils die entsprechende 
Eingangsvariable) moeglich?

Vielen Dank
daniel

von Matthias L. (Gast)


Lesenswert?

Irgendwie verstehe ich überhaupt nicht was du vorhast.

>ich suche nach einer Moeglichkeit fuer eine Bitzuweisung wo ich mit
>einer Maske mehrere Bits auswaehle und durch logische Kombinationen nur
>ein definiertes Bit dieser Maske, mit einer Funktion steuere.

Hm.. klingt nach einer Bitmaske für ein definiertes Bit. Die anderen 
scheinen ja uninteressant zu sein...

von Besserwisser (Gast)


Lesenswert?

@ daniel

Mir geht es da ähnlich wie Matthias.
Nach der Beschreibung klingt es so als wenn es Sinn macht. Aber ich kann 
irgendwie nicht ableiten welchen.

Ich meine soviel zu verstehen, das Du einen bestimmtes Ziel erreichen 
willst und Dir schon Gedanken gemacht hast wie Du es erreichen kannst.
Du scheinst einige Teilschritte gedanklich schon fertig konzipiert zu 
haben aber Dir fehlen noch einige andere Teilschritte.

Vielleicht können wir Dir helfen, wenn Du uns an einem konkreten 
Beispiel, vielleicht mit den Ports eines AVR, nochmal schilderst was Du 
erreichen willst.

Einstweilen:

>ich suche nach einer Moeglichkeit fuer eine Bitzuweisung
OK. Z.B. PortB = (1 << BitNummer)

>mit einer Maske mehrere Bits auswaehle
OK. Maske = 0x0F ; nur low nibble ausgewählt

>durch logische Kombinationen nur ein definiertes Bit dieser Maske
Da wird es ungewöhnlich. Kann aber noch Sinn machen.
Eben eine zweite Maske. Maske2 = 0x03 ; nur die untersten beiden Bits
Dann könnte man beide Masken miteinander verkknüpfen.
EffektiveMaske = Maske & Maske2

>Ich denke da an die Moeglichkeit das 2 Informationen in der Maske
>stecken. Die eine Information ist definiert und zwar das alle Bits eines
>Prozesses in der Maske nacheinander zu folgen haben.
Das verstehe ich wirklich nicht. Denn ob alle Bits nacheinander zu 
folgen haben oder nicht passt als Information eigentlich in ein einziges 
Bit.

>Die andere Information ist eben die, dass die selektierten Bits "1" und
>die Anzahl durch die Maske bekannt sind.
Ob oder ob nicht "selektierten Bits "1" und die Anzahl durch die Maske 
bekannt sind" ist genau wie das eben gesagt eine Ein-Bit-Information.

Du hast ja versucht ein Beispiel zu geben. Aber das hilft irgendwie 
nicht weiter.

>- 2 Funktionen nutzen 1 Byte
OK.
>- dieses Byte definiert Bits an einem Port
Was heisst hier definieren? (Das Wort wird manchmal nicht ganz richtig 
verwendet). Du meinst vielleicht das jedes Bit dieses Bytes mit einem 
Bit des Ports zugeordnet sein soll.
>- dieses Byte selbst stellt eine Bitmaske dar
Mmh. Und?
>- aus diesem Byte sollen die Informationen fuer die einzelnen Bits
>entschluesselt werden
Welche Information?

von Besserwisser (Gast)


Lesenswert?

Oder ist es so, das Du mehrere Bits eines Bytes miteinander verknüpfen 
willst um ein anderes Bit des selben Bytes zu berechnen?

von daniel (Gast)


Lesenswert?

Hi,
vielen Dank fuer die Antworten, freut mich das sich auch andere Gedanken 
darueber machen moechten.
Vielleicht ist das Beispiel von mir schon zu speziell gewaehlt ich werde 
etwas eher anfangen.

Man stelle sich zwei Funktionen vor die wiefolgt verknuepft sind.
Mal als beispiel:
Jedoch nicht richtig in der Zuweisung mit den Logischen Verknuepfungen! 
Danach suche ich ja :).

function main
{
  while (1)
  {
  qwer( 0x07);   // Prozess 1 nutzt im Port byte: 00000111b
  qwer( 0x38);   // Prozess 2 nutzt im Port byte: 00111000b
}
// Kommentare sind vom Aufruf des Prozess 2, Byte = Bit0...Bit7
function qwer ( unsigned int wMask)
{
   const unsigned int wMaskCom := 0000001;
   const unsigned int wValueCom := 0000001;
   const unsigned int wValueSet
   ...
   asdf ( wMask = (wMask AND wMaskCom)OR(wMaskCom MOD wMask), wValue = 
(wMask AND wValueCom) MOD wValueSet ; // Ziel 2.Bit der Bitmask also 
Bit4 soll gesetzt werden !
   ...
   asdf ( wMask = (wMask AND wMaskCom), wValue = (wMask & wValueCom)XOR 
wValueReset; // Ziel 2.Bit der Bitmask also Bit4 soll geloescht werden !
}

asdf ( usigned int wMask, unsigned int wValue)
{
   ....
   Funktion weisst dem gewaehlten Bit aus wMask Wert des selben Bits aus 
wValue zu
  Beispiel:
 wValue = 00100100b,
 wMask  = 00010000b -> Bit 4 wird geloescht
}

An der Funktion asdf kann nichts mehr geaendert werden.
In der Funktion qwer ist bekannt welches Bit IN BEZUG auf die 
uebergebene Bitmaske(2.Bit der aktuellen Bitmaske) benutzt und wie 
geaendert werden soll. Jedoch ist NICHT die Bitposition vorher bekannt. 
Diese wird erst indirekt beim Aufruf mit wMask uebergeben.
Wichtig ist die Zuweisung fuer asdf soll nur in einer Zeile erfolgen.

ist das verstaendlicher ?

vielen Dank
Daniel

von Besserwisser (Gast)


Lesenswert?

>ist das verstaendlicher ?
Nein.

>Vielleicht ist das Beispiel von mir schon zu speziell gewaehlt ich werde
>etwas eher anfangen.
Es ist nicht speziell sondern unklar beschrieben. Siehe meine 
Kommentare.

Nach
>  qwer( 0x07);   // Prozess 1 nutzt im Port byte: 00000111b
>  qwer( 0x38);   // Prozess 2 nutzt im Port byte: 00111000b
geht es darum das jeweils zwei Bereiche von Bits in einem Port benutzt 
werden sollen. Das ist ja ohne weitere Kopfstände möglich. Erkläre noch, 
was Du eigentlich erreichen willst.

>Byte = Bit0...Bit7
Die Reihenfolge ist widersprüchlich. In adsf ist der Kommentar so als 
wenn die Bitreihenfolge Bit7 ...Bit0 ist. Das wäre auch die gewöhnliche 
Reihenfolge mit dem LSB links.

Was ist das für eine Programmiersprache?

Wenn Du willst versuchen wir was anderes.
Mache eine Werte-Tabelle und fülle sie mit einigen Beispielen:

| qwer  |          |           |           | asdf  | asdf   |
| wMask | wMaskCom | wValueCom | wValueSet | wMask | wValue | Ergebnis |
+-------+----------+-----------+-----------+-------+--------+----------+
| 0x07  | ?        | ?         | ?         | ?     | ?      | ?        |
| 0x38  | 0x01     | 0x01      | ?         | ?     | ?      | 0x10     |

Erkläre die Bedeutung von wMask, wMaskCom, wValueCom, wValueSet, wMask 
und wValue.

Versuche das ganze mal von dem ganzen Funktionsgeraffel befreit an einem 
Beispiel zu erklären. Die Funktionen usw. sind ja erst das Ergebnis der 
Gedankengänge. Was ist das Ziel?

von Besserwisser (Gast)


Lesenswert?

Oder fangen wir es anders an:

Nimm mal an Du willst in zwei Fällen mal das Bit 0 und mal das Bit 7 
setzen. Wie sollen dann die Eingangsdaten lauten?

von tastendrücker (Gast)


Lesenswert?

hmmm, selten so eine undurchsichtige Beschreibung gesehen

> // Ziel 2.Bit der Bitmask also Bit4 soll gesetzt werden !

Nicht einmal dieser Kommentar ist mir ganz klar!?

von Besserwisser (Gast)


Lesenswert?

Ich habe mal wieder rinks und lechts verwechselt:
Statt "Reihenfolge mit dem LSB links."
muss es natürlich heissen
"Reihenfolge mit dem LSB rechts"

>> // Ziel 2.Bit der Bitmask also Bit4 soll gesetzt werden !

>Nicht einmal dieser Kommentar ist mir ganz klar!?

Naja. Irgendwie könnte man sich denken, das ja weil in 0x38, das 3., 4. 
und 5. Bit gesetzt sind, ist das 2. Bit der Bitmaske das 4. des Bytes.
Soweit schon recht, aber ich kann die 2 nirgendwo finden.

von daniel (Gast)


Lesenswert?

Hi,

>geht es darum das jeweils zwei Bereiche von Bits in einem Port benutzt
>werden sollen. Das ist ja ohne weitere Kopfstände möglich. Erkläre noch,
>was Du eigentlich erreichen willst.

ja das ist richtig erkannt. Zwei Bereiche von Bits in einem Port. Aber 
es ist nur bekannt, dass es diese Bereiche geben wird. Nicht an welcher 
Bitposition diese Bereiche jeweils beginnen.

> // Ziel 2.Bit der Bitmask also Bit4 soll gesetzt werden !
Ja, sehr ungluecklich formuliert. Es kommen die Eingangsdaten 00111000b 
und von diesen 111 soll das 2. Bit gesetzt werden -> 4.Bit aus der 
Eingangsdatenmaske

>Nimm mal an Du willst in zwei Fällen mal das Bit 0 und mal das Bit 7
>setzen. Wie sollen dann die Eingangsdaten lauten?
zwei Faelle, also 2 Prozesse die die function "qwer" nutzen moechten. 
und sie geben diese Eingangsdaten an:
Fall 1(Prozess1) 00001111b (0x0F)
Fall 2(Prozess2) 11100000b (0xE0)
beide rufen dann nacheinander die function qwer auf und uebergeben 
ihre Eingangsdaten. Also
qwer(0x0F) fuer fall 1
qwer(0xE0) fuer fall 2
von Fall 1 moechte ich nur das Bit 0 setzten durch die Funktion asdf, 
welche eine Maske und einen Wert verlangt.
also programmiere ich in der funktion /qwer(Maske fuer Bitbereich)/, 
welche die Funktion /asdf(Maske fuerBit am Port,Bitwert(0,1) fuer Bit 
aus Maske)/  aufruft:
asdf (neue Bitmaske nur fuer Bit0, Bitwert "1" fuer Bit0 uebergeben) 
beim Aufruf muss die Maske so verarbeitet werden, das sie Bit0 setzt, 
fuer den Fall 1 (bekannt ist aber nicht BIT0 ! sondern das 1. Bit des 
Bitbereiches in der Maske!)

BEIM zweiten Aufruf fuer Fall 2 soll jedoch der Aufruf von asdf 
(...,...) das Bit 7 setzen also:
asdf (neue Bitmaske nur fuer Bit7, Bitwert "1" fuer Bit7 uebergeben)
(bekannt ist aber nicht BIT7 ! sondern das 3. Bit des Bitbereiches in 
der Maske!)

>Byte = Bit0...Bit7
sorry das ist falsch?! (schreibe extra diesen hinweis und dann falsch?!
#DEFINE ja das LSB ist recht und entspricht Bit0, dem 0.ten bit !

>Was ist das für eine Programmiersprache?
Am Ende soll es STRUCTURED TEXT fuer eine SPS sein.
Jetzt wollte ich es jedoch zum Verstaendnis ohne Bezug auf eine Syntax 
einer Programmiersprache schreiben. Ist aber anscheind voellig 
fehlgeschlagen.

>Tabelle
Zur Tabelle: ich transformiere sie mal ;)
              Aufruf 1    | Aufruf 2  |
qwer wMask   | 0x07       |  0x38     |
asdf wMask   |  ?         |  ?        |
asdf wValue  |  ?         |   ?       |
Ergebnis     |2.Bit im    |2.Bit im   |
             |Bitbereich  |Bitbereich |
             |setzen,Bit1 |setzen,Bit4|

Beim Ergebnis ist es ja in beiden Aufrufen ein anderes Bit. Aufruf 1 ist 
Bit 1 zu setzen. Aufruf 2 ist Bit 4 zu setzen! Zum Programmierzeitpunkt 
der Funktion asdf sind wMask von qwer NICHT bekannt.

Meine Schlussfolgerung:
Ich denke es geht nicht mit einer logischen Verknuepfung, auch wenn es 
mehrere sind und geklammert wird. Es muss eine Schleife programmiert 
werden die die Bitbereiche extrahiert. Das geht in der 
Programmiersprache ST jedoch nicht in einer Zeile.

Meine Andere Loesung ist eben fuer jedes Bit eine Maske beim Aufruf zu 
uebergeben. Also:
qwer (Mask_1tesBit, Mask_2tesBit, Mask3_tesBit);
...

Vielen Dank,
Sorry fuer meine schlechte Formulierung, aber ich denke ich lern dazu 
;).
daniel

von Besserwisser (Gast)


Lesenswert?

>>geht es darum das jeweils zwei Bereiche von Bits in einem Port benutzt
>>werden sollen. Das ist ja ohne weitere Kopfstände möglich. Erkläre noch,
>>was Du eigentlich erreichen willst.

>ja das ist richtig erkannt. Zwei Bereiche von Bits in einem Port. Aber
>es ist nur bekannt, dass es diese Bereiche geben wird. Nicht an welcher
>Bitposition diese Bereiche jeweils beginnen.

Na gut. Das ist nach wie vor möglich. Wenn es darauf hinausläuft, was 
ich zu ahnen meine, dann drückst Du Dich nur einfach nur wahnsinnig 
umständlich aus. (Tut mir leid wenn das hart für Dich ist).

Es wäre einfacher, wenn Du Dich auf den Algorithmus konzentrierst.
Ich versuche das mal hier um es Dir vorzuführen:

Du willst eine Funktion (das es nachher zwei sind, spielt jetzt erstmal 
keine Rolle).
Sie hat drei Eingangsparameter:
1. Eine Bitmaske die angibt welche Bits grundsätzlich geändert werden 
dürfen .
2. Eine Bitmaske die angibt welche Bits jetzt gerade geändert werden 
sollen. Sie bezieht sich auf die Bits in Parameter 1 (In welcher Weise 
sie interpretiert werden müssen, muss noch festgelegt werden).
3. Ein Wert dessen Bits entsprechend (einer noch zu findenden) 
Verknüpfung von Parameter 1 und 2 in dem Ergebnis gesetzt sein sollen.
Sie hat folgendes Ergebnis:
1. Ein Wert in dem diejenigen Bits entsprechend Parameter 3 gesetzt bzw. 
gelöscht sind, die mit der Bitmaske 1 und der Bitmaske 2 korrespondieren 
(im erstmal weiteren Sinne).

Erstes Beispiel: (Deinem hoffentlich folgend)

1. Bitmaske 0x0F
2. Bitmaske 0x01
3. Wert 0x01           (0. Bit soll 1 sein)
Ergebnis: 0x01

Das Ergebnis muss so nicht stimmen. Denn Du hast noch nicht erklärt was 
mit den Bits passieren soll, die nicht durch die erste und zweite Maske 
erfasst sind. Sollen sie so bleiben wie sie sind? Das nehme ich an.
Deswegen sollte das Ergebnis vielleicht so beschrieben werden:
X sind Bits die so stehen bleiben wie sie vorher waren.
Also ist das Ergebnis (ich wandle erstmal 0x02 in 00000010 um) XXXXXX10.
Ist das so richtig?

Zweites Beispiel. (2. Bit der Bitmaske, also Bit 4 soll gesetzt werden)
1. Bitmaske 0xE0 (11110000)
2. Bitmaske 0x04 (00001000)
3. Wert 0x01     (00000001)

Lies erst noch weiter, bitte.
Jetzt ordne ich mal die nachfolgenden Teile Deiner letzten Antwort der 
Parameterbeschreibung und den Beispielen zu:

>>Nimm mal an Du willst in zwei Fällen mal das Bit 0 und mal das Bit 7
>>setzen. Wie sollen dann die Eingangsdaten lauten?
>zwei Faelle, also 2 Prozesse die die function "qwer" nutzen moechten.
>und sie geben diese Eingangsdaten an:
>Fall 1(Prozess1) 00001111b (0x0F)
Das wäre dann also der 1. Parameter in meinem Beispiel 1.
>Fall 2(Prozess2) 11100000b (0xE0)
Das wäre dann also der 1. Parameter in meinem Beispiel 2.

>beide rufen dann nacheinander die function qwer auf und uebergeben
>ihre Eingangsdaten. Also
>qwer(0x0F) fuer fall 1
>qwer(0xE0) fuer fall 2
Das können wir erstmal aussen vor lassen, denke ich. Ob da was in 
welcher Reihenfolge aufgerufen wird ist egal.

>von Fall 1 moechte ich nur das Bit 0 setzten...
Das ist dann der Parameter 2. in Beispiel 1. Und das seten geht aus Wert 
hervor, indem das 0 Bit gesetzt ist. OK?

> durch die Funktion asdf, welche eine Maske und einen Wert verlangt.
OK. Wie die Funktione asdf am Ende aussieht muss man später sehen.
Lass das erstmal aussen vor, damit wir erstmal die Aufgabe verstehen.


>BEIM zweiten Aufruf fuer Fall 2 soll jedoch der Aufruf von asdf
>(...,...) das Bit 7 setzen also:
Das ist eigentlich ein drittes Beispiel:
Drittes Beispiel. (3. Bit der Bitmaske, also Bit 7 soll gesetzt werden)
1. Bitmaske 0xE0 (11110000)
2. Bitmaske 0x04 (00001000)
3. Wert 0x01     (00000001)

>Byte = Bit0...Bit7
>sorry das ist falsch?! (schreibe extra diesen hinweis und dann falsch?!
#>DEFINE ja das LSB ist recht und entspricht Bit0, dem 0.ten bit !
Naja. Das ist so eine Konvention. Das Problem war nur das Du es mal so 
und mal so in Deinem Text vorausgesetzt hast. Üblich ist aber LSB 
rechts.

>Was ist das für eine Programmiersprache?
>Am Ende soll es STRUCTURED TEXT fuer eine SPS sein.
>Jetzt wollte ich es jedoch zum Verstaendnis ohne Bezug auf eine Syntax
>einer Programmiersprache schreiben. Ist aber anscheind voellig
>fehlgeschlagen.
Das geht im Prinip schon. Aber das Problem ist, das man dann Gefahr 
läuft einen Algorithmus zu formulieren, der Operationen enthält, die 
entweder garnicht in der gewählten Sprache enthalten sind, oder durch 
andere Operationen emuliert (nachgebildet) werden müssen. Aber dieser 
Gefahr kann man, gerade bei etwas komplexeren Sachen nicht ausweichen.
Wenn man aber mal wenigstens einen Algorithmus gefunden hat, dann ist 
der zweite Schritt meist nicht mehr so schlimm, da Abwandlungen davon 
viel einfacher zu finden sind.

>Zur Tabelle: ich transformiere sie mal ;)
>              Aufruf 1    | Aufruf 2  |
>qwer wMask   | 0x07       |  0x38     |
>asdf wMask   |  ?         |  ?        |
>asdf wValue  |  ?         |   ?       |
>Ergebnis     |2.Bit im    |2.Bit im   |
>             |Bitbereich  |Bitbereich |
>             |setzen,Bit1 |setzen,Bit4|

Das Ergebnis müsstest Du ja eigentlich eintragen können.

>Beim Ergebnis ist es ja in beiden Aufrufen ein anderes Bit. Aufruf 1 ist
>Bit 1 zu setzen. Aufruf 2 ist Bit 4 zu setzen! Zum Programmierzeitpunkt
>der Funktion asdf sind wMask von qwer NICHT bekannt.
Das ist kein Problem, denke ich.

>Meine Schlussfolgerung:
Woraus eigentlich? Warum wirfst Du die Flinte schon in's Korn. Wir haben 
ja noch nicht mal die Aufgabe richtig formuliert.

>Ich denke es geht nicht mit einer logischen Verknuepfung, auch wenn es
>mehrere sind und geklammert wird. Es muss eine Schleife programmiert
>werden die die Bitbereiche extrahiert. Das geht in der
>Programmiersprache ST jedoch nicht in einer Zeile.
Bezüglich einer Schleife würde ich das so nicht sagen. Im Moment hängt 
das davon ab, ob die Bitbereiche zusammenhängend sind oder nicht.
Also ob es etwa vorkommen kann, das die erste Maske etwa 01010000b sein 
kann oder nicht.

Kann die Sprache eigentlich Schiebeoperationen? Gibt es ein Carry-Bit? 
Gibt es Logarithmen? Ich habe keine Ahnung von "Structured Language". 
Habe, wenn, dann AWLs oder KOPs oder FUPs beschrieben.

Auf jeden Fall gebe ich Dir recht, das das nicht in einer Zeile gehen 
wird.
Zumindest wenn man noch verstehen soll, was da abgeht.

Also, willst Du noch weiter machen oder nicht?

von Besserwisser (Gast)


Lesenswert?

Jetzt habe ich beim zweiten und dritten Beispiel das Ergebnis vergessen.

Irgendwie ist das zweite Beispiel auch fehlgegangen.
Na guck mal und korrigiere das.

von daniel (Gast)


Lesenswert?

Hi, natuerlich kann man weitermachen.
Aber mir ist noch eine neue Loesung hierfuer eingefallen bzw was 
einfacheres. Durch eine Function (in ST) kann dies entsprechend 
durchgefuehrt werden. Somit wird ist der Aufruf nur eine Zeile und durch 
die Function wird nur eine generierte Maske und das zu setzende Bit 
uebergeben.

ich denke mein Verstand ist in einer while(1) gefangen ?!

Beispiel 2 ist falsch. Es darf nicht moeglich sein das Bit 4 bei einer 
BitMaske von 0xE0 zu setzen, denn diese Maske deklariert nur den Bereich 
von Bit5 bis Bit7.
Beispiel:
Fall 1: wMask = 0x07 -> nur bit0,1,2 duerfen 
veraendert(gesetzt/geloescht) werden
Fall 2: wMask = 0xE0 -> nur Bit5,6,7 duerfen veraendert werden


Ja ich kann die Ergebnisse in die Tabelle einfuegen:

Ergebnis     |2.Bit im    |2.Bit im   |
             |Bitbereich  |Bitbereich |
             |setzen,Bit1 |setzen,Bit4|
             |   0x02     |  0x10     |

>3. Wert 0x01           (0. Bit soll 1 sein)
>Ergebnis: 0x01
>Also ist das Ergebnis (ich wandle erstmal 0x02 in 00000010 um) XXXXXX10.
>Ist das so richtig?
Nein das ist falsch. Wenn das Ergebnis 0x01 ist muss es so aussehen 
XXXXXXX1.


So kann die Loesung aussehen: (schreibe mal in C)
Beispiel fuer Setzen des 4.Bits des Bereiches aus der MainMask
1
int main
2
{
3
   qwer(0xF0);  // verwendbarer Bereich ist Bit4 bis Bit 7 des Bytes
4
};
5
6
qwer (unsigned int MainMask)
7
{
8
...
9
asdf (ReMask(MainMask,0x08),(ReMask(MainMask,0x08)&0xFF));  // MainMask = 0xF0, Bit4(0x08) des Bitbereiches soll gesetzt (0xFF) werden -> Bit7 wird gesetzt am Port
10
...
11
};
12
13
unsigned int ReMask(unsigned int MainMask, unsigned int BitMask)
14
{
15
   while (!(MainMask & 0x01));    // stop bei ersten 1)
16
   {
17
     MainMask = MainMask >> 1;  // schiebe 1mal rechts bis zur ersten 1 im Byte 
18
     BitMask = BitMask << 1;    // schiebe 1mal links, ich denke mal es wird mit 0-len aufgefuellt beim schieben, ODER? 
19
   }
20
   return BitMask;
21
};
22
// diesen Code hat kein Compiler geprueft, sicher gibts hier Syntax- Fehler ;)

so muss es funktionieren. Ohne die Funktion ReMask, wuerde der 
funktionsaufruf asdf so einfach aussehen. Man kann es nicht so 
zuweisen, weil eine Schleife benoetigt wird. Nur mittels einer Funktion.

Vielleicht versteht man jetzt was ich wollte.

vielen dank
daniel

von daniel (Gast)


Lesenswert?

hi,

formuliere nochmal mein letzte Bemerkung um:
So kann es funktionieren. Ohne die Funktion ReMask, wuerde der
funktionsaufruf asdf NICHT so einfach aussehen.
Man kann es "nicht" in einer Zeile zuweisen beim Aufruf der Funktion 
asdf, weil eine Schleife benoetigt wird. Nur mittels einer Funktion 
laesst sich dann der Funktionsaufruf asdf so einfach gestalten.

PS: ja!, man kann in C alles in einer Zeile schreiben. Sieht aber 
!@#%!#^ aus und ist somit keine akzeptable Loesung.

daniel

von Besserwisser (Gast)


Lesenswert?

>Aber mir ist noch eine neue Loesung hierfuer
Eine Lösung wofür? Es gibt ja garkeine Beschreibung dessen was Du 
willst.

Es macht keinen Sinn mitten in dem Versuch eine Funktion zu beschreiben, 
schon Lösungen zu bewerten. Nimmt man nun die Funktion als Vorlage um 
den beabsichtigten Effekt zu erkennen oder die Beschreibung des Effekts 
um die Funktion zu schreiben? Für eines musst Du Dich entscheiden.

Und wie ich schon sagte, lassen wir erstmal Deine Funktionen ausser acht 
und versuchen das Ziel und den Weg dahin zu beschreiben.

Zweites Beispiel. (2. Bit der Bitmaske, also Bit 4 soll gesetzt werden)
1. Bitmaske 0xE0 (11110000)
2. Bitmaske 0x04 (00010000)
3. Wert 0x01     (00000001)

Ausserdem hast Du meine Frage

"Im Moment hängt das davon ab, ob die Bitbereiche zusammenhängend sind 
oder nicht. Also ob es etwa vorkommen kann, das die erste oder zweite 
Maske etwa 01010000b sein kann oder nicht."

nicht beantwortet.

von Besserwisser (Gast)


Lesenswert?

>>3. Wert 0x01           (0. Bit soll 1 sein)
>>Ergebnis: 0x01
>>Also ist das Ergebnis (ich wandle erstmal 0x02 in 00000010 um) XXXXXX10.
>>Ist das so richtig?
>Nein das ist falsch. Wenn das Ergebnis 0x01 ist muss es so aussehen
>XXXXXXX1.

Ist klar.

Warum erwähnst Du eigentlich immer ob es in eine Zeile passt?
Spielt das eine Rolle? Wenn ja, welche.

Also: Hast Du Deine Lösung oder willst Du weitermachen?

von daniel (Gast)


Lesenswert?

Hi,


>"Im Moment hängt das davon ab, ob die Bitbereiche zusammenhängend sind
>oder nicht. Also ob es etwa vorkommen kann, das die erste oder zweite
>Maske etwa 01010000b sein kann oder nicht."
ja, es ist entscheident, dass die Bits einer Maske nacheinander folgen 
muessen. Damit wird der "Bitbereich" im Byte definiert.

>Warum erwähnst Du eigentlich immer ob es in eine Zeile passt?
>Spielt das eine Rolle? Wenn ja, welche.
ja, denn es wird jede Zeile gezaehlt. Und dadurch in der Visualisation 
somit die Zeilennummer der Funktion angegeben. Ist nun eine Funktion 
ueber 2 Zeilen, dann stimmen die Angaben der Visualisierung nicht mehr 
mit den realen Zeilennummern ueberein.

>Also: Hast Du Deine Lösung oder willst Du weitermachen?
Ich denke ich habe eine Loesung diesen Code den ich hier gepostet habe. 
Sozusagen eine Realisierung welche mit Hilfe einer Funktion 
durchgefuehrt wird.
Um diese Bitbereiche in der Bitmaske wo sie definiert sind zu erkennen, 
wird unbedingt eine Schleife benoetigt. Somit ist es nicht moeglich, 
diese nur mit logischen Operationen(auch Shift-Operatoren) zu erfuellen.

>Es gibt ja garkeine Beschreibung dessen was Du willst.
Ich versuche mal eine bessere Beschreibung fuer mein Ziel zu definieren.
Die 3 Eingangsvariablen:
Variable /Hauptmaske/: definiert einen Bitbereich (aufeinanderfolgende 
Bits in einem Byte), wird jeweils vom Anwender definiert
Variable /BitSelection/: definiert welches Bit in dem Bitbereich 
ausgewaehlt werden soll, NUR dieses darf beeinflusst werden
Variable /Wert/: definiert binaere Information fuer das selektierte Bit 
im Bitbereich

Ich suche nach einer logischen Kombination von diesen Variablen um mein 
Wert dem selektierten Bit aus dem Bitbereich zuzuweisen. Aber es geht 
eben nicht, dass man nur mit einer logischen Kombination diese Ziel 
erreicht. Man benoetigt eine Schleife, da man Schiebeoperationen 
anwenden muss.

>Also: Hast Du Deine Lösung oder willst Du weitermachen?
Ich denke wir lassen es. Ich habe nun das Problem beschrieben und die 
Funktion bietet darauf, eine Loesung.

Ich danke dir fuer deine Hinweisse, ich hoffe ich kann beim naechsten 
mal meine Beschreibung eindeutig formulieren.
Ich danke dir fuer deine Muehe.
daniel

von Besserwisser (Gast)


Lesenswert?

>Ich denke wir lassen es.

OK. Dann viel Erfolg.

von Arc N. (arc)


Lesenswert?

daniel wrote:
> hi,
>
> formuliere nochmal mein letzte Bemerkung um:
> So kann es funktionieren. Ohne die Funktion ReMask, wuerde der
> funktionsaufruf asdf NICHT so einfach aussehen.
> Man kann es "nicht" in einer Zeile zuweisen beim Aufruf der Funktion
> asdf, weil eine Schleife benoetigt wird. Nur mittels einer Funktion
> laesst sich dann der Funktionsaufruf asdf so einfach gestalten.
>
> PS: ja!, man kann in C alles in einer Zeile schreiben. Sieht aber
> !@#%!#^ aus und ist somit keine akzeptable Loesung.
>
> daniel

Schleifen braucht man nicht...
Stichwörter sind: De Bruijn Sequence und/oder Parallel/Population/Ones 
Count

1
byte ones(byte v) {
2
  v = ((v >> 1) & 0x55) + (v & 0x55);
3
  v = ((v >> 2) & 0x33) + (v & 0x33);
4
  v = ((v >> 4) + v) & 0x0f;
5
  return v;    
6
}
7
8
byte trailingZeros(byte v) {
9
   return ones((v & -v) - 1);
10
}
11
12
// cut, copy, paste 
13
byte tz1(byte t) {
14
  return ((((((((((t & -t) - 1) >> 1) & 0x55) + (((t & -t) - 1) & 0x55)) >> 2) & 0x33) + ((((((t & -t) - 1) >> 1) & 0x55) + (((t & -t) - 1) & 0x55)) & 0x33)) >> 4) + ((((((((t & -t) - 1) >> 1) & 0x55) + (((t & -t) - 1) & 0x55)) >> 2) & 0x33) + ((((((t & -t) - 1) >> 1) & 0x55) + (((t & -t) - 1) & 0x55)) & 0x33))) & 0x0f;
15
}
16
17
byte tzDB(byte v) {
18
    unsigned char db[] = { 0, 1, 6, 2, 7, 5, 4, 3 };
19
    v &= -v;
20
    v *= 0x1d;
21
    v >>= 5;
22
    return db[v];
23
}

von Wissbegieriger (Gast)


Lesenswert?

@ Arc Net

>De Bruijn Sequence

die finde ich bei Google, aber

>Parallel/Population/Ones Count

nicht.
Kannst Du mir noch einen Hinweis geben?

von Arc N. (arc)


Lesenswert?


von Wissbegieriger (Gast)


Lesenswert?

@ Arc Net

Domo arigatou gosaimasu.

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
Noch kein Account? Hier anmelden.