Forum: Mikrocontroller und Digitale Elektronik Muxer/Demuxer adressieren - Problem mit Bitoperationen


von Holger K. (zaldo)


Lesenswert?

Hallo zusammen,

ich beiße mir gerade an - wahrscheinlich - einem typischen 
Anfangerfehler die Zähne aus.

Ich habe an einem Mega32 Port zwei 16 in 1 Multiplexer/Demultiplexer 
angeschlossen, die ich adressieren möchte. Der "Receive" Muxer hängt 
dabei an PB0..PB3 und der "Send" an PB4..PB7

Ich habe nun folgende Funktionen geschrieben:
1
void Set_RCV (uint8_t bits) // Low Byte von PORTB
2
{
3
  uint8_t byte;
4
5
  byte = (PORTB &= 0x0f);
6
  byte |= bits;
7
  
8
  PORTB = byte;
9
}
10
11
void Set_SND (uint8_t bits) // High Byte von PORTB
12
{
13
  uint8_t byte;
14
  
15
  byte = (PORTB &= 0xf0);
16
  byte |= (bits <<4);
17
  
18
  PORTB = byte;
19
}

und benutze folgendes Testprogramm (der relevante Ausschnitt)
1
int x=1;
2
int y=1;
3
4
for (x=1;x<=16;x++)
5
{
6
  Set_SND(x);
7
  
8
  for (y=1;y<=16;y++)
9
  {
10
    lcd_string_xy(0,0,"SEND:     ");
11
    lcd_number_xy(11,0,x,2,32);
12
13
    lcd_string_xy(0,1,"RECEIVE:  ");
14
    lcd_number_xy(11,1,y,2,32);
15
16
    Set_RCV(y);
17
18
    btnpress(2);
19
  }
20
}

Die Displayausgabe dient hier nur der Visualisierung welche Werte 
gesetzt sind. btnpress(2) wartet einfach nur bis ein Taster gedrückt 
wird.

Wenn ich das Programm laufen lasse und mit dem Logiktester die Pins 
ablese beobachte ich folgendes: Auf PB0..PB3 werden die Bits zwar 
gesetzt aber nicht gelöscht. Ich schicke eine 1 und PB0 wird gesetzt. 
Ich schicke eine 2 und PB1 wird gesetzt, PB0 BLEIBT jedoch gesetzt. Bei 
einer 3 ändert sich weiter nichts, mit der 4 wird PB2 gesetzt (PB0 und 
PB1 bleiben ebenfalls gesetzt) und so weiter.

PB4..PB7 bleiben allesamt auf 0

Wo liegt meine dummer Fehler??

Danke im Voraus und beste Grüße
Holger

: Verschoben durch User
von Stefan K. (stefan64)


Lesenswert?

Du willst die relevanten Bits löschen, dazu musst Du die Maske 
invertieren:
1
void Set_RCV (uint8_t bits) // Low Byte von PORTB
2
{
3
  uint8_t byte;
4
5
  byte = (PORTB &= ~0x0f);
6
  byte |= bits;
7
  
8
  PORTB = byte;
9
}
10
11
void Set_SND (uint8_t bits) // High Byte von PORTB
12
{
13
  uint8_t byte;
14
  
15
  byte = (PORTB &= ~0xf0);
16
  byte |= (bits <<4);
17
  
18
  PORTB = byte;
19
}

Maske:            0x0f 00001111b
invertiert:      ~0x0f 11110000b

Bsp PortB = 0x15  0x15 00010101b
PORTB &= ~0x0f    0xf0 11110000b
--------------------------------
Ergebnis:         0x10 00010000b

Zweiter Fehler:
Deine Schleifen laufen von 1.. 16. Damit laufen die 4 Bits über.
Richtig ist eine Schleife von 0 .. 15.


Viele Grüße, Stefan

: Bearbeitet durch User
von Holger K. (zaldo)


Lesenswert?

Super, läuft. Danke Stefan.

Verdammt, das mit den Schleifen ist ja schon peinlich :-((((((

Gruß
Holger

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

>  byte = (PORTB &= ~0x0f);

Das sind zwei Zuweisungsoperatoren in einer Zeile.

Das willst Du nicht.

Lass den zweiten Zuweisungsoperator weg, denn sonst beschreibst Du 
PORTB.

Die Klammern sind übrigens auch überflüssig.

Also:

byte = PORTB & ~0x0f;

von Holger K. (zaldo)


Lesenswert?

Ja stimmt, hiesse ausgeschrieben byte = (PORTB = PORTB & ~0x0f) wenn ich 
richtig liege. Macht wenig Sinn. Danke. Ich lerne noch :-)

LG
Holger

von Stefan K. (stefan64)


Lesenswert?

Rufus Τ. F. schrieb:
> byte = PORTB & ~0x0f;

Oh wie peinlich. Habe ich mit abgeschrieben. Asche auf mein Haupt.

Gruß, Stefan

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.