Forum: Compiler & IDEs Atmega8-Programmierung Anfängerfrage!


von Stefan (Gast)


Lesenswert?

Ich habe vor kurzem mit dem Programmieren von Atmega8 und Attiny13 
begonnen. Ich habe schon Blink- und Lauflichter mit LEDs programmiert. 
Jetzt habe ich eine Frage:

Wenn ich ein Byte zu einem Port schreiben will (sag man das so?) habe 
ich das so gemacht:
1
PORTB = 0b10011001;

Die 1.,4.,5. und 8. LED leuchtet, die 2.,3.,6. und 7. bleibt dunkel.

Jetzt möchte ich, dass bspw. die ersten drei Ausgänge entweder 0 oder 1 
sind, abhängig von irgendwas...

Nachher die restlichen 5 LEDs in einer Reihenfolge(von irgendetwas 
abhängig) blinken lassen.

Wenn ich aber den Status des 1. Ausgangs nicht kenne, den 6. und 7. aber 
auf HIGH haben möchte funktioniert das nicht:
1
PORTB = 0b01100000;

Da ich ja alle anderen Bits auf 0 setzte.

Ich möchte also den Wert einzelner Bits ändern, ohne die anderen zu 
beeinflussen.

Ich hoffe man versteht meine Frage.
Ich habe das AVR-GCC Tutorial gesehen, nur ist das ohne 
Programmiererfahrungen etwas schwierig.

Stefan

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan schrieb:
> Wenn ich aber den Status des 1. Ausgangs nicht kenne

Den kennst du: PORTB lässt sich zurücklesen.
1
  uint8_t tmp = PORTB;
2
  tmp &= ~0b00111111;  // keep low 6 bits as they are
3
  tmp |= newval << 6;  // newval: 1 ... 3 => 0b01000000 ... 0b11000000
4
  PORTB = tmp;

von Rene (Gast)


Lesenswert?

Schau mal hier: Bitmanipulation

Grüsse,
R.

von Oliver (Gast)


Lesenswert?

Die Zauberwörter heissen "und", "oder" und "nicht".

Such dir ein gutes C-Buch, und arbeite das durch. Irgenwann kommt darin 
ein Kapitel mit den Operatoren, darin sind dann auch die Bit-Operatoren 
beschrieben. Wenn du das gelesen hast, dann lies nochmals das Kapitel 
dazu im Tutorial durch. Denn da steht eigentlich alles drin.

Ganz ohne Grundlagen lernen und verstehen wird das sonst sehr schwierig.

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Oliver schrieb:
> Die Zauberwörter heissen "und", "oder" und "nicht".

Nicht allein.  Man muss auch das Konzept kennen, dass man beim AVR
die in PORTx gesetzten Ausgangsbits zurücklesen kann.  Das ist ja
nicht notwendigerweise bei jedem Controller so, bei manch anderem
liest man auf diese Weise den Zustand der Eingänge.

von Stefan (Gast)


Lesenswert?

Vielen Dank für die schnellen Antworten!

Stefan

von Ralf G. (ralg)


Lesenswert?

Jörg Wunsch schrieb:
> Den kennst du: PORTB lässt sich zurücklesen.

Meistens kann sich auch merken [ Variable ;-) ], was man irgendwann mal 
dorthin geschrieben hat.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf G. schrieb:
> Meistens kann sich auch merken [ Variable ;-) ], was man irgendwann mal
> dorthin geschrieben hat.

Wenn es sich der Controller merkt, ist das aber überflüssig.  Teurer
ist es obendrein (weil ein LDS einer Variablen aus dem Speicher mehr
Zeit und Flash kostet als ein IN direkt von PORTB).

von Ralf G. (ralg)


Lesenswert?

Jörg Wunsch schrieb:
> Wenn es sich der Controller merkt, ist das aber überflüssig.

Ich hatte jetzt eher daran gedacht, dass sich die verschiedenen 
Bitzustände ja irgendwie ergeben|empfangen|berechnet|manipuliert werden 
müssen. Dazu müssen die Grundlagen ja irgendwo herkommen. Der Ausgang 
wird ja nicht von außen geändert...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ja, aber wenn man (was nicht untypisch ist) die Bits in völlig
unabhängigen Zweigen berechnet (weil beispielsweise an Bit 0 bis
2 Status-LEDs hängen, während bit 4 und 5 irgendwelche externe
Peripherie steuern), dann ist das Rücklesen von PORTB schon der
sinnvollste Platz um zu ermitteln, welchen Zustand die Portpins
gerade haben.

von Ralf G. (ralg)


Lesenswert?

Jetzt klingelt's erst: Sowas hatte ich als 'Zurückleseoperation' völlig 
ignoriert:
1
PORTB &= ~(3 << 6);

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf G. schrieb:
> Sowas hatte ich als 'Zurückleseoperation' völlig
> ignoriert:

Ja, und selbst CBI und SBI sind read-modify-write, wenn auch atomar.

von Johannes P. (Firma: Zodiac) (nbgabber)


Lesenswert?

Für solche zwecke habe ich in meinen Projekten immer folgende defines 
angelegt:

#define setBit(byte, mask) byte = byte | (mask)
#define clearBit(byte, mask) byte = byte & ~(mask)
#define changeBit(byte, setMsk, clsMsk) byte = (byte | (setMsk)) & 
~(clsMsk)

setBit setzt die Bits die in mask = 1 sind
und clearBit löscht alle Bits (auf 0 setzen) die in mask = 1 sind

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.