serielle Empfangsroutine - so OK?

rbr50
 
Avatar
 
Subject:

serielle Empfangsroutine - so OK?

 · 
Posted: 13.03.2011 - 20:09  ·  #1
Hallo,

vielleicht findet jemand Zeit, sich dieses Codefragemnt anzuschauen:

Code

  bACKReceived:= False;        //Flag für ACK von PC löschen
  SetSysTimer(TimerTOut, 250); //Kein ACK von PC? Dann Timeout nach 250xSystick
  repeat
    SetSysTimer(TimerWait, 8);  //~80ms auf Antwort von PC warten
    SerOutBlock_P(@SendBuffer[0], 9);    //Referenz OK an PC senden
    inc(SendACKCount);         //Sendungen mitzaehlen
    repeat
      if serstat then         //PC hat gesendet
        SerialMonitor;       //Input verarbeiten, hier wird auch bACKReceived gesetzt
      endif;
    until isSysTimerZero(TimerWait);  //80ms um, ACK empfangen? Sonst weiter bis TimeOut
  until bACKReceived or isSysTimerZero(TimerTOut);
  SysLEDflashMsg(0, SendACKCount, 5);


Es geht darum, Daten an den PC zu senden und auf eine Bestätigung des PC zu warten.
Die Funktionen SerInpBlock_TO habe ich gesehen, glaube aber nicht, dass ich diese für meine Empfangsroutine "SerialMonitor" nutzen kann. Siehe Codefragment unten.

Grundsätzlich funktioniert Senden und Empfang, wie ich es jetzt gelöst habe. Ich habe aber den Verdacht, das ich alles (mal wieder) zu kompliziert mache?

Vielen Dank für Eure Zeit und eine schöne Woche!

Rolf

Code

procedure  SerialMonitor;
begin

  if CommFlag = StartChar then   //Vorher schon gültiges Startzeichen empfangen?
    inc(CommPointer);            // dann im Buffer ablegen
    RecvBuffer[CommPointer]:= SerInp;
    if (CommPointer = BUFFMAX) then   //Bufferende erreicht?
      if RecvBuffer[CommPointer] = LASTCHAR  then  // und auch letztes Zeichen=Endezeichen?
        CommFlag:= Received;  //Ja, Empfangsflag setzen
      else                   //Buffer voll und kein Endezeichen
        CommFlag:= NoChar;   //wieder von vorn
      endif; // if RecvBuffer[CommPointer] = SYNC
    endif;  //if (CommPointer = BUFFMAX) then
  else
    Case Serinp of
      SYNC :                     //sync empfangen
             CommPointer:= 0;    //Bufferzeiger auf Anfang Buffer
             CommFlag:= StartChar;
             RecvBuffer[CommPointer]:= SYNC;
           |

    endcase;
  endif;  //if CommFlag = StartChar then

  if CommFlag = Received then
    (*
 +-----+-----+-----+-----+-----+-----+-----+-----+-----+
 |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |
 +-----+-----+-----+-----+-----+-----+-----+-----+-----+
 |snyc |cmd  |dat1 |dat2 |dat3 |dat4 |crcL |crcH | stp |
 +-----+-----+-----+-----+-----+-----+-----+-----+-----+

 CRC16 über Byte1 bis Byte4
 CMD von 1..125
 Bit7 von CMD = 1 = ACK
 *)

    CRCstreamInit ($0810);
    Crc16w := CRCcheck(@RecvBuffer[1], 5);
    crcPCLow:= RecvBuffer[6];
    crcPCHigh:= RecvBuffer[7];
    if CrcPC = Crc16w then  //die vom PC gesendete CRC ist gleich der errechneten
      cmd:= RecvBuffer[1];  //also ist das Kommando gültig
      if cmd < 127 then  //es wurde ein Befehl vom PC empfangen
        RecvBuffer[1]:= RecvBuffer[1] or %10000000; //Bit7 auf 1, stecht für ACK
        CRCstreamInit ($0810);
        Crc16w := CRCcheck(@RecvBuffer[1], 5); //CRC16 über Byte1 bis Byte4
        RecvBuffer[6]:= lo(Crc16w);
        RecvBuffer[7]:= hi(Crc16w);
        SerOutBlock_P(@RecvBuffer[0], 9);    //ACK an PC senden
        ProcessCommand(cmd);                 //Befehl ausführen
      else  //es wurde ein ACK von PC empfangen
        ProcessACK(cmd);
      endif;
    endif;
    CommFlag:= NoChar;
    CommPointer:= 0;
  endif;
end;
Torsten
Benutzer
Avatar
Gender:
Location: Bad Doberan
Age: 59
Posts: 62
Registered: 11 / 2005
Subject:

Re: serielle Empfangsroutine - so OK?

 · 
Posted: 14.03.2011 - 08:33  ·  #2
Hallo Rolf,

ich habe nur ein Anmerkung zum Umgang mit der Checksumme. Um zu prüfen ob die Daten korrekt empfangen wurden kann man einfach die Checksumme in die Prüfung mit einbeziehen, dass Ergebnis muss dann Null sein. Wenn dies so ist, dann wurden die Daten ohne Fehler übertragen. Ich bin mir nicht ganz sicher ob die Reihenfolge von crcL und crcH bei dir dazu richtig ist, einfach mal probieren, sonst tauschen.
Auf der anderen Seite führen viele Wege nach Rom. :-)

Torsten
rbr50
 
Avatar
 
Subject:

Re: serielle Empfangsroutine - so OK?

 · 
Posted: 14.03.2011 - 21:09  ·  #3
Hallo Torsten,

Quote

Um zu prüfen ob die Daten korrekt empfangen wurden kann man einfach die Checksumme in die Prüfung mit einbeziehen, dass Ergebnis muss dann Null sein


coole Sache! Hatte ich nicht gewusst, danke für den Hinweis. Habe auch gleich ganz fleißig bei Wikipedia nachgelesen! :-)

Viele grüße,

Rolf
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   64   78 · Page-Gen-Time: 0.023347s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI