Direkte Portmanipulation - Denkfehler?

Hallo zusammen,

habe mit dem Tiny13 weitere Experimente gemacht und bin bei der Portmanipulation gelandet.

Folgender Sketch bereitet mir Kopfzerbrechen

//Testsketch für ATTiny13
//direkte Portmanipulation

void setup() {                

  DDRB |= (1 << PB4) | (1 <<PB0);  //PB4 und PB0 als Output
  PORTB |= (1 << PB4);  //PB4 HIGH
  delay(1000);    //ist nur, damit ich PB4 messen kann
 }
void loop(){
    PORTB |= (1 << PB0);
    delay(500);
    PORTB &= (0 << PB0);
    delay(500);
}

Ich möchte also PB4 dauerhaft HIGH schalten und PB0 blinkt fröhlich.
Blinken tut's auch, aber PB4 schaltet wieder auf LOW.

Wer öffnet mit die Augen :fearful: für das sicherlich Offensichtliche?

Merci
Klaus

DDRB = (1 << PB5) | (1<<PB0);
PORTB |= (1 << PB5);

Versuch das mal so.

Meines Erachtens setzt du mit
PORTB &= (0 << PB0);
auch Port4 wieder auf Null.

PORTB &= (0 << PB0);

Falsch. Du musst mit dem invertierten Muster verunden um es zu löschen, da das Bit das gelöscht werden soll 0 sein muss:

PORTB &= ~(1 << PB0);

Außerdem muss da eine 1 rein und keine 0. Das Schieben ist dazu da um das entsprechende Bit zu setzten. Das geht auch einfach mit dem _BV() Makro (für Bit Value):

PORTB &= ~_BV(PB0);

Zwei selbst-geschriebene Makros helfen auch:

#define bit_set(p,m) ((p) |= (m)) 
#define bit_clear(p,m) ((p) &= ~(m)) 

bit_clear(PORTB, _BV(PB0));

Man könnte auch das _BV() gleich in das Makro packen. Dann muss man nur bit_clear(PORTB, PB0) schreiben

Ähh, aha, das muss ich gleich mal probieren.

Danke!

Sagenhaft, das funktioniert.

Und ich dachte bzw. hatte verstanden, dass PORTB &= (0 << PB0); PB0 mit 0 "ver-undet" und somit auf 0 setzt.

Das setzt den ganzen Port auf 0. Nicht nur das eine Bit.

Die Makros wie PB0, PB1, etc. sind die Nummern der Bits um Port-Register. PB2 wäre also 2. Wenn man 1 zweimal nach links schiebt hat man 0000 0100.

Das invertiert man dann:
1111 1011

Wenn man jetzt das Register damit verundet wird das Bit gelöscht, da das UND auf jeden Fall 0 ergibt.

ich glaub ich hab's jetzt gefressen, danke.