Forum: PC-Programmierung String empfangen


von Valdiz V. (valdiz)


Lesenswert?

Hallo!
Ich möchte ein String von der serielen Schnittstelle empfangen.
Ich nutze einen alten Borland C++ und bin selbst noch ein Anfänger.
Das Problem ist folgendes:
Ich sende mit einem µC ein String und möcht den auf dem Rechner 
empfangen um ihn
weiter zu bearbeiten. Das Empfangen selbst funktioniert, nur die 
einzelnen Zeichen
in einem String zusamenzufügen klappt nicht. Könnt ihr mir vielleicht 
sagen,wo der Fehler liegt?

Ich bedanke mich schon mal im Vorraus für eure Hilfe.




#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>

#define com 0x3F8                //Basisadresse

int main(void)
{
 int i;
 char c,c1;
 char string[10];

 outport(com+3,128);           //DLAB setzen
 outport(com,12);              //Devisor Low
 outport(com+1,0);             //Devisor High
 outport(com+3,3);             //8N1  8 Datenbit 1 Stopbib, kein Paritet


 while(c1!=27)                    //warten bis ESC
 {
   if(kbhit())
    c1=getch();
    i=0;

       while(inportb(com+5)&1)      //Zeichen empfangen?
       {
       c=inportb(com);
       string[i++]=c;
       if(c=='\r') break;
       }

       for(i=0;i<strlen(string);i++)
   {
   printf("%c",string[i]);
   }
      strcpy(string,"");

  }
 return(0);
}

von C, es ist C (Gast)


Lesenswert?

>Borland C++

>#include <stdio.h>

>printf

C++, ah ja...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Auf diese Art und Weise kann man nur unter DOS mit seriellen 
Schnittstellen kommunzieren; unter Betriebssystemen wie Windows oder 
Linux funktioniert das nicht. Statt direkte I/O-Zugriffe auf den 
Schnittstellenbaustein durchzuführen, ist der Devicetreiber des 
Betriebssystemes dafür zu verwenden.

Beispiele, wie man unter Windows mit seriellen Schnittstellen hantiert, 
finden sich hier zu Hauf, ich lege die Nutzung der Forensuche nahe.


> C++, ah ja...

Nein, das ist exakt so auch in C++ möglich. Niemand wird dazu 
gezwungen, die Stream-Operatoren zu verwenden, auch wenn es 
standardkonformer erscheinen mag. printf lässt sich selbstverständlich 
auch aus C++-Programmen heraus nutzen. Sicher, die mangelnde 
Typsicherheit lässt dies nicht ratsam erscheinen, aber das ist eine 
andere Angelegenheit.

von C, es ist C (Gast)


Lesenswert?

Wenn man freilich überhaupt kein Feature aus C++ benutzt, ist es 
unsinnig, einen C++ Compiler zu verwenden.

Bestes Beispiel:

"Hello World" in C, ausführbare Datei: 15.883 Bytes
"Hello World" in C++, ausführbare Datei: 495.695 Bytes

Beides mit GCC/MinGW auf Windows XP.

von Klaus W. (mfgkw)


Lesenswert?

... aber vermutlich nicht mit demselben Quelltext.
Wenn man einem C++-Compiler nur C-Code gibt, wird er
in aller Regel auch kein größeres Programm daraus machen.
Dein Beispiel zieht vrmtl. nur mit stdio.h bei C und
iostream bei C++?

von C, es ist C (Gast)


Lesenswert?

Ja. Soll das jetzt ein Argument dafür sein, C++ Compiler zu verwenden 
und reinen C Code zu schreiben? Irgendwie seh ich dann den Sinn nich 
drin...

von Klaus W. (mfgkw)


Lesenswert?

das ist keines dafür, aber auch keines dagegen.

Ich wollte nur den Eindruck verhindern, daß ein Programm
von einem C++-Compiler nur dadurch größer wird, daß es
ein C++-Compiler ist.

Einen reinen C-Compiler gibt es doch kaum noch; deshalb
werden letztlich C-Programme auch von C++-Compilern
übersetzt und lassen halt die neuen Sachen von C++
im Wesentlichen einfach weg.

von Karl H. (kbuchegg)


Lesenswert?

Valdiz Valdiz schrieb:

>        while(inportb(com+5)&1)      //Zeichen empfangen?
>        {
>        c=inportb(com);
>        string[i++]=c;
>        if(c=='\r') break;
>        }
>
>        for(i=0;i<strlen(string);i++)
>    {
>    printf("%c",string[i]);
>    }
>       strcpy(string,"");

Vorausgesetzt das Empfangen der einzelnen Zeichen ist korrekt, dann hast 
du den String nicht 0-terminiert
1
         while(inportb(com+5)&1)      //Zeichen empfangen?
2
         {
3
           c=inportb(com);
4
           string[i++]=c;
5
           if(c=='\r') break;
6
         }
7
8
         string[i] = '\0';
9
10
         for(i=0;i<strlen(string);i++)
11
...

... allerdings kommt mir dieses Konstrukt
         while(inportb(com+5)&1)      //Zeichen empfangen?

etwas seltsam vor. Da ich aber nicht weiß, welche Aussage 
inportb(com+5)&1 überhaupt macht, kann ich dazu wenig sagen. Seltsam 
aussehen tut es nach wie vor. Kann es sein, dass das eine Abfrage ala 
'Zeichen vorhanden' ist? In dem Fall sei dir gesagt, dass der PC um 
Zehnerpotenzen schneller ist als die serielle Schnittstelle. Aus Sicht 
des PC trifft alle heiligen Zeiten mal ein Zeichen ein. Die Abfrage ist 
daher nicht sehr sinnvoll. Die while Schleife wird in der überwiegenden 
Mehrzahl der Fälle kein einziges Mal durchlaufen.

von JojoS (Gast)


Lesenswert?

die while Schleife geht schon, nur wird meistens höchstens ein Zeichen 
pro Durchlauf empfangen. Aber in die Abfrage auf CR gehört dann die 
Ausgabe rein:
1
if (c=='/r)
2
{
3
  string[i] = 0;
4
  printf("%s", s);
5
}

oder so wie hier beschrieben:
http://www.zeiner.at/c/serialport.html
Aber solche Sachen mit Polling sind gruselig wenn die Programme grössser 
werden, die CPU rennt sich in Warteschleifen heiss. Für kleine Tools ok, 
aber wenn es was grösseres werden soll lieber nach einem RTOS gucken das 
auch die seriellen unterstützt.

von Valdiz V. (valdiz)


Lesenswert?

Hallo.

Die Zeile:
while(inportb(com+5)&1)
bedeutet:
#define com 0x3F8 - Basisadresse com1
        com+5     - Leitungsstatusregister
Beim Empfang wird das Bit 0 im Leitungs-Statusregister überprüft.
Dieses Bit mit der Wertigkeit 1 wird gesetzt, wenn ein empfangenes 
Zeichen
im Empfänger-Pufferregister vorliegt.

Der Vorschlag von JojoS funktioniert auch,
aber ich bekomme in Ausgabefenster immer nur die einzelne
Zeichen, die empfangen wurden aber nicht den String.
Das beweist, wenn ich schreibe:
printf("%c",string[2]);
Als Ausgabe kommt ein beliebiges Zeichen aus dem gesamten String
oder überhaupt gar nicht!!!

gruß   Valdiz

von Gerry E. (micky01)


Lesenswert?

Dann überleg doch mal, Valdiz:

Wenn beim Aufruf der while-Schleife zufällig ein Zeichen schon da ist,
so holst Du das ab und speicherst es auf Adresse 0. Danach bricht die 
Schleife evtl. noch nicht ab, wenn sich im Puffer der Schnittstelle noch 
weitere Zeichen befinden. Aber diesen Puffer leert Dein Code ganz rasch. 
Danach ist das Bit halt Null, und Deine Schleife zuende, was sie auch 
wäre, wenn anfangs noch gar kein Zeichen empfangen wurde.

Das mit dem while ist nicht verkehrt (nämlich um den Puffer auf einen 
Schlag leerzumachen), nur braucht es drumherum noch eine weitere 
Schleife, und in der bringst Du die Abbruchbedingung unter.

Ich sehe gerade die hast Du ja; Entschuldigung.

Dann zieh das i=0; vor das erste while.

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.