Forum: Mikrocontroller und Digitale Elektronik PORTB = (1<<PB(w));


von Mike S. (alber)


Lesenswert?

Hallo

Ich möchte, mal wieder, einen Einstieg in die C-Programmierung versuchen 
und bin dabei auf folgendes Problem gestoßen.


Ich möchte mit dem angefügten Program einfach, mit kleiner Verzögrung, 
die Ausgänge am PortB durchschalten, zu diesen Zweck soll in der While 
Schleife die Variable "W" hochgezählt werden und dann an den Port 
übergeben(PORTB = (1<<PB(w));). Funktioniert so, wie im Quelltext, aber 
nicht. :o(  Im GCC Tutorial habe ich leider auch keine Lösung für dieses 
Problem gefunden.

Die verwendete Hardware ist das STK500.
Kann Mir da jemand auf die Spründe helfen?
Gruß Mike





#include <avr/io.h>
#include <util/delay.h>


void sleep (uint8_t ms){

  for (;ms>0;ms--) _delay_ms(10);
  }

int main (){

  DDRB  = 0xFF;  //PortB als Ausgang
  PORTB = 0x00;  //PortB Ausschalten
  int x=255;    //länge der Pause
  int w=0;    //Variable für Portpin(0-7)

while(1){      //endlosschleife

  PORTB = (1<<PB(w));  //Port einschalten
  //x++;
  sleep(x);      //Sleep function aufrufen
  w++;        //nächsten portpin wählen
  if (w>7) w=0;
  }

return(0);
}

von Muggel (Gast)


Lesenswert?

PORTB = (1<<PB(w))

--> PB0 , PB1, etc sind Makros und keine Funktionen...du könntest das 
mit einer switch-case Anweisung lösen, ungefähr so...
switch(w){
   case 0: PORTB = (1<<PB0); break;
   case 1: PORTB = (1<<PB1); break;
    ...
}

von ich (Gast)


Lesenswert?

Mike S. schrieb:
>   PORTB = (1<<PB(w));  //Port einschalten
Wie ist denn dieses PB()-Dingsda (Funktion? Makro?) definiert?

von ich (Gast)


Lesenswert?

Ah Ok, jetzt verstehe ich. Nimm einfach PORTB=(1<<w);

von Muggel (Gast)


Lesenswert?

ich schrieb:
> Ah Ok, jetzt verstehe ich. Nimm einfach PORTB=(1<<w);

Das geht natürlich auch...

von Mike S. (alber)


Lesenswert?

Auweier,

das die Lösung nicht schwer sein kann, war mir eigentlich klar, aber so 
einfach :oS

Ich hatte so einiges durchprobiert -- Is wohl so ein Fall vom "Wald 
lauter Bäume nicht sehen" :)

Na jedenfalls Ich danke euch und wünsche einen schönen abend und ein 
gesundes neues Jahr.

von Peter II (Gast)


Lesenswert?

ich schrieb:
> Ah Ok, jetzt verstehe ich. Nimm einfach PORTB=(1<<w);

das macht zwar etwas sehr ähnliches aber nicht das gleiche. (1<<w) ist 
keine Konstante damit muss es zur laufzeit aufgerechet werden, das ganze 
ist sehr langsamt weil der AVR kein mehrfach schift kann. Dazu kommt 
noch das Problem das weil es auch wieder keine Konstante ist, das der 
Port voher ausgelesen und wieder geschrieben wird, das ganze ist also 
nicht mehr atomar. Macht ärger wenn noch eine ISR auch auf dem Port 
arbeitet.

auch wenn es nehr sehr elegant ist, die Switch case variante ist 
durchaus eine sinnvoller alternative.

von ich (Gast)


Lesenswert?

Peter II schrieb:
> ...

Stimmt schon, dürfte im konkreten Fall aber wenig relevant sein. 
Trotzdem gut für später auf solche Sachen hinzuweisen, gerade das mit 
dem atomar bzw. nicht atomar kann sehr merkwürdige Fehler erzeugen...

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.