Forum: Mikrocontroller und Digitale Elektronik UART DatenProtokoll


von Stefan (Gast)


Lesenswert?

Hallo,

ich bin derzeit am Basteln einer kleinen UART Kommunikationsroutine.
Ich weiß das Thema gibts schon und ich habe auch die Suchfunktion 
bemüht, allerdings hab ich keinen Ansatz gefunden.

Ich nutze zum Senden der Daten von PC zu µC folgendes Protokoll:
STX|CMD|AL|A0|..|An|ETX
wobei AL die Länge des Attributs ist und A0..An die Attributdaten.

Gehandlet werden die Daten in einem struct das ich CtrlInterface genannt 
hab. Darin befindet sich ein State und ein FIFO Buffer für die 
empfangenen Daten.
In der UART ISR setze ich mit STX/ETX den State auf "RECEIVE"/"COMPLETE" 
daneben gibt es noch den "IDLE" state in dem auf den Beginn einer 
Übertragung gewartet wird (wird gesetzt wenn ein Kommando abgearbeitet 
wurde).
Die Daten möchte ich eigentlich binär übertragen und nicht in ASCII. 
Durch die State Machine hab ich keine Probleme mit dem Wert 0x02 (STX). 
0x03 (ETX) bereitet mir jedoch Probleme, da während des Empfangens einer 
Übertragung keine Daten mit dem Wert 0x03 gesendet werden können, sonst 
wird das natürlich als Ende der Übertragung angesehen.
1
 
2
ISR(USART_RX_vect)
3
{
4
  uint8_t uartRX = UDR0;
5
  switch(CtrlInterface.state)
6
  {
7
    case IDLE:
8
      // waiting for start of transmission
9
      if(uartRX == STX)
10
        CtrlInterface.state = RECEIVE;
11
      break;
12
    case COMPLETE:
13
      // trunk data
14
      break;
15
    case RECEIVE:
16
      // receiving data
17
      if(uartRX == ETX)
18
        CtrlInterface.state = COMPLETE;
19
      else
20
        fifo_push(CtrlInterface.pUSART_RX_Buf, uartRX);
21
  }  
22
}

Eine Möglichkeit wäre natürlich das Zählen der empfangenen Attribut 
Character. Das würde aber zu einem zusätzlichen Member in der 
CtrlInterface Struktur führen und etwas mehr Arbeit in der ISR 
verlangen. STX und ETX als Beginn und Ende einer Übertragung zu nutzen 
erscheint mir daher sauberer, mir fällt nur nicht ein wie ich das oben 
genannte Problem lösten könnte.
Nutzt man ETX nur wenn man Daten als ASCII Zeichen überträgt? Mir fällt 
momentan leider kein anderer Weg ein...

Viele Grüße
Stefan

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


Lesenswert?

Stefan schrieb:
> Die Daten möchte ich eigentlich binär übertragen und nicht in ASCII.
> Durch die State Machine hab ich keine Probleme mit dem Wert 0x02 (STX).
> 0x03 (ETX) bereitet mir jedoch Probleme, da während des Empfangens einer
> Übertragung keine Daten mit dem Wert 0x03 gesendet werden können, sonst
> wird das natürlich als Ende der Übertragung angesehen.
STX und ETX sind ASCII-Zeichen. Aus diesem Grund müssen bei einer mit 
STX-ETX gesteuerten Übertragung für die Nutzdaten auch ASCII-Zeichen 
verwendet werden (und zwar andere). Oder du mußt dir ein anderes 
Protokoll ausdenken. Einfach nur das schönste aus beiden Welten zu 
nehmen (ASCII und Binär) das geht nicht so ohne weiteres... :-o

von Stefan (Gast)


Lesenswert?

In Ordnung,

hätte ja sein können das man das noch irgendwie drehen kann :).
Danke für den Hinweis.. dann werde ich wohl doch ASCII zum Übertragen 
nutzen.

Viele Grüße
Stefan

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:

> verlangen. STX und ETX als Beginn und Ende einer Übertragung zu nutzen
> erscheint mir daher sauberer, mir fällt nur nicht ein wie ich das oben
> genannte Problem lösten könnte.
> Nutzt man ETX nur wenn man Daten als ASCII Zeichen überträgt? Mir fällt
> momentan leider kein anderer Weg ein...

ETX darf dann in den Daten nicht vorkommen.
Kommt es trotzdem vor, dann darf man 0x03 eben nicht übertragen, sondern 
ein Ersatzzeichen dafür.

Du könntest zb definieren, das 0x03 nicht als 0x03 übertragen wird, 
sondern als 0xFF 0xFD. Damit der Empfänger das von einem tatsächlichen 
0xFF in den Daten unterscheiden kann, wird 0xFF als 0xFF 0xFE 
übertragen.

bekommt der Empfänger das zu sehen

   0x80 0xFF 0xFE 0x50

dann lauten die Daten, die der Sender übermitteln will 0x80 0xFF 0x50

bekommt der Empfänger zu sehen

  0x80 0xFF 0xFD 0x50

dann wollte der Sender eigentlich übertragen: 0x80 0x03 0x50

Da du eine schöne Statemachine hast, ist es beim Empfänger auch nicht 
weiter schwer, diese Rücksubstitution zu machen.

von Heinzi (Gast)


Lesenswert?

Zählen dürfte der bei weitem schmerzloseste Ansatz sein,
das Prob zu lösen. Du überträgst ja schon die Länge, warum
dann nicht nutzen. Deine STX und ETX sind prinzipiell sowieso schon 
redundant.
Ansonsten wäre das Prob auch über escape chars zu lösen (z.b.
ETX doppelt zu übertragen, wenn es sich um ein ETX in den Daten handelt
und auf der Empfangsseite wieder entfernen).

h.

von Stefan (Gast)


Lesenswert?

Vielen Dank für Eure Anregungen.

Ich werde mal schaun wie groß der Aufwand mit ASCII Zeichen wird, hat 
vielleicht auch einen kleinen Vorteil zum Debuggen übers Hyperterminal. 
Ansonsten ist das mit den Ersatzzeichen eine interessante Idee!

Viele Grüße
Stefan

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.