www.mikrocontroller.net

Forum: PC-Programmierung String empfangen


Autor: Valdiz Valdiz (valdiz)
Datum:

Bewertung
0 lesenswert
nicht 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);
}

Autor: C, es ist C (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Borland C++

>#include <stdio.h>

>printf

C++, ah ja...

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: C, es ist C (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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++?

Autor: C, es ist C (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
         while(inportb(com+5)&1)      //Zeichen empfangen?
         {
           c=inportb(com);
           string[i++]=c;
           if(c=='\r') break;
         }

         string[i] = '\0';

         for(i=0;i<strlen(string);i++)
...

... 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.

Autor: JojoS (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
if (c=='/r)
{
  string[i] = 0;
  printf("%s", s);
}

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.

Autor: Valdiz Valdiz (valdiz)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gerry E. (micky01)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.