Forum: Mikrocontroller und Digitale Elektronik Bits Prüfen ohne for-Schleife


von Stefan (Gast)


Lesenswert?

im Tutorial zu Bitmanipulation
http://www.mikrocontroller.net/articles/Bitmanipulation
insbesondere Bits prüfen, kann mit dem Ausdruck
if(~tmp & 0x11)
geprüft werden, ob mind. 1 gelöscht ist.
Gibt es auch eine Möglichkeit raus zu bekommen, ob mind. 2 oder 3 oder 
auf ein Port gesehen mind. 7 Bits gelöscht sind?
MfG
Stefan

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

sicher:

 if tmp < 255

von Klaus W. (mfgkw)


Lesenswert?

ja, z.B. mit einer Tabelle, in die man mit dem Portwert als Index 
reingeht und als Ergebnis ja oder nein bekommt.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Es ist egal welches Bit gelöscht ist, da der Wert "255" bedeutet das 
alle 8 Bits eines Bytes gesetzt sind.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

@klaus,

 dann braucht man aber nicht erst ja oder nein auswerten sondern kann 
die Tabelle gleich als Sprungverteiler (oder interupttabelle) verwenden.

Das ist aber zwei schritte weiter. ;-)

von Klaus W. (mfgkw)


Lesenswert?

je nachdem, was er vorhat...

Das geht aus der Frage ja nicht so recht hervor (wie meistens), und ich 
habe nur bedingt Lust immer zu spekulieren.

Außerdem kann man das mit deinem Ausdruck i<255 ja auch machen :-)

von (prx) A. K. (prx)


Lesenswert?

Mindestens 7 Bits gelöscht = maximal 1 Bit gesetzt:
  if ((val & (val - 1)) == 0)

von Stefan (Gast)


Lesenswert?

hey Leute,

was ich vorhabe ist recht simple, ich will an einem beliebigen port nur 
überprüfen, ob bei den ersten 5 Pins nur 1 Signal anliegt und wenn mehr 
als 1 signal mein if()-Abfrage das erkennt und auf printf ausgibt 
Fehler.

von Klaus W. (mfgkw)


Lesenswert?

Was ich meinte, könnte man etwa so schreiben:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <stdint.h>
4
5
inline uint8_t anzahlBits5( uint8_t n )
6
{
7
  static uint8_t nBits[] =
8
    {
9
      0,  //   0b00000
10
      1,  //   0b00001
11
      1,  //   0b00010
12
      2,  //   0b00011
13
      1,  //   0b00100
14
      2,  //   0b00101
15
      2,  //   0b00110
16
      3,  //   0b00111
17
      1,  //   0b01000
18
      2,  //   0b01001
19
      2,  //   0b01010
20
      3,  //   0b01011
21
      2,  //   0b01100
22
      3,  //   0b01101
23
      3,  //   0b01110
24
      4,  //   0b01111
25
      1,  //   0b10000
26
      2,  //   0b10001
27
      2,  //   0b10010
28
      3,  //   0b10011
29
      2,  //   0b10100
30
      3,  //   0b10101
31
      3,  //   0b10110
32
      4,  //   0b10111
33
      2,  //   0b11000
34
      3,  //   0b11001
35
      3,  //   0b11010
36
      4,  //   0b11011
37
      3,  //   0b11100
38
      4,  //   0b11101
39
      4,  //   0b11110
40
      5,  //   0b11111
41
    };
42
43
  return nBits[n&0b11111];
44
}
45
46
int main()
47
{
48
  uint8_t i;
49
  for( i=0; i<32; ++i )
50
  {
51
    printf( "%2u hat %2u Bits\n", (unsigned)i, (unsigned)anzahlBits5(i) );
52
  }
53
54
  return 0;
55
}

von Klaus W. (mfgkw)


Lesenswert?

ok, hat natürlich auch eine for-Schleife drin :-)

von Klaus W. (mfgkw)


Lesenswert?

Eine andere Möglichkeit, wäre passende logische Ausdrücke zu bauen.
1
inline uint8_t anzahlBits5( uint8_t n )
2
{
3
  return ( n&0b00001 != 0 ) + ( n&0b00010 != 0 ) + ( n&0b00100 != 0 ) + ( n&0b01000 != 0 ) + ( n&0b10000 != 0 );
4
}

von Stefan (Gast)


Lesenswert?

:-)
das wollt ich so vermeiden, weil es geht mit der for-schleife oder so 
einen umständlichen ausdruck wie (bisschen abgewandelt)
if( (a==b) || (b==c) || (a==d) || etc.
und das für 5 pins durchgespielt ist hölle

von Klaus W. (mfgkw)


Lesenswert?

Stefan schrieb:
> hey Leute,
>
> was ich vorhabe ist recht simple, ich will an einem beliebigen port nur
> überprüfen, ob bei den ersten 5 Pins nur 1 Signal anliegt und wenn mehr
> als 1 signal mein if()-Abfrage das erkennt und auf printf ausgibt
> Fehler.

Stefan schrieb:
> das wollt ich so vermeiden, weil es geht mit der for-schleife oder so
> einen umständlichen ausdruck wie (bisschen abgewandelt)
> if( (a==b) || (b==c) || (a==d) || etc.
> und das für 5 pins durchgespielt ist hölle

ich sehe da jetzt keinen Zusammenhang, aber solange du ihn siehst, ist 
es gut :-)

von Stefan (Gast)


Lesenswert?

ein freund sagt, ich muss jeden pin untereinander prüfen und die 
untereinander prüfen. ich glaub du hast recht, der letzt post klappt 
nicht so wie ich das gedacht hab.

von Stefan (Gast)


Lesenswert?

ich versuchs mal zu verstehen :-). danke für schnelle hilfe

von Stefan (Gast)


Lesenswert?

Stefan schrieb:
> :-)
> das wollt ich so vermeiden, weil es geht mit der for-schleife oder so
> einen umständlichen ausdruck wie (bisschen abgewandelt)
> if( (a==b) || (b==c) || (a==d) || etc.
> und das für 5 pins durchgespielt ist hölle

aja, so ist das gemeint. wenn angenommen port a, dann soll sein:
if( (pa0==pa1) || (pa0==pa1) etc

also gucken, ob bei 2 pin gleichzeitig liegen signal vor

von Thomas E. (thomase)


Lesenswert?

Stefan schrieb:
> was ich vorhabe ist recht simple, ich will an einem beliebigen port nur
> überprüfen, ob bei den ersten 5 Pins nur 1 Signal anliegt und wenn mehr
> als 1 signal mein if()-Abfrage das erkennt und auf printf ausgibt
> Fehler.
Dann fragst du in einer Schleife die Bits nacheinander ab. Wenn es 1 
ist, zählst du einen Zähler hoch. Und wenn der am Ende >1 ist, ist die 
Fehlerbedingung erfüllt.

unsigned char nCt = 0;
unsigned char nTmp = PINC;

for (unsigned char nInd = 0; nInd < 5; nInd++)
{
  if((nTmp & (1 << nInd))) nCt++;
}
if (nCt > 1) printf("...");

> und das für 5 pins durchgespielt ist hölle
Deswegen in einer Schleife.

mfg.

von switch (Gast)


Lesenswert?

1
switch (PORTxy){
2
  case 0x01:
3
  case 0x02:
4
  case 0x04:
5
  case 0x08:
6
  case 0x10:
7
  case 0x20:
8
  case 0x40:
9
  case 0x80:
10
    printf ("Ok!");
11
  break;
12
  default
13
    printf ("Ko!");
14
}

von Stefan (Gast)


Lesenswert?

Thomas Eckmann schrieb:

> Dann fragst du in einer Schleife die Bits nacheinander ab. Wenn es 1
> ist, zählst du einen Zähler hoch. Und wenn der am Ende >1 ist, ist die
> Fehlerbedingung erfüllt.
>
> unsigned char nCt = 0;
> unsigned char nTmp = PINC;
>
> for (unsigned char nInd = 0; nInd < 5; nInd++)
> {
>   if((nTmp & (1 << nInd))) nCt++;
> }
> if (nCt > 1) printf("...");
>
>> und das für 5 pins durchgespielt ist hölle
> Deswegen in einer Schleife.
>
> mfg.

ich wollten eigentlich ohne for-schleife (topic :-))

von (prx) A. K. (prx)


Lesenswert?

Liebe Güte macht ihr das kompliziert... Nu ist schon fast alles da, 
Tabelle, Schleife, Switch-Statement. Fehlt eigentlich nur noch jemand, 
der es auf den Logarithmus zurückführt. ;-)

von Stefan (Gast)


Lesenswert?

A. K. schrieb:
> Liebe Güte macht ihr das kompliziert... Nu ist schon fast alles da,
> Tabelle, Schleife, Switch-Statement. Fehlt eigentlich nur noch jemand,
> der es auf den Logarithmus zurückführt. ;-)

haha, du weißt:
wer sagen a muss auch sagen b

von Thomas E. (thomase)


Lesenswert?

Stefan schrieb:
> ich wollten eigentlich ohne for-schleife (topic :-))
Code schreibt man effektiv und übersichtlich.
Die switch-Variante ist, wenn sie fehlerfrei wäre, aber auch OK

mfg.

von (prx) A. K. (prx)


Lesenswert?

Stefan schrieb:

> haha, du weißt:
> wer sagen a muss auch sagen b

Das hatte ich bereits. Das war aber so kurz und offenbar viel zu 
einfach, dass es niemand zur Kenntnis nahm.

von Stefan E. (sternst)


Lesenswert?

Ich hätte da auch noch einen:
1
if ((tmp & (tmp-1)) == 0) {
2
  // in tmp ist maximal ein Bit gesetzt
3
4
if ((tmp > 0) && ((tmp & (tmp-1)) == 0)) {
5
  // in tmp ist genau ein Bit gesetzt

von (prx) A. K. (prx)


Lesenswert?

Stefan Ernst schrieb:

> Ich hätte da auch noch einen:

Siehe oben.

von Stefan E. (sternst)


Lesenswert?

A. K. schrieb:
> Stefan Ernst schrieb:
>
>> Ich hätte da auch noch einen:
>
> Siehe oben.

Ups, sorry. ;-)

von Klaus W. (mfgkw)


Lesenswert?

A. K. schrieb:
> Das hatte ich bereits. Das war aber so kurz und offenbar viel zu
> einfach, dass es niemand zur Kenntnis nahm.

doch, doch - nur war mir lange Zeit nicht klar, ob es wirklich um 7 bzw. 
1 Bit geht, oder andere Kombinationen.
Genau genommen, weiß ich immer noch nicht genau, was wirklich gefragt 
ist.

von (prx) A. K. (prx)


Lesenswert?

Klaus Wachtler schrieb:

> Genau genommen, weiß ich immer noch nicht genau, was wirklich gefragt
> ist.

Die erste Formulierung fragte u.A. nach 7 Bits. Unter der Annahme, dass 
ein Byte gemeint war, lief das auf die "maximal 1 Bit gesetzt" Situation 
raus.

Später konkretisierte er es etwas. Etwas verallgemeinert bedeutet es, ob 
ein Subset von Portins - dort 5 - maximal ein gesetztes Bit enthält. Was 
zum Schema (var & (var - 1)) nur noch eine Ausblendung der ungefragten 
Pins hinzu fügt.

von Klaus W. (mfgkw)


Lesenswert?

Ja, jetzt kann man das so eruieren.
Einfacher wäre es gewesen, man hätte am Anfang gewusst, was es soll.
Aber egal, ich muß ja hier nicht meine Probleme lösen...

von Rainer (Gast)


Lesenswert?

was er wollte, war doch nichts anderes, als bei dem genannten Portpin, 
bestehend aus genau 5 Pins, herauszufinden, ob zu jedem Zeitpunkt mehr 
als 2 Pins ein Signal bekommen. Falls ja, soll eine Fehlermeldung 
erscheinen, andernfalls soll was anderes geschehen. Was genau geht nicht 
hervor.

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.