Forum: Mikrocontroller und Digitale Elektronik uart Problem


von Sabine F. (Gast)


Lesenswert?

// warten bis ein byte empfangen
while(!(UCSRA&(1<<RXC)));
data=UDR;


Versuche mit Hilfe der UART ein Zeichen zu empfangen, dies funktiniert 
ohne Probleme. Nun möcht ich die empfangenen Zeichen in ein Char - Array 
speichern. Ich komme einfach nicht auf die Schleifenbedingung, welche 
abfragen sollte wann alle Zeichen empfangen sind.

while(!(UCSRA&(1<<RXC)));
for(int i = 0; ??; i++) {
    charArray[i] = UDR;
}

von Peter II (Gast)


Lesenswert?

wenn du nicht mal weiss wenn alles zeichen da sind, woher soll es dann 
der controler wissen?

von Sabine F. (Gast)


Lesenswert?

Möchte Zeichen empfangen, diese dann in ein Array speichern. Wie 
funktiniert das? benötige ich da eine spezielle Interrupt - Methode oder 
geht das auch ohne?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Sabine F. schrieb:
> Möchte Zeichen empfangen, diese dann in ein Array speichern. Wie
> funktiniert das?
So, wie du es schon geschrieben hast.

Nur musst du jetzt auch noch wissen, wann du mit dem Speichern aufhören 
und mit dem Auswerten anfangen kannst. Weißt du das?
Woher kommen die Daten? Wer sendet die? Gibt es Datenpakete mit längeren 
Pausen? Was soll danach mit den empfangenen Daten geschehen?

von Uwe (Gast)


Lesenswert?

z.B. so

do
{
while(!(UCSRA&(1<<RXC)));
charArray[i]=UDR;
}
while(charArray[i++]=='<');

Dort hast du dann das Endezeichen als '<' definiert. Bleibt aber dir 
überlassen. Du solltest besser Interupts benutzen.

z.B.

UART_RXC_INT:
if(complete) overrun=true;
charArray[i]=UDR;
if (charArray[i++]=='<') complete=true;
reti

main:
if (complete=true)
{
 send_uart(charArray,i);
 i=0;
 complete=false;
}

von Sabine F. (Gast)


Lesenswert?

Es kommen immer in etwa gleichviel Daten, sprich Zeichen herein. Ich 
möchte einen bestimmten Teil der empfangenen Daten herausfiltern und 
dann den gefilterten Text wieder senden. Die Daten werden über das 
Terminal geschickt. Keine längeren Pausen, nur Zeilenumbrüche.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Sabine F. schrieb:
> Ich möchte einen bestimmten Teil der empfangenen Daten herausfiltern
Wenn ich dir ein ausgedrucktes Blatt mit dem Datenstrom drauf hinlege, 
kannst du diese Fragen dann beantworten:
Welchen Teil willst du "herausfiltern"?
Woran erkennst du den?

von Sabine F. (Gast)


Lesenswert?

Bestimmte Schlagwörter sollten aus einem Text heraus gefiltert werden. 
Diesen Filter habe ich bereits geschrieben, er funktiniert auch ;).

Mein Problem ist nur, dass ich die Daten welche ich empfange in ein 
Array speichere, dem Filter übergebe und dann anschließend den 
gefilterten Text wieder sende.

von Karl H. (kbuchegg)


Lesenswert?

Fangen wir doch mal anders an.
Was sind das für Daten?

Wo kommen sie her?
Gibt es da drinnen so etwas wie eine Satzstruktur. Also etwas, nach 
dessen Empfang man definitiv sagen kann: Jetzt ist ein Datensatz zu 
Ende.

Wenn es sowas gibt, dann ist es leicht

  while( 1 )
  {
    Satz empfangen, bzw. zuwarten bis ein kompletter Datensatz
    vorliegt.

    in diesem Satz die entsprechenden Ersetzungen machen.

    veränderten Datensatz auf der anderen UART wieder rausschicken.
  }

Im einfachsten Fall ist es auch noch so, dass man eine bestimmte 
maximale Datensatzlänge im Vorhinein festlegen kann. Dann wird dieses 
Verfahren besonders einfach.

Voraussetzung ist es aber, dass es ein eindeutiges Kriterium gibt, nach 
dem man sagen kann: jetzt ist ein Datensatz definitiv vollständig und 
kann weiter bearbeitet werden.
Und in irgendeiner Form gibt es sowas eigentlich fast immer.

von Karl H. (kbuchegg)


Lesenswert?

> Keine längeren Pausen, nur Zeilenumbrüche.

Und ein Zeilenumbruch ist die Kennung für 'jetzt ist dieser Datensatz zu 
Ende'?

Wenn ja: na dann hast du doch da dein Kriterium!
Der Empfang läuft solange, bis ein Zeilenumbruch empfangen wird. Kommt 
der, dann wird dieser Datensatz als vollständig deklariert und der jetzt 
vollständige String der weiteren Verarbeitung zugeführt.

von Karl H. (kbuchegg)


Lesenswert?

Uwe schrieb:
> z.B. so
>
> do
> {
> while(!(UCSRA&(1<<RXC)));
> charArray[i]=UDR;
> }
> while(charArray[i++]=='<');
>
> Dort hast du dann das Endezeichen als '<' definiert. Bleibt aber dir
> überlassen.

Aber bitte nicht so.

Wenn man schon eine Funktion hat, die ein einzelnes Zeichen empfängt 
(und die hat sie, das hab ich ihr in ihrem letzten Posting nahegelegt), 
dann benutzt man diese Funktion auch um damit eine Zeile (bis zu einem 
Trennzeichen) zu empfangen. An dieser Stelle haben weder das UCSRA noch 
das UDR Register dann etwas verloren sondern werden durch einen 
Funktionsaufruf ersetzt.

Modularer Schichtaufbau ist das Um und Auf von wartbarer Software.
1
char uartRxChar()
2
{
3
  while( !(UCSRA&(1<<RXC)) )
4
    ;
5
  return UDR;
6
}
7
8
void uartRxString( char * string )
9
{
10
  uint8_t i = 0;
11
12
  do {
13
    string[i] = uartRxChar();
14
  } while( string[i++] != '\n' );
15
16
  string[i] = '\0';
17
}


Fehlerbehandlung bzw. Berücksichtigung von Arraygrößen überlass ich der 
Lernenden.

von Sabine F. (Gast)


Lesenswert?

Vielen Dank, werde mich wieder damit beschäftigen.

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.