Problem bei UART einlesen

OP #4465381
Lesenswert?

Hallo,

ich empfange aktuell über die serielle Schnittstelle Werte.
Wenn ich das Programm so schreibe, das der Programmdurchlauf blockiert 
wird vom Lesebefehl, d.h. ich warte bis neue Daten empfangen wurde, dann 
funktioniert alles.

Verwende ich aber jetzt den Befehl das ich nur die Daten einlese wenn 
neue Daten vorhanden sind:
1
if ( (UCSR0A & (1<<RXC0)) ){
2
   ......

Empfange ich die Werte nicht mehr korrekt. Woran kann das liegen?
#4465391
Lesenswert?

A. R. schrieb:
> Hallo,
>
> ich empfange aktuell über die serielle Schnittstelle Werte.
> Wenn ich das Programm so schreibe, das der Programmdurchlauf blockiert
> wird vom Lesebefehl,
Zeig mal DEN Code. Inwiefern unterscheidet sich das blockieren vom 
aktuellen Ansatz? Die Abfrage sollte gleich bleiben. Lediglich eine 
while Schleife sollte hinzugekommen sein.

Und poste mal den ganzen Code.
OP #4465406
Lesenswert?

Hier das Programm in kurzer zusammenfassung:

Das funktioniert:
1
int main(void){
2

3
  uart_init();
4

5
while(1){
6
....
7
  a = uart_empfange();  //Low-byte
8
  b = uart_empfange();  //High-byte
9
  c = a+ (b<<8);
10
  ... 
11
  itoa(c,buffer,10);
12
  lcd_string(buffer);
13
  ....
14
 }
15
}



Das funktioniert nicht:
1
int main(void){
2

3
  uart_init();
4

5
while(1){
6
....
7
if ( (UCSR0A & (1<<RXC0)) ){
8
  a = uart_empfange();  //Low-byte
9
  b = uart_empfange();  //High-byte
10
  c = a+ (b<<8);
11
   
12
  ... 
13
  itoa(c,buffer,10);
14
  lcd_string(buffer);
15
  ....
16
  }
17
 }
18
}
OP #4465581
Lesenswert?

Ok danke schonmal für eure Hilfen.
Werde mich mit dem Interrupt mal beschäftigen.

Jetzt wäre aber zum Verständnis meine Frage:
Warum bekomm ich die Daten denn falsch rein wenn ich diese Abfrage mit 
drin habe? Ist das ein Timing Problem? Und warum sollte das beim 
Interrupt anders sein?
Gast #4465782
Lesenswert?

Flip B. schrieb:
> uart_empfange anspringen, bis deine 2 bytes empfangen wurden.

Die können aber genausogut in falscher Reihenfolge gelesen werden, b vor 
a. Da fehlt jede Synchronisation. Beim blocckierenden Lesen auch, aber 
da fällt das weniger auf, wenn der Sender nach dem Empfänger startet.

Georg
OP #4466000
Lesenswert?

Wenn ich die IF bedinungen nutze,
dann springt er rein wartet aber auf neue Werte im Puffer, wenn ich 
erneut werte sende, also seriell an den µC, dann liest er den letzten 
Wert ein und der Rest ist irgenndetwas komisches. Und danach springt er 
immer in die IF rein weil immer irgendwas im Puffer steht.

1
uint8_t uart_empfange (void){
2
  while (!(UCSR0A & (1<<RXC0)));
3
  return UDR0;
4
}
#4466028
Lesenswert?

so was?
1
state = EMPFANGE_A;
2
while(1)
3
{
4
  // check UART
5
  if (UCSR0A & (1<<RXC0))
6
  {
7
    if (state == EMPFANGE_A)
8
    {
9
      a = UDR0;
10
      state = EMPFANGE_B;
11
    } else if (state == EMPFANGE_B) {
12
      b = UDR0;
13

14
      // Tue was mit a und b
15

16
      state = EMPFANGE_A;
17
    }  else {
18
      error(WRONG_STATE);
19
      state = EMPFANGE_A;
20
    }
21
  }
22

23
  //
24
  // do other stuff here
25
  //
26
}
Gast #4466112
Lesenswert?

Eric B. schrieb:
> a = UDR0;
>       state = EMPFANGE_B;

Da bist du auf der richtigen Spur, aber woher weisst du was a und was b 
ist?

Ich sehe da 2 Möglichkeiten:

1. Das MSB entscheidet, 0=a, 1=b. Aber dann bleiben bloss 14 Bit an 
Daten.

2. Nach a und b kommt eine deutlich längere Pause als dazwischen. Aber 
dann musst du diese Zeit messen und auswerten, du brauchst also 
mindestens ein Timeout, das zwischen a,b und a,b anspricht.

Georg
OP #4466255
Lesenswert?

Also di funktion das ich zweimal den uart lese und anschließend 
High-Low-Byte zusammen setzte funktioniert ja an sich.

Was mich gerade etwas irretiert oder noch unklar ist, warum funktioniert 
das uart_empfange(); nicht mehr wenn ich es nur dann mache, wenn neue 
Daten im Eingangspuffer steht?

Georg schrieb ja, das die If-Anweisung ja nur aussgat, das 1-byte 
vorhanden ist. Und ich frage erst dann ab. D.h. ich lese ja wenn ich 
zweimal Byte ein, wenn aber jetzt nur noch ein Byte vorhanden ist wartet 
das Program ja. und beim nächsten senden von zwei Byte erhält läuft das 
Programm weiter und springt im nächsten durchlauf direkt wieder in die 
IF-Anweisung.

Bedeuted doch eigentlich, das durch die IF-Anweisung mir vermutlich das 
erste Byte verloren geht oder?
#4469304
Lesenswert?

Georg schrieb:
> Da bist du auf der richtigen Spur, aber woher weisst du was a und was b
> ist?

Ist mir schon klar. Das Problem bin ich auch gar nicht angegangen.

A. R. schrieb:
> Was mich gerade etwas irretiert oder noch unklar ist, warum funktioniert
> das uart_empfange(); nicht mehr wenn ich es nur dann mache, wenn neue
> Daten im Eingangspuffer steht?

Das können wir nur beantworten wenn du den Code von /uart_empfange/() 
zeigst.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren