www.mikrocontroller.net

Forum: Compiler & IDEs UART repeater


Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Forum,
benötige eine Möglichkeit die daten die über Uart0 empfängt auf ein
Steuerzeichen prüft und gleich wieder auf Uart1 weiter sendet.

Hat jemand sich mit einer solchen Aufgabe schonmal auseinander
gesetzt?
Habe irgendwie keine so richtige Idee!

Gruß Volker

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int
main(void)
{
  uint8_t c;

  init_uarts();
  for (;;) {
    c = UDR0;
    if (c == ein_Steuerzeichen) {
      /* do whatever you need */
    }
    UDR1 = c;
  }
  return 0;
}

Oder an was dachtest du?

(Obiges setzt natürlich voraus, dass die Baudraten auf beiden Seiten
gleich sind.)

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,
diese Lösung habe ich auch schon angedacht, nur wenn ich einen ganzen
Datenstrom habe kann es dann nicht passieren das ich gesendete Zeichen
während meiner Prüfroutine verlieren kann?

Danke und Gruß Volker

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hängt von deiner Prüfroutine ab.

Du willst uns aber auch nicht verraten, was du denn genau beim
Eintreffen deines Sonderzeichens vorhast, insofern ist dir
schwer wirklich zu raten.

Eine andere Variante wäre es, den Empfänger interrupten zu
lassen, in der ISR dann das empfangene Zeichen nur zu testen
und damit ein Flag zu setzen (volatile nicht vergessen!) und
sofort danach neu auszugeben.

Die main loop kann dann das Flag testen (und löschen) und
ihrererseits ihre langwierigen Operationen ausführen.

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, am Ende soll es möglich sein ein Gerät von einem PC aus über den
Repeater zu Programmiern. Um das Gerät reseten zu können muss ich
schauen wann das Programmieren beendet ist, dies erfolgt nach dem als
letztes eine Zeichenfolge z.B. 0000FFFF vom PC gesendet wurde. Das
ganze soll mit 9600 Baud funktionieren.

Habe das ganze mit Peter Fleury's uartlib mal probiert und bekomme
nach geraumer Zeit einen Buffer Overflow.
Das erklärre ich mir so, daß die Empfangsinterruptroutine ständig
beansprucht wird und somit kein senden mehr möglich ist.

Werde mich aber jetzt mal hinsetzen und mir das USART-Kapitel im Manual
genau anschauen.

Vielen Dank und Gruß Volker

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke, dass der einfache Interrupt-Weg dafür
funktionieren sollte.
volatile uint8_t rx_char, updated;

SIGNAL(SIG_UART0_RECV)
{
  uint8_t c;

  c = UDR0;
  UDR1 = c;
  rx_char = c;
  updated = 1;
}

int
main(void)
{
  uint8_t state = 0, c;

  init_uarts();
  sei();

  for (;;) {
    if (updated) {
      updated = 0;
      c = rx_char;
      switch (state) {
        case 0:
  case 1:
    if (c == 0) state++;
    else state = 0;
    break;
  case 2:
  case 3:
    if (c == 255') state++;
    else state = 0;
    if (state == 4) {
      state = 0;
      pull_external_reset();
    }
      }
    }
  }

  return 0;
}

Die Interruptverarbeitung sollte bei einem kontinuierlichen Datenstrom
von 9600 Bd selbst bei 1 MHz Takt kein Thema sein.  Die Zeichen kommen
dann ca. alle 1 ms, d.h. zwischen den Zeichen verbleiben knapp 1000
Takte für die Verarbeitung.  Die ISR selbst braucht 28 Takte (wenn ich
mich nicht verzählt habe), also 28 µs.  Die main loop braucht so 20
... 30 Takte pro Umlauf (je nach Zustand).

Eigentlich könnte man am Ende auch noch ein sleep_mode() plus einen
NOP dransetzen, um die restlichen 950 µs lang Strom zu sparen.  Der
Zustand kann sich ja ohnehin erst ändern, nachdem es einen neuen
Rx-Interrupt gab.  Den NOP braucht man, weil der meiner Erinnerung
nach nach dem Aufwachen abgearbeitet wird, bevor die Rx-ISR
angesprungen wird, diese aber setzt ja erst das "updated"-Flag.
Ggf.
nach dem Aufwachen so lange Kreise laufen, bis "updated" erschienen
ist.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Einrückungen des C-Beautifiers hier sind nicht gerade
sehr konsistent...

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Habe das ganze mit Peter Fleury's uartlib mal probiert und bekomme
>>nach geraumer Zeit einen Buffer Overflow.

Überlauf gibt es immer, sobald mehr Zeichen gesendet als empfangen
werden: bei gleicher Baudrate versteht sich.
Fügst Du vielleicht in Deinen Audgangsdatenstrom noch Zeichen ein ?
Dann gibt es nach 'geraumer Zeit' Probleme.
Oder werden eventuell LFs nach CR-LF expandiert ???

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

Bewertung
0 lesenswert
nicht lesenswert
Hier mal der erste Ansatz von mir!

@Jörg: Vielen vielen Danke, möchte dich aber nicht von deiner Arbeit
abhalten.

Gruß Volker

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde den Koloss von Peter Fleury dafür nicht benutzen.

Du hast einen Empfänger mit 9600 Bd und einen Sender mit 9600 Bd.  Es
kann dir bei ordentlicher Programmgestaltung also gar nicht passieren,
dass der Empfänger überläuft.  Warum also ...zig Tests für Dinge, die
nicht auftreten können?  (Ich gehe mal davon aus, dass du nicht noch
flow control oder sowas brauchst.)

Guck dir doch mal mein Template an.  Du solltest doch wirklich
ausreichend Reserven haben, die von dir gewünschte Aktion innerhalb
der entsprechenden Zeit auszuführen.

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,
ja du hast recht ich werde mal eine einfachere Lössung anstreben als
die von Peter. Eigentlich sollte es ohne FIFO funktionieren es kann ja
eigentlich nichts dazwischen funken wenn der Controller nur diese
Aufgabe erledigen soll. Alle anderen Aufgaben werden während dieser
Aktion eh abgeschaltet.

Gruß Volker

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

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,
habe neue Erkenntnisse gesammelt. Der im Anhang verwendete Code
funktioniert wenn ich schneller sende als empfange wunderbar. Bei
gleicher Baudrate aber nicht. Werde dann woll doch nicht um einen
Zwischenspeicher herum kommen. Denke aber das dieser dann auch wieder
überläuft?

Gruß Volker

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der im Anhang verwendete Code funktioniert wenn ich schneller sende
> als empfange wunderbar. Bei gleicher Baudrate aber nicht.

Das wundert mich, sollte man analysieren.

Ich hätte mir zwar den Test auf UDRE geklemmt, aber das sollte sich
nicht fatal auswirken.  Bei gleicher Baudrate sollte der Sender ja
wohl wieder bereit sein, zumal er ein Byte puffern kann.

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn die Bytes wirklich Start an Stop kommen, dann muß der Quarz
geringfügig schneller sein, damit nicht langsamer gesendet als
empfangen wird.

Der erste Sender sollte daher ab und zu mal Pausen machen oder mit 2
Stopbits senden.


Peter

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,
danke für deine Antwort,das mit 2 Stopbits werde ich auch mal
ausprobieren.

Gruß Volker

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jungs,
geht jetzt alles wie gewollt lag aber nicht am Wiederholer sondern an
meiner Sendeeinheit. Nun habe ich das Teil zwischen 2 PC's gehängt und
es geht ab wie die Feuerwehr am Stück 100kbyte geschickt und keinen
Fehler. Na ja aber jetzt habe ich wenigsten gelernt wie mann einen FIFO
bastelt.
Danke an Alle und Gruß Volker

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.