ATtiny2313 über RS232 steuern - Problem mit if/else

OP #2679088
Hallo,

ich möchte ein Programm für den ATtiny2313 schreiben, damit dieser 
unterschiedliche Ports schaltet, abhängig von den Zeichen die er per 
RS232 vom PC bekommt.
Das empfangen der Daten funktioniert soweit. Der Controller bekommt 
immer nur ein Byte geschickt.

#include <avr/io.h>

#ifndef F_CPU
#define F_CPU 1000000UL //1MHZ kann eigentlich 8 Mhz aber CKDIV8 ist 
noch gesetzt
#endif

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

void InitUART(void);
unsigned char ReceiveByte(void);


int main (void)
{
DDRD |= (1<<PORTD4) | (1<<PORTD5) | (1<<PORTD6);//  LED 1,2,3 als 
Ausgang

        InitUART();
                while(1)
                {
                        if(ReceiveByte() == 0b00000101)  //Senden mit 
300 Baud nötig (300,N,8,1)
                        {
                          PORTD = PIND^(1<<PORTD4); //Zustand LED 1 
wechseln
                        }

            if(ReceiveByte() == 0b01100010)
                        {
                            PORTD = PIND^(1<<PORTD5);  //Zustand LED 2 
wechseln
                        }

              else
              {
                PORTD |= (1<<PORTD6);    // Blinken LED 3 wenn sonstiges 
empfangen wird
                _delay_ms(20);
                PORTD &= ~(1<<PORTD6);
                _delay_ms(20);
                PORTD |= (1<<PORTD6);
                _delay_ms(20);
                PORTD &= ~(1<<PORTD6);
                _delay_ms(20);
                PORTD |= (1<<PORTD6);
                _delay_ms(20);
                PORTD &= ~(1<<PORTD6);
              }
            }
}


void InitUART(void)
{
        UBRRL = 0b11001111;
        UBRRH = 0b00000000;
        UCSRB = (1 << RXEN) | (1 << TXEN);
        UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
}

unsigned char ReceiveByte(void)
{
        while (!(UCSRA & (1 << RXC)));
        return UDR;
}

Mit der if/else Anweisung wollte ich die empfangenen Zeichen zum 
Schalten der Ausgänge selektieren. (Im Code den Wert 5 um LED1 zu 
schalten und 98 für LED2.)
Wenn ich jetzt das Signal sende um LED 1 zu Schalten, wechselt diese 
auch den Zustand. Sende ich den Befehl erneut, wird dieser jedoch als 
else-Fall erkannt (LED3). Beim dritten Senden des Befehls wechselt die 
LED1 wieder den Zustand. Beim vierten Senden wird es wieder ein 
else-Fall.
Gleiches passiert bei LED2.
Sende ich die Befehle für LED1 und 2 abwechselnd klappt dies. Sprich 
LED1 an - LED2 an - LED1 aus -LED2 aus -... (an aus versetzt 
funktioniert auch)
Schicke ich nach dem Reset des Controllers den Befehl für LED1, wechselt 
diese und macht dann Probleme. Sende ich nach dem Reset den Befehl für 
LED2, wird dies gleich als else-Fall bewertet. Erst ein erneutes Senden 
des Befehls wechselt den Zustand von LED2.
Als die Anweisung nur aus einem if und einem else bestand funktionierte 
alles problemlos. Mit dem Einfügen des zweiten if kam das Problem.
Auch nachdem ich mich durch einige Foreneinträge zu if/else und 
switch/case gearbeitet habe, weis ich nicht wo der Fehler liegt.

Was habe ich übersehen?
Vielen Dank

Andreas
Gast #2679109
Zumindest ein Fehler liegt darin, dass du für jedes if ReceiveByte() 
erneut aufrufst. Du läufst also in das erste if hinein und wartest dort 
auf ein Byte. Ist das Byte 5, wird die LED 1 geschalten. Dann läufst du 
in das zweite if hinein und wartest wieder. Da das Byte nicht den Wert 
0x62 hat, wird der else-Zweig ausgeführt.
Du möchtest aber ein Byte lesen, und dann sehen welcher Fall passt:
1
unsigned char c;
2
while(1)
3
{
4
  c = ReceiveByte();
5
  if(c == ...)
6
    ...
7
  if(c == ...)
8
    ...
9
}
Oder etwas schöner (wie ich finde) mit switch:
1
while(1)
2
{
3
  switch(ReceiveByte()) {
4
  case 0x5:
5
    ...
6
    break;
7
  case 0x62:
8
    ...
9
    break;
10
  default:
11
    ...
12
  }
13
}
OP #2679412
Stimmt natürlich. Ich habe ReceiveByte()als Variable behandelt. Aber mit 
ReceiveByte() rufe ich jedes mal das Unterprogramm auf, dass dann auf 
ein Zeichen wartet.
Sowohl mit if/else als auch mit switch funktioniert es jetzt.
Danke für den Hinweis.

Anbei der funktionierende Quelltext für Interessenten.
Angehängte Dateien:

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.