Maskierungsprobleme

Gast #5639548
Lesenswert?

Hallo miteinander

Ich lese momentan mit einem Mikrokontroller (ATM644) Einen 8X Dipswitch 
aus.
Ich möchte in den Variabeln GainSen1-4 nur immer 2 Bit von dem Switch 
haben. Dafür habe ich dies nach rechts geschoben und mit 0x03 verundet. 
Nachdem noch mit 0x10 verodert, da ich immer dieses eine Bit noch dazu 
benötige. Somit sollten keine anderen Schalter einen Einfluss auf die 
Einzelnen Gain's besitzen. Jedoch wenn ich z.B. nur Bit 6 und 1 
einschalte am Switch, wird mir schon ein Fehler ausgegben. So besitzt 
einer der Variabeln GainSen1-4 0x13. Jedoch sollte dies nie passieren 
und ist für mich unlogisch. Sieht jemand den Fehler, wo dies auslösen 
könnte. Ich Versuchte schon das Ganze konstrukt anderst zu schreiben 
half aber jedoch nicht.

1
#include <avr/io.h>
2

3
int main(void)
4
{
5

6
  unsigned char GainSen1 = 0;
7
  unsigned char GainSen2 = 0;
8
  unsigned char GainSen3 = 0;
9
  unsigned char GainSen4 = 0;
10

11
  
12
    while(1)
13
    {
14

15
        //8x Dipswitch auslesen
16
        GainSen1 = ((PIND >> 6)&0x03)|0x10;    //Nur Bit 6 und 7
17
        GainSen2 = ((PIND >> 4)&0x03)|0x10;    //Nur Bit 4 und 5
18
        GainSen3 = ((PIND >> 2)&0x03)|0x10;    //Nur Bit 2 und 3
19
        GainSen4 = (PIND & 0x03)|0x10;      //Nur Bit 0 und 1
20
    
21
        //Auf ("0x03" + 0x10) überprüfen Verboten laut Datenblatt
22
        if ((GainSen1 | GainSen2 | GainSen3 | GainSen4) == 0x13) 
23
        {
24
          PORTA = PORTA & ~0x80;
25
        }
26
    }
27
}
#5639556
Lesenswert?

Dein Code sieht gut aus. Schuss ins Blaue: vielleicht ist bei dir PIND 
als Signed deklariert. Dann wäre der Fehler logisch:

Probier mal das hier:

        //8x Dipswitch auslesen
        unsigned char p = PIND;
        GainSen1 = ((p >> 6)&0x03)|0x10;    //Nur Bit 6 und 7
        GainSen2 = ((p >> 4)&0x03)|0x10;    //Nur Bit 4 und 5
        GainSen3 = ((p >> 2)&0x03)|0x10;    //Nur Bit 2 und 3
        GainSen4 = (p & 0x03)|0x10;      //Nur Bit 0 und 1
Gast #5639562
Lesenswert?

Naja. Leider bedeutet der Code nicht das, was Du verbal beschreibst.


Das hier:
1
if ((GainSen1 | GainSen2 | GainSen3 | GainSen4) == 0x13)

bedeutet nicht, dass die Bedingung war wird, falls einer der 
GainSenX-Werte == 0x13 ist.

Vielmehr bedeutet es, dass die Bedingung wahr wird, falls _die 
Bitweise-Oder Verknüpfung aller_ GenSenX Werte == 0x13 ist.

Dem Fehlerbeispiel entsprechend ergibt das Folgendes:

Seien Bit 6 und Bit 1 des Schalter gesetzt.


        GainSen1 = ((PIND >> 6)&0x03)|0x10;
        GainSen4 = (PIND & 0x03)|0x10;

mit Eingabe ergibt sich:

        GainSen1 = ((0x82 >> 6)&0x03)|0x10;
        GainSen4 = (0x82 & 0x03)|0x10;

nach dem schieben:

        GainSen1 = (0x02 & 0x03)|0x10;
        GainSen4 = (0x81 & 0x03)|0x10;

nach der Und-Verknüpfung

        GainSen1 = (0x02 |0x10;
        GainSen4 = (0x01)|0x10;

nach der Oder Verknüpfung

        GainSen1 = 0x12;
        GainSen4 = 0x11;

In der IF-Bedingung werden diese Werte nochmal Oder-Verknüpft.

        GainSen1 | ... | GainSen4;

        0x12 | ... | 0x11;

was eben 0x13 ergibt.

Erst danach vergleichst Du ja mit 0x13.
Gast #5639563
Lesenswert?

Habe ich gleich ausprobiert. Funktioniert Leider nicht.
Folgende Bitmuster habe ich ausprobiert und gehen nicht:

10010000
10000100
10000001
01100000
01001000
01000010

Es besitzt auch eine Regelmäsigkeit somit muss ein fehler forliegen.
#5639567
Lesenswert?

Deine Beschreibung klingt, als meintest du in der if-Bedingung:
1
//Auf ("0x03" + 0x10) überprüfen Verboten laut Datenblatt
2
if ((GainSen1 == 0x13) || (GainSen2 == 0x13) || (GainSen3 == 0x13) || (GainSen4 == 0x13)) {

(true wenn einer der GainSen-Werte 0x13 ist)

Deine Bit-Veroderung ist etwas anderes: Wenn Bit 1 und 6 an sind, dann 
ist GainSen1 = 0x12, GainSen2= GainSen3 = 0x10 und GainSen4 = 0x11.
0x12 | 0x11 = 0x13
Gast #5639570
Lesenswert?

Au Mist. Da hat sich ein Fehler eingeschlichen:

nach dem schieben:

        GainSen1 = (0x02 & 0x03)|0x10;
        GainSen4 = (0x82 & 0x03)|0x10;

nach der Und-Verknüpfung

        GainSen1 = (0x02 |0x10;
        GainSen4 = (0x02)|0x10;

nach der Oder Verknüpfung

        GainSen1 = 0x12;
        GainSen4 = 0x12;

In der IF-Bedingung werden diese Werte nochmal Oder-Verknüpft.

        GainSen1 | ... | GainSen4;

        0x12 | ... | 0x12;

was eben 0x12 ergibt.


Dann tritt der Fehler so nicht ein. Sorry.
Gast #5639591
Lesenswert?

Josh schrieb:
> So besitzt einer der Variabeln GainSen1-4 0x13.
das wäre
(GainSen1== 0x13 || GainSen2 == 0x13|| GainSen3== 0x13 || GainSen4== 
0x13) == 0x13)
>         if ((GainSen1 | GainSen2 | GainSen3 | GainSen4) == 0x13)
bit0 bit1 bit7 ist in mind.1 einer Variable gesetzt.
#5639693
Lesenswert?

Josh schrieb:
> Mit dem Funktionier es. Aber wiso nicht, wenn ich über das gesammte nach
> 0x13 abfrage?

Du verwechselst | und ||.
| liefert eine bitweise VerODERung, || ist ein logisches ODER.
Mit ((GainSen1 | GainSen2 | GainSen3 | GainSen4) == 0x13) veroderst Du 
zuerst alle Bits von GainSen1..4 und vergleichst dann das Ergebnis mit 
0x13.

Du willst aber wissen, ob mindestens eine der 4 GainSen Variablen beide 
Bits 0 bzw. 1 gesetzt haben, also 0x13 als Wert haben. Und dazu musst Du 
eben jede der 4 Variablen mit 0x13 verghleichen und das jeweilige 
TRU/FALSE Ergebnis miteinander logisch verODERn.

Gruß, Stefan

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren