Forum: Mikrocontroller und Digitale Elektronik Bit an einem Port manipulieren


von Martin (Gast)


Lesenswert?

Hallo,

Vorweg: ich habe diesen Artikel hier gelesen:
http://www.mikrocontroller.net/articles/Bitmanipulation#Standard_C

Nun habe ich an meinem Atmega8 folgendes "Problem":
PB0 dient für das Input Capture, Pullup aktiviert
PB1-PB6 hängt ein Darlington Array
PB7 ist unbenutzt (Pullup aktiviert)

Der Darlingten Array wird je nach Programmereignis teilweise an und 
ausgeschaltet, d.h. PB1 bis PB6 werden je nachdem zufällig verändert.

Angenommen die Kombination lautet bspw.:
(1)
PB1 high
PB2 high
PB3 low
PB4 low
PB5 high
PB6 low

Im nächsten Durchlauf der Hauptschleife soll es dann so aussehen
(2)
PB1 high
PB2 low
PB3 low
PB4 high
PB5 high
PB6 high

Die Änderung bzw. der Zustand des Darlington Arrays ist in einer 
Variable gespeichert, z.B. für (1) so:
0b0010011
Durch ein linksschieben würde ich es auf die Stellen platzieren, wie 
auch der Port gesetzt werden soll:
0b0100110

Nun habe ich aber das Problem, das PB0 und PB7 die Pullups aktiviert 
sind, d.h. hier eigentlich eine 1 steht.

Wie schriebe ich das wieder auf den Port-Ausgang am besten zurück ohne 
PB0 und PB7 zu ändern?

Als Anfänger würde ich jetzt noch in dieser Variable durch 
Bitmanipulation PB0 und PB7 auf 1 setzen und dann auf den Port komplett 
zurückschreiben.

Oder wie macht man das am geschicktesten?

Martin

von Stefan E. (sternst)


Lesenswert?

1
PORTB = (PORTB & 0x81) | (data << 1);

von Martin (Gast)


Lesenswert?

Super, danke.
Das ist im Prinzip das was ich auch mir gedacht bzw. geschrieben hatte, 
nur in einem Aufwasch zusammengefasst.

von Stefan E. (sternst)


Lesenswert?

Martin schrieb:
> Das ist im Prinzip das was ich auch mir gedacht bzw. geschrieben hatte,
> nur in einem Aufwasch zusammengefasst.

Falls du damit das hier meinst
> Als Anfänger würde ich jetzt noch in dieser Variable durch
> Bitmanipulation PB0 und PB7 auf 1 setzen und dann auf den Port komplett
> zurückschreiben.
dann nein, es ist ein wenig was anderes. Es erhält den aktuellen Zustand 
von PB0 und PB7 und setzt sie nicht auf 1.

von Achim M. (minifloat)


Lesenswert?

Martin schrieb:
> Wie schriebe ich das wieder auf den Port-Ausgang am besten zurück ohne
> PB0 und PB7 zu ändern?
1
uint8_t meinportb = PORTB;
2
3
// rette PB0 und PB7
4
uint8_t maske = meinportb & ( (1 << PB0) | (1 << PB7) );
5
6
// Schiebung wie gefordert
7
meinportb = meinportb << 1;
8
9
// Rotieren über Carry Emulation
10
// Oberstes Bit PB7, war ja vorm Schieben PB6, gesetzt?
11
if (meinportb & (1 << PB7))
12
{
13
  // füll es unten bei PB1 wieder rein
14
  meinportb |= (1 << PB1);
15
}
16
else
17
{
18
  // ja ansonsten lösch es halt
19
  meinportb &= ~(1 << PB1);
20
}
21
22
// stelle PB0 und PB7 wieder her
23
meinportb &= ~( (1 << PB0) | (1 << PB7) );
24
meinportb |=  maske;
25
26
PORTB = meinportb;

mfg mf

von Stefan E. (sternst)


Lesenswert?

Joachim минифлоть schrieb:
> ...

Du hast die Aufgabenstellung missverstanden.

von Achim M. (minifloat)


Lesenswert?

Stefan Ernst schrieb:
> Du hast die Aufgabenstellung missverstanden.

Nein. Beide Fragen des Eröffnungspostings wurden mit einer möglichen 
Lösung beantwortet. Was den Krempel zwischen "Retten" und 
"Zurückschreiben" angeht, das ist ja nicht von Interesse. Hat sich der 
TO auch selber hergeleitet.

Martin schrieb:
> Die Änderung bzw. der Zustand des Darlington Arrays ist in einer
> Variable gespeichert

Die Änderung des Zustands?? Ich sehe weder in deinem noch in meinem 
Code einen EXOR-Operator. Wir habens also beide falsch gemacht. Ich 
bring dich jetzt wieder zurück in den Sandkasten, ja?

von Stefan E. (sternst)


Lesenswert?

Joachim минифлоть schrieb:
> Stefan Ernst schrieb:
>> Du hast die Aufgabenstellung missverstanden.
>
> Nein. Beide Fragen des Eröffnungspostings wurden mit einer möglichen
> Lösung beantwortet. Was den Krempel zwischen "Retten" und
> "Zurückschreiben" angeht, das ist ja nicht von Interesse. Hat sich der
> TO auch selber hergeleitet.

Wenn der "Mittelteil" von dir nur als Beispiel ohne Bezug zum OP gedacht 
war, wieso steht dann beim Schieben des Port-Inhalts als Kommentar 
"Schiebung wie gefordert"?

Joachim минифлоть schrieb:
> Martin schrieb:
>> Die Änderung bzw. der Zustand des Darlington Arrays ist in einer
>> Variable gespeichert
>
> Die Änderung des Zustands?? Ich sehe weder in deinem noch in meinem
> Code einen EXOR-Operator. Wir habens also beide falsch gemacht.

Auch trotz der etwas unglücklichen Formulierung ist absolut klar, was er 
machen möchte.

Joachim минифлоть schrieb:
> Ich bring dich jetzt wieder zurück in den Sandkasten, ja?

Ernsthaft jetzt? Du reitest eine alberne persönliche Attacke, weil ich 
so "dreist" war zu behaupten, du hättest etwas missverstanden?

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.