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); }
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.
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.
... 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++?
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...
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.
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.
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.