mikrocontroller.net

Forum: Compiler & IDEs Per UART empfangenen String weiterverarbeiten


Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo @ all.
Ich fange gerade an mit C zu programmieren und habe ein paar Fragen zu 
folgender Situation :

Ich möchte eine per UART empfangenen String (GCC-Tutorial) 
weiterverarbeiten, der bzw. die Strings sind wie folgt aufgebaut :

-Stelle 1 [1-3] => Unterscheidung an welchem Port die Daten ausgegeben 
werden sollen

-Stelle 2 bis 4 bzw.5 [0-9] => Wert der auf mehreren 7 Segmentanzeigen 
angezeigt werden soll

-Stelle 5 bzw. 6 [:] => 'Endezeichen'
/* Zeichen empfangen */
uint8_t uart_getc(void)
{
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
        ;
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
}
 
void uart_gets( char* Buffer, uint8_t MaxLen )
{
  uint8_t NextChar;
  uint8_t StringLen = 0;
 
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
 
                                  // Sammle solange Zeichen, bis:
                                  // * entweder das String Ende Zeichen kam
                                  // * oder das aufnehmende Array voll ist
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
    *Buffer++ = NextChar;
    StringLen++;
    NextChar = uart_getc();
  }
 
                                  // Noch ein '\0' anhängen um einen Standard
                                  // C-String daraus zu machen
  *Buffer = '\0';
}

Ich dachte mir jetzt nach der Zeile '*Buffer='\0' ' zunächst via
switch(buffer[1])
case('1'):....;
break;
case('2'):....;
break; 
....
zu unterscheiden für welche Anzeigen die Werte gedacht sind und 
scheitere an meinem geplanten weiteren Wunsch dann danach die Stellen 2 
bis 4/5 einzulesen und als geeigneten Wert für die Anzeigen so 
abzuspeichern das ich sie dann bitweise am entsprechenden Port an das 
Schieberegister ausgeben kann, zB 1 = 0x00000011;
Ich krieg es nicht auff die Reihe das in den entsprechenden Variablen zu 
speichern und dann auszugeben...

Wäre für jede Hilfestellung dankbar !!!

MfG,
Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass die uart_gets so wie sie ist.

Du machst die Ausertung des Strings ausserhalb
int main()
{
  char input[80];
  char wertASCII[10];
  unsigned char port;
  unsigned char wert;

  ....

  while( 1 ) {

    uart_gets( input, sizeof( input ) );

    // Zeichen Nr 0 ist der Port
    port = input[0] - '0';         // portnummer
    
    // Zeichen 1, 2, und 3 bilden den Wert
    wertASCII[0] = input[1];
    wertASCII[1] = input[2];
    wertASCII[2] = input[3];
    wertASCII[3] = '\0';
    wert = atoi( wertASCII );

    // mach was mit portNr und Wert

    ...
  }
}

Autor: Oliver Müller (gonzox)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mal versucht, das wie folgt zu lösen (=> siehe Anlage).
Wäre sehr nett wenn ihr mich auf Fehler oder Verbesserungen hinweisen 
könntet.

Danke im Voraus,
Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wichtigste was du unbedingt beherzigen solltest:
Jede Funktion soll nur das machen, was auch aussen drauf steht!
Die Funktion heisst uart_gets. In langen Worten: hole einen String von 
der UART.
Die Funktion heisst nicht uart_gets_and_set_7_seg_Led!
D.h. deine Funktion macht viel zu viel!

Teile dir die Problemkreise auf. uart_gets ist dafür zuständig einen 
String über die UART zu empfangen. Nicht mehr aber auch nicht weniger. 
Was mit diesem String passiert, ist nicht das Bier von uart_gets. Dafür 
ist u.U. eine andere Funktion zuständig, aber auf jeden Fall nicht 
uart_gets.

Nur so kriegst du dann einen Baukasten, in dem du Funktionen 
wiederverwenden kannst und die du in weitere Projekte übernehmen kannst.


Zu deiner restlichen Auswertung:
Das ist übelste Copy&Paste Programmierung. Such nach gemeinsamen Teilen 
und lagere die in eigene Funktionen aus.

zb. Sieht bei dir ausnahmslos jeder case-Fall so aus (ICh hab es jetzt 
nur anhand von Stichproben kontrolliert)
       if(LED_0[y]==0)
          {
          PORTB &= ~(1 << PB1);
          }
          else
          {
          PORTB|=(1 << PB1);
          }
          PORTB &= ~(1 << PB2);
          PORTB |= (1 << PB2);
        }
        PORTB &= ~(1 << PB2);
        PORTB |= (1 << PB2);

das einzige was sich ändert ist LED_0 oder LED_1 oder LED_2 ... da ganz 
oben.

D.h. der ganze restliche Teil ist heisser Kandidat für eine Funktion
void SetBit( char state )
{
  if( state == '0' )
  {
    PORTB &= ~(1 << PB1);
  }
  else
  {
    PORTB|=(1 << PB1);
  }
  PORTB &= ~(1 << PB2);
  PORTB |= (1 << PB2);
}


Damit würde deine Auswertung schon abmagern:
    if(Buffer[0]=="1")      //Fallunterscheidung welche 7-Segment Reihe die Daten anzeigen soll
    {
      PORTB &= ~(1 << PB3);
      for(x=1;x<6;x++)
      {
        switch(Buffer[x])
        {
          case 0:
            for(y=0;y<8;y++)
              SetBit( LED_0[y] );
            PORTB &= ~(1 << PB2);
            PORTB |= (1 << PB2);
            break;
          case 1:
            for(y=0;y<8;y++)
              SetBit) LED_1[y] );
            PORTB &= ~(1 << PB2);
            PORTB |= (1 << PB2);
            break;
          case 2:
            for(y=0;y<8;y++)
              SetBit( LED_2[y] );
            PORTB &= ~(1 << PB2);
            PORTB |= (1 << PB2);
            break;

    ....


Siehst du um wieviel einfacher das schon ist. Aber es geht noch weiter. 
Im Grunde sind die ganzen case-Fälle immer noch gleich. Einzig im 
LED-Argument unterscheiden sie sich. -> Funktion dafür machen.
void AllBits( char leds[] )
{
  unsigned char y;

  for(y=0;y<8;y++)
    SetBit( leds[y] );
  PORTB &= ~(1 << PB2);
  PORTB |= (1 << PB2);
}

und in der Verwendung erhalten wir dann
......

    if(Buffer[0]=="1")      //Fallunterscheidung welche 7-Segment Reihe die Daten anzeigen soll
    {
      PORTB &= ~(1 << PB3);
      for(x=1;x<6;x++)
      {
        switch(Buffer[x])
        {
          case 0: SetBits( LED_0 ); break;
          case 1: SetBits( LED_1 ); break;
          case 2: SetBits( LED_2 ); break;
          case 3: SetBits( LED_3 ); break;
         ....

Wow. Nicht schlecht. Der Code verkürzt sich rapide.
Aber noch ist nicht Ende der Fahnenstange. Der ganze Teil rund um die 
x-Schleife wird in jedem if( Buffer[0] == '1' ) Teil wiederholt -> ab in 
eine einzige Funktion damit.

PS: Buffer[0]=="1"
Das wird zwar vom Compiler akzeptiert, macht aber etwas ganz anderes als 
du vermutest. Strings kann man nicht auf diese Art vergleichen. Brauchst 
du auch nicht, denn du hast keine Strings. Du hast Character. Charcter 
schrieben sich mit ' und nicht mit ". Mit " ist das immer ein String.

   Buffer[0] == '0'


Fazit: Wann immer du versucht bist, Code einfach zu duplizieren, überleg 
dir ob eine Funktion nicht besser wäre. Letztenendes hast du weniger 
Arbeit, und baust weniger Fehler ein, wenn du gleich von vorneherein 
Funktionen machst. Dass es mit Copy&Paste in der Entwicklung schneller 
geht, ist ein Mythos.

Und der wichtigste und schwerwiegenste Fehler, den du machst: Du benutzt 
kein C-Buch um die Sprache zu lernen. Die Methode 'Schaun wir mal und 
holen uns dann Tipps von anderen' funktioniert bei Programmiersprachen 
nicht. Du brauchst Literatur!


PS2: Ist das richtig so, dass du nach jedem Bit-setzen mittels PB2 einen 
Puls generierst und nach allen 8 Bits noch einen Puls nachschiebst?

Autor: gonZoX (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz:
Danke für deine Hinweise, ist nachvollziehbar und war mir auch schon 
bewusst,dass ich da noch verkürzen kann und ich werde das mal 
durcharbeiten.
(Und auch noch mal mein altes C-Buch rauskramen,hat schon Staub 
angesetzt)

Das Nachschieben des Pulses habe ich aus dem Programmierbeispiel des 
7-Segment Herstellers übernommen (siehe Anlage,ist allerdings für einen 
PIC*)

MfG,
Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gonZoX schrieb:

> Das Nachschieben des Pulses habe ich aus dem Programmierbeispiel des
> 7-Segment Herstellers übernommen (siehe Anlage,ist allerdings für einen
> PIC*)

Schau dir das Codefragment noch einmal genau an!
Da wird kein Puls nachgeschoben. Übrleg einfach mal, wie sich die 
Manipulationenen am CLK auswirken und in welchem Zustand die CLK Leitung 
jeweils vorher war. Nur eine Änderung von CLK ist interessant.

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void LED_display(void)
{
  unsigned char i;
  unsigned char U;
  U=Value;
  for(i=1;i<8;i++)
  {
    DATA = U & 0x01;
    CLK = 0;
    CLK = 1;
    U = U>>1;
  }
  CLK = 1;
  CLK = 0;
}
Am Ende der 'for-Schleife' steht CLK auf 1, wird danach nochmal auf 1 
und wieder auf Null gesetzt, also kein eigentlicher Wechsel sondern ein 
Rückstellen auf Null und einmal 'CLK=1;' hätte man sich sparen 
können,oder ?

MfG,Oliver.

Autor: gonZoX (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es jetzt nach Durcharbeiten der Anregungen wie folgt gelöst 
(siehe Anhang),ich bitte um weitere Manöverkritik :)

MfG,
Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir die Funktion SetLeds noch mal genauer an. Da ist noch jede 
Menge weiterer Vereinfachungsspielraum.

* Gemeinsame Funktionalität auslagern
* was ist die Bedeutung der 'magischen Konstanten' im switch-case.
  Warum 48?

  Was ist leichter zu verstehen?
  switch( Zeichen )
    case 48: ...
    case 49: ...


  oder
  switch( Zeichen )
    case '0': ...
    case '1': ...

  In welcher Variante sehe ich besser, was mit dem switch beabsichtigt
  wird.


(Hast du schon einmal darüber nachgedacht, die ganzen LED_x in einem 2 
dimensionalen Array zusammenzufassen? Dann würde sich nämlich der ganze 
switch-case in Luft auflösen)


Es heißt zwar, dass vorzeitige Optimierung die Wurzel allen Übels ist. 
Das bedeutet aber nicht, dass man vorsätzlich Laufzeit verbraten soll 
....
  if(Zeile[0]=='1')
    {
       ..
    }

  if(Zeile[0]=='2')
    {
       ..
    }

  if(Zeile[0]=='3')
    {
       ..
    }

Wenn Zeile[0] gleich '1' ist, dann KANN es nicht mehr gleich '2 oder '3' 
sein. Dieser Test ist daher völlig überflüssig und kann ausgelassen 
werden.
  if(Zeile[0]=='1')
    {
       ..
    }

  else if(Zeile[0]=='2')
    {
       ..
    }

  else if(Zeile[0]=='3')
    {
       ..
    }



Warum läuft eigentlich x einmal bis 6 und einmal bis 5. Und was passiert 
eigentlich, wenn der String gar nicht so lange ist (also sagen wir mal 
aus 2 Zeichen besteht). Denkste du nicht es wäre besser, eine 
universelle Funktion zu schreiben, die mit beliebigen 'Zahlen' klar 
kommt?

Autor: Oliver Müller (gonzox)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke wieder einmal.
Die switch Anweisung hatte ich in der Weise gestaltet da ja die case 
Unterscheidung einen Integer erwartet, aber der Cast von z.B. '1' in 49 
findet ja automatisch statt, da hast du recht. ( Nur wie ich zuerst 
abgefragt hatte ' case 1 ' funktionierte logischerweise nicht).

Ist es von der Performance her ein Unterschied, ob ich 3x if abfrage 
oder via if .., else if, oder geht es nur um den besseren Stil ?

Das mit dem 2 dimensionalen Array muss ich mal versuchen 
umzusetzen,danke für den Hinweis.

MfG,
Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver Müller schrieb:

> Ist es von der Performance her ein Unterschied, ob ich 3x if abfrage
> oder via if .., else if, oder geht es nur um den besseren Stil ?

Eine Abfrage die nicht gemacht wird, verbraucht auch keine Zeit :-)
OK. Das ist jetzt nicht die Welt, ein Programm welches in Zeitnot gerät, 
kann man damit nicht retten, aber ein bischen was ist es auch.
AUsserdem hat es einen gewissen dokumentarischen Wert.

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm,
vom Ansatz dachte ich das in etwa so zu lösen :
...
  const unsigned char LEDNR[10][8] = {"11111100"/*0*/,"11000000"/*1*/,"11011010"/*2*/,"11110010"/*3*/,"01100110"/*4*/,"10110110"/*5*/,"10111110"/*6*/,"11100000"/*7*/,"11111110"/*8*/,"11110110"/*9*/};
....
void SetBits( char leds[] )
{
  unsigned char y;

  for(y=0;y<8;y++)
    {
      if( leds[y] == '0' )
      {
        PORTB &= ~(1 << PB1);
      }
      else
      {
        PORTB|=(1 << PB1);
      }
      PORTB &= ~(1 << PB2);
      PORTB |= (1 << PB2);
  }
}

void setLEDS(char* Zeile)
{
  unsigned char x;

  if(Zeile[0]=='1')
    {
    PORTB &= ~(1 << PB3);
           for(x=1;x<6;x++)
                  {
                  SetBits( LEDNR[Zeile[x]] );
                  }
                  PORTB |= (1 << PB3);
                  }
        else if(Zeile[0]=='2')
.....

Habe ich das so richtig umgesetzt ???

Danke im Voraus,
Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gonZoX schrieb:

>            for(x=1;x<6;x++)
>                   {
>                   SetBits( LEDNR[Zeile[x]] );
>                   }
>                   PORTB |= (1 << PB3);
>                   }
>         else if(Zeile[0]=='2')
>
> Habe ich das so richtig umgesetzt ???

Das kann nicht stimmen. Denn Zeile[x] hat zb den Wert 49 (für '1') und 
das Array ist in dieser Dimension aber nur 10 Einträge groß :-)

Aber Zeile[x] - '0'   würde für Zeile[x] gleich '0' zb 0 ergeben. Und 
für '1' würde 1 rauskommen etc.


(Über die Verwendung eines char-Arrays zu Kodierung der Bits sollten wir 
uns sowieso noch unterhalten)

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:) Ja den falschen Index hatte ich übersehen,Danke.

>(Über die Verwendung eines char-Arrays zu Kodierung der Bits sollten wir
>uns sowieso noch unterhalten)

Ich denke du meinst ich sollte die Bits 'direkt' im Array speichern 
anstelle ihrer Entsprechung als String.

Allerdings bekomme ich das gedanklich noch nicht umgesetzt ....

MfG,Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gonZoX schrieb:

> Allerdings bekomme ich das gedanklich noch nicht umgesetzt ....

Dachte ich mir schon. Drum habe ich bisher auch noch nichts gesagt. Nur 
ist jetzt ein Punkt erreicht an dem ein eigentlich unnützes 2D Array 
eingeführt wird, nur damit die Bitcodierungen weiterhin als String 
bestehen bleiben können. Das würde wegfallen.
Auf der anderen Seite schadet es auch nicht, wenn du ein wenig Übung im 
Umgang mit Arrays kriegst :-)

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:) Nein das schadet mir garantiert nicht :)

Wenn ich heute Abend ein paar ruhige Minuten habe, werde ich mich da mal 
dransetzen und versuchen zu begreifen ...

MfG,
Oliver.

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Index war sogar doppelt falsch da er ja bei 1 startet und der 
entsprechende Array Inhalt dementsprechend an der Stelle x-1 liegt, 
würde bedeuten ' Zeile[x-1]-'0' ', oder nicht ?

:) Aber der Weg soll ja eh nicht weiter beschritten werden :)

Meine Werte habe ich jetzt wie folgt gesetzt :
  const unsigned char LEDBytes[] = {0xFC,0xC0,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};
und werde dann mal versuchen nachzuvollziehen wie ich das richtig 
übergebe.

MfG,
Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gonZoX schrieb:
> Der Index war sogar doppelt falsch da er ja bei 1 startet und der
> entsprechende Array Inhalt dementsprechend an der Stelle x-1 liegt,
> würde bedeuten ' Zeile[x-1]-'0' ', oder nicht ?

Nein. Das war schon richtig so.

Wenn Zeile[x] den Wert '5' enthält, dann sind die auszugebenden Daten 
bei LEDNR[5][..] zu finden. Also musst du auch LEDNR[5] an die 
Ausgabefunktion übergeben.

>
> :) Aber der Weg soll ja eh nicht weiter beschritten werden :)

Zur Übung könntes du das ja einfach mal probieren :_)

>
> Meine Werte habe ich jetzt wie folgt gesetzt :
>
>   const unsigned char LEDBytes[] =
> {0xFC,0xC0,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6};
> 
> und werde dann mal versuchen nachzuvollziehen wie ich das richtig
> übergebe.

Das sollte ja kein Problem sein. Die Funktion SetBits kriegt dann einen 
unsigned char und muss sich die Bits aus dem Wert herausholen.

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Das sollte ja kein Problem sein. Die Funktion SetBits kriegt dann einen
>unsigned char und muss sich die Bits aus dem Wert herausholen.

Doch das ist leider ein Problem für mich,ich begreife noch nicht wie ich 
das lösen kann.

Vorher habe ich ja einen String,also ein char array übergeben und bin 
mit dem Index durch die Positionen gewandert, das geht in mein kleines 
Hirn vom Verständnis noch rein :),
aber jetzt übergebe ich mit dem entsprechenden unsigned char ein byte 
und ich sehe nicht wie ich das bitweise auslese und entsprechend 
reagiere ....

MfG,
Oliver.

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... ich bedaure es wirklich sehr wenn ich den Wissenden auf den 'Keks' 
gehe, aber ich stehe total auf dem Schlauch und kann anscheinend ohne 
passendes Beispiel die Sache nicht selber umsetzen,sorry.

Wenn ich einer Funktion also einen unsigned char mit dem Wert z.B. 0xFC 
übergebe, wie kann ich dann die entsprechenden Bits auslesen und 
entsprechend ob 0 oder 1 reagieren.

Reines Vorsagen ist ansich wegen des fehlenden Lernerfolges keine gute 
Lösung, aber ich komme leider nicht weiter ....

Es wäre sehr nett wenn sich jemand erbarmen könnte mir das plausibel zu 
machen.

Danke im Voraus,
Oliver.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn ich einer Funktion also einen unsigned char mit dem Wert z.B. 0xFC
> übergebe, wie kann ich dann die entsprechenden Bits auslesen und
> entsprechend ob 0 oder 1 reagieren.
Du brauchst eine Ver-UND-ung mit einer Maske.

Wenn du wissen willst, ob im Wert 0xFC das Bit 3 gesetzt ist:
(Bit-Zählweise ist 7...0)
Bit      76543210
0xFC = 0b11111100

dann musst du dieses Bit mit 1 und alle anderen bits mit 0 ver-und-en:
0x08 = 0b00001000

daraus ergibt sich:
0xFC = 0b11111100
0x08 = 0b00001000
-----------------
         00001000  --> Jawoll, dieses Bit ist gesetzt

Beim Bit 1 wäre das
0xFC = 0b11111100
0x08 = 0b00000010
-----------------
         00000000 --> Dieses Bit ist nicht gesetzt

Du kannst natürlich auch mehrere Bits auf einmal kontrollieren:
Beim Bit 7 und Bit 3
0xFC = 0b11111100
0x08 = 0b10001000   ---.
-----------------      v
         10001000 == 10001000 --> Diese Bits sind beide gesetzt


Beim Bit 3 und Bit 0
0xFC = 0b11111100
0x08 = 0b00001001   ---.
-----------------      v
         00001000 != 00001001 --> Es sind nicht alle Bits gesetzt


Der bitweise UND Operator in C ist & (nicht verwechseln mit &&)

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deine Hilfe.

Ich habe ja bisher einen String übergeben und dann positionsweise 
geprüft, ob '0' oder '1' und dann entsprechend die Ports gesetzt.

Ich sehe noch nicht den Vorteil wenn ich jetzt anstelle des Strings ein 
Byte übergebe und dann jedes Bit einzeln überprüfe und entsprechend 
reagiere ???

Danke im Voraus,
Oliver.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gonZoX schrieb:

> Ich sehe noch nicht den Vorteil wenn ich jetzt anstelle des Strings ein
> Byte übergebe und dann jedes Bit einzeln überprüfe und entsprechend
> reagiere ???

Dein String hat 8 Bytes verbraucht, jetzt brauchst du nur noch 1 Byte.
Du hast aber nicht nur 1 String, du hast 8 davon. Macht 64 Bytes und das 
im Kontrast zu den 8 Bytes mit Bitmaskieren.

Rechenzeitmässig hält sich beides in etwa die Waage. Den Zugriff in das 
Array kriegst du auch nicht gratis, genausowenig wie das Ausmaskieren 
des richtigen Bits.
void SetBits( unsigned char leds )
{
  unsigned char y;
  unsigned char mask = 0x01;

  for(y=0;y<8;y++)
  {
      if( ( leds & mask ) == 0 )
      {
        PORTB &= ~(1 << PB1);
      }
      else
      {
        PORTB|=(1 << PB1);
      }
      PORTB &= ~(1 << PB2);
      PORTB |= (1 << PB2);

      mask <<= 1;
  }
}

Bleibt noch anzuführen, dass es ich bei solchen Maskieroperationen um 
eine Standardtechnik in der µC-Progammierung handelt. Wie willst du zb 
einen Eingang an einem Port auswerten, wenn du nicht weist, wie du das 
eine interessierende Bit isolieren kannst? Der Umgang mit &, | und 
Schiebeoperationen ist in der µC Programmierung sowas wie das kleine 
Einmaleins.

Autor: gonZoX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, jetzt habe ich das 'Durchlaufen' des Bytes mittels der sich immer 
verschiebenden Maske verstanden, sicherlich muss ich da noch genug 
lernen um das 'kleine Einmaleins' zu beherschen.

Gäbe es jetzt noch eine direktere Maßnahme den entsprechenden Port ohne 
die if-Abfrage zu setzen,so nach der Methode 'PB1 = 0' bzw 'PB1 = leds & 
mask' ?
(Ich habe halt in dem einen Beispiel für einen Pic gesehen, dass man da 
die Ports so direkt setzen kann)

Danke für eure Mühe,
Oliver.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich habe halt in dem einen Beispiel für einen Pic gesehen, dass man da
> die Ports so direkt setzen kann
Das sind herstellerspezifische nichtportable Compilererweiterungen...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gonZoX schrieb:

> Gäbe es jetzt noch eine direktere Maßnahme den entsprechenden Port ohne
> die if-Abfrage zu setzen,so nach der Methode 'PB1 = 0' bzw 'PB1 = leds &
> mask' ?

Man kann diese Abfrage in C etwas verstecken aber grundsätzlich ist sie 
immer da.
denn ( leds & mask ) ergibt ja nicht 1, wenn das Bit gesetzt ist.
Ausserdem: Bit setzen und Bit löschen sind prinzipiell unterschiedliche 
Operationen.

> (Ich habe halt in dem einen Beispiel für einen Pic gesehen, dass man da
> die Ports so direkt setzen kann)

Auch das mündet irgendwo immer in dieser Abfrage. Nur weil du sie nicht 
direkt siehst, heisst das ja nicht, dass sie nicht da ist.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.