C Programmierung: Digitale EIngänge mit Bitmaske

Hallo!

ich habe folgendes Problem zu lösen.
Ein C Programm läuft auf eine Board mit digitalen Eingängen (inputs) und Ausgängen. Ich muss die Eingänge beobachten.
Es gibt eine Reihe von 8 digitalen inputs, die auf 0 oder auf 1 sind. Pro Input habe ich ein bit:

char input_zustand:

0000 0000: alle input auf 0

1111 1111: alle inputs auf 1

0001 0001: erster und vierter Eingang sind auf 1.

Ich muss ein Programm laufen lassen, aber nur, wenn ein bestimmter Zustand der inputs gegeben ist. Welcher Zustand das ist, wird vom Benutzer in einer Maske festgelegt.

und zwar könnte er zu Beispiel eine 1 eingeben, wenn der Zustand 1 sein muss
Eine 0, wenn der Zustand 0 sein muss. und eine 2, wenn der Zustand egal ist.

Allerdings komme ich mit dieser lösung dann nicht mehr mit einer bitmaske aus, weil ich nicht mehr 0 oder 1 habe. ich muss wohl ein array[8] nehmen.

Ich hätte gern soetwas gehabt:

if (input_zustand) & (input_maske)
programm_laufen_lassen();
else
meldung_voraussetzungen nicht erfüllt();

Aber mit einer Maske aus 0,1 udn 2 geht es natürlich nicht.
Ich kann natürlich in einer Schleife prüfen lassen, ob input_maske[x] und (input_zustand&2^x) übereinstimmen, aber vielleicht geht es eine elegantere Lösung?
Hat jemand eine Idee, wie man es am schlauesten machen könnte?

Vielen Dank im Voraus, falls jemand eine Idee hat,

frenchcancan

Hi frenchcancan.

Ich würde das über eine dritte Bitmaske lösen, in der die Bits
der Eingänge deren Zustand dir egal ist 1 sind. Also wenn
Eingang 0 und 3 dir egal sind, dann hätte diese Maske den
Wert 0x09.
diese Maske dann mit

 input\_zustand 

und

input\_maske

im if verodern.

also:

if ((input\_zustand | egal\_mask) == (input\_maske | egal\_mask))

Ohne das jetzt getestet zu haben, sollte das eigentlich
funktionieren.

Gruß
re-G

danke schön
Ja, das ist eine super idee! Danke!
so werde ich das lösen!
schönes Wochenende

frenchcancan

Hossa :smile:

Du brauchst eine Bitmaske „ein“, die angibt, welche Bits gesetzt sein müssen. Du brauchst eine Bitmaske „aus“, die angibt, welche Bits nicht gesetzt sein dürfen. Eine Bitmaske „egal“, die angibt, welche Bits egal sind, brauchst du nicht, die ergibt sich ja aus „ein“ und „aus“:

egal = ~0 ^ ein ^ aus

Beispiel:
ein = 11000000 (Bits 6 und 7 müssen gesetzt sein)
aus = 00001010 (Bits 1 und 3 dürfen nicht gesetzt sein)
egal= 11111111 ^ 11000000 ^ 00001010 = 00110101

Musst du nun ein Bitmuster „test“ prüfen, blendest du zunächst alle Bits ohne Belang aus, indem du sie auf 0 setzt:

test & ~egal

Damit deine Startbediungung nun zutrifft, müssen alle Bits in „aus“ auf 0 sein und alle Bits aus „ein“ auf 1. Mit anderen Worten, obiger Ausdruck muss gleich „ein“ sein. Also lautet deine Prüfbedingung:

if ((test & ~egal)==ein) { … }

Beachte bitte die Klammerung, Vergleichsoperatoren haben höheren Vorrang als binäre Verknüpfungen…

Viele Grüße

Oops, da war re-G schneller :smile:
Sorry, habe nicht gesehen, dass hier schon eine Lösung steht, die funktioniert…

ach ja noch besser, danke!
vielen Dank an beide, das ging so schnell und ist viel besser als ein array.
ich setze es nach dem Wochenende um.
Vielen Dank!
frenchcancan

Nioch eine Variante
Hallo frenchcancan

char mask = 0x3F; // gesetzte Bits werden ausgewertet
char code = 0x12; // Zustand welcher auslöst

if ( !((input\_zustand ^ code) & mask) )
 // mach was
else
 // nix zu tun

MfG Peter(TOO)

Nachfrage zu XOR
Und wenn ich egal = 1111 1111 ^ 1100 0000 ^00001010
nach deinem Beispiel mache, wie mache ich das XOR.

Mache ich es so: (1111 1111 ^ 1100 0000) ^0000 1010 ?

(1111 1111
1100 0000)
0000 1010

0000 0101

Danke für die Hilfe
frenchcancan

Hossa :smile:

Die Reihenfolge von XOR ist egal, es ist assoziativ. Das heißt:

( a ^ b ) ^ c = a ^ ( b ^ c )

Viele Grüße