Forum: PC-Programmierung Die serielle Schnittstelle


von Lobert (Gast)


Lesenswert?

Hallo zusammen,

ich habe eine Frage, die hier schon desöfteren gestellt wurde und aus 
meiner Sicht für ein Windows-System nicht eindeutig erklärt wurde.
Auch im Artikelbereich dieses Forums habe ich nichts entnehmen können:

Folgendes Vorhaben:

Ich möchte ein ganz simples C-Konsolenprogramm dazu bewegen, den 
COM-Port (COM1) zu öffnen und anschließend einen String (Hallo Welt!) 
über diese Schnittstelle zu schicken.

Leider finde ich auch bei der Googlesuche nach "serial port C" keine 
wirklich hilfreiche Lösung.


Könntet ihr mir bitte für dieses (eigentlich) Miniprogramm helfen?

Vielen Dank!

von Ingo (Gast)


Lesenswert?

Bin zwar kein Programmierer, aber macht man sowas nicht mit einem 
Batch-File?

von Coder (Gast)


Lesenswert?

Schau mal bei der Knowledge Base von Microsoft vorbei...

von Matthias L. (Gast)


Lesenswert?

Wo genau liegt jetzt dein Problem?

Bei der Bedienung eines Terminalprogrammes? Oder wo?

von Lobert (Gast)


Lesenswert?

>Wo genau liegt jetzt dein Problem?

>Bei der Bedienung eines Terminalprogrammes? Oder wo?

Falscher Thread?

Mit einem Terminalprogramm schaffe ich es gerade noch. ;-)

von Dr. Sommer (Gast)


Lesenswert?

1
FILE* fd = fopen (":COM1", "a");
2
fprintf (fd, "Hallo, Welt!\n");
3
fclose (fd);

von Dr. Sommer (Gast)


Lesenswert?

Alternativ:
1
  HANDLE hFd = CreateFile ("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_NO_BUFFERING, NULL);
2
  if (hFd == INVALID_HANDLE_VALUE) {
3
    printf ("Fail\n"); exit(1);
4
  }
5
6
  DCB cs;
7
  GetCommState (hFd, &cs);
8
  cs.BaudRate = CBR_57600; // <--- Baudrate
9
  cs.fBinary = TRUE;
10
  cs.fParity = FALSE;
11
  cs.fOutxCtsFlow = FALSE;
12
  cs.fOutxDsrFlow = FALSE;
13
  cs.fDtrControl = DTR_CONTROL_DISABLE;
14
  cs.fDsrSensitivity = FALSE;
15
  cs.fOutX = cs.fInX = FALSE;
16
  cs.fErrorChar = FALSE;
17
  cs.fNull = FALSE;
18
  cs.fRtsControl = RTS_CONTROL_DISABLE;
19
  cs.ByteSize = 8;
20
  cs.Parity = NOPARITY;
21
  cs.StopBits = ONESTOPBIT; // <--- Stopbits
22
  SetCommState (hFd, &cs);
23
24
  DWORD bytesWritten;
25
  WriteFile (hFd, "Hello, World!", 13, &bytesWritten, NULL);
26
  CloseHandle (hFd);

von Lobert (Gast)


Lesenswert?

Ok, danke!

Was benötige ich an headerfile(s) dafür?

von Lobert (Gast)


Lesenswert?

Genial.

Und weshalb finde ich diesen Dreizeiler und den zweiten code in keinem 
Forum (und auch nicht hier)?


Vielen Dank @Dr. Sommer

von Dr. Turtur (Gast)


Lesenswert?

Lobert schrieb:
> Leider finde ich auch bei der Googlesuche nach "serial port C" keine
> wirklich hilfreiche Lösung.
die serielle Schnittstelle ist kein Sprachbestandteil von C, sondern ein 
Teil des Betriebssystems. Deswegen schaue in die Dokumentation deines 
Betriebssystems. Vielleicht würden die Ergebnisse auch besser werden 
wenn du die Suche auf ein Betriebssystem einschränken würdest.

für Windows schau dir das an:
http://msdn.microsoft.com/de-de/library/aa363858(v=vs.85).aspx

für Linux kannst du selber googeln oder dir hier was abschauen:
http://www.teuniz.net/RS-232/index.html
(RS-232 for Linux and Windows)

von Dr. Sommer (Gast)


Lesenswert?

Lobert schrieb:
> Was benötige ich an headerfile(s) dafür?
Für den ersten <stdio.h>, für den zweiten <windows.h> und <io.h>.

Lobert schrieb:
> Und weshalb finde ich diesen Dreizeiler und den zweiten code in keinem
> Forum (und auch nicht hier)?
Eben deswegen:
Dr. Turtur schrieb:
> die serielle Schnittstelle ist kein Sprachbestandteil von C, sondern ein
> Teil des Betriebssystems. Deswegen schaue in die Dokumentation deines
> Betriebssystems.

von Coder (Gast)


Lesenswert?

@Lobert
vermutlich nennt man das TEAM-Arbeit...

von Reinhard Kern (Gast)


Lesenswert?

Lobert schrieb:
> Und weshalb finde ich diesen Dreizeiler und den zweiten code in keinem
> Forum (und auch nicht hier)?

Insbesondere der 2. Code zeigt, dass das Windows-API für serielle 
Schnittstellen nicht ganz einfach ist, dafür kann man alles mögliche und 
unmögliche einstellen. Im Endeffekt schreibt sich daher jeder eine 
Library oder Klasse, die das weitgehend kapselt, davon findest du nicht 
eine, sondern hunderte im Internet, für alle Programmiersprachen. Leider 
hat jeder der sowas programmiert hat eine leicht andere Auffassung wie 
man sowas aufbaut, daher gibt es auch hunderte Wege, Hallo World zu 
senden.

Eine bestimmte Version hier in den FAQs einzustellen würde unweigerlich 
einen endlosen Krieg mit unschuldigen Opfern darüber auslösen, welches 
der hunderte Pakete für serielle Schnittstellen das beste ist. 
Vielleicht war da auch schon was und es wurde weggehasst. Der natürliche 
Zustand einer Internetdiskussion ist eben der Shitstorm.

Gruss Reinhard

von Lobert (Gast)


Lesenswert?

Vielen Dank erstmal für euere Antworten!

>Eine bestimmte Version hier in den FAQs einzustellen würde unweigerlich
>einen endlosen Krieg mit unschuldigen Opfern darüber auslösen, welches
>der hunderte Pakete für serielle Schnittstellen das beste ist.

Ich denke viel mehr, dass es einen Krieg auslösen wird, wenn zum x-ten 
mal die gleiche Frage gestellt wird und nicht ausreichend beantwortet 
wird.
Hier habe ich nun meine Antwort gefunden und würde mich freuen, wenn man 
sie trotzdem als eine (oder zwei) Ansätze (!) zur Lösung des Problems 
zum Ansteuern der Seriellen in die Artikel einfügen würde.
Sicherlich bin ich (besonders hier im hardwarenahen Forum) nicht der 
erste/letzte, der das noch öfter machen wird.


Nun noch eine Frage zum ersten Codeausschnitt mit fopen():

Wenn ich Daten empfangen möchte, kann ich dies mit scanf() tun?
Allerdings tut sich da die Frage auf, wie man es mit dem Timing macht, 
wenn nicht exakt im gleichen Moment ein scanf() ausgeführt wird, wenn 
die Daten von der zu sendenden Einheit gesendet werden?
Gibt es eine Art Puffer, die die Daten zwischenspeichert, damit man sie 
zeit-unkritisch "abholen" kann?


Vielen Dank!

von Blackbird (Gast)


Lesenswert?

>> Wenn ich Daten empfangen möchte, ...

Jetzt wird es interessant!
Popcorn holen.

Blackbird

von Robert L. (lrlr)


Lesenswert?

>Gibt es eine Art Puffer, die die Daten zwischenspeichert, damit man sie
>zeit-unkritisch "abholen" kann?

ja

von i-Troll (c) (Gast)


Lesenswert?

Was spricht denn gegen eine Library, sonst wird das nie was.

von Karl H. (kbuchegg)


Lesenswert?

Lobert schrieb:

> Ich denke viel mehr, dass es einen Krieg auslösen wird, wenn zum x-ten
> mal die gleiche Frage gestellt wird und nicht ausreichend beantwortet
> wird.
> Hier habe ich nun meine Antwort gefunden und würde mich freuen, wenn man
> sie trotzdem als eine (oder zwei) Ansätze (!) zur Lösung des Problems
> zum Ansteuern der Seriellen in die Artikel einfügen würde.
> Sicherlich bin ich (besonders hier im hardwarenahen Forum) nicht der
> erste/letzte, der das noch öfter machen wird.


Das Problem ist eigentlich ein ganz anderes.
Das Problem ist, dass dir (wie so vielen) einige der banalsten 
Grundlagen fehlen bzw. du nicht in der Lage bist die zu googeln.

Jeder Programmierer, dem man sagt "Windows verfolgt da den Unix-Ansatz, 
dass sich die serielle Schnittstelle wie ein File verhält", sollte sich 
damit eigentlich schon auskennen. Damit ist fast alles gesagt, und was 
nicht gesagt wurde, findet man wiederrum mit ... Google.

Microsoft hat eine umfangreiche Doku online, man muss sie nur benutzen.


> Wenn ich Daten empfangen möchte, kann ich dies mit scanf() tun?

Siehst du. Genau das mein ich.

Für dich ist die serielle Schnittstelle einfach nur ein File. scanf 
liest nicht von Files.
Wie soll man mit jemandem vernünftig sich über Programmierprobleme 
unterhalten, der noch nicht mal den Vorrat an Funktionen in Standard-C 
kennt? Geschweige denn einen Überblick über die 
Windows-Spezialfunktionen hat?

von Lobert (Gast)


Lesenswert?

Ok, viel anfangen kann man damit dennoch nicht, wenn man aktive 
Datenkommunikation wie ein FILE behandelt...
Wie kann ich denn z.B. mit dem ersten Prog.beispiel die Baudrate, die 
Paritätsbits etc. einstellen?! -Anscheinend nicht möglich.
Oder: mit welcher Baudrate wird denn das "Hallo Welt" übertragen?

@Karl Heinz Buchegger:

>Siehst du. Genau das mein ich.
Sorry, dass ich fscanf() bzw. fread() mit scanf() verwechselt habe.


>der noch nicht mal den Vorrat an Funktionen in Standard-C kennt?
Siehe oben. Ich bitte vielmals um Entschuldigung.

>Geschweige denn einen Überblick über die Windows-Spezialfunktionen hat?
Und wovon lebt nochmal so ein Forum?

Als Moderator könntest du uns ja alle an deinem fundierten Fachwissen in 
Form von Artikeln im Bezug auf "Windows-Spezialfunktionen" teilhaben 
lassen. Dann müsste ich noch nicht euch Profis belästigen.

von amateur (Gast)


Lesenswert?

Langer Rede kurzer Sinn:

Du öffnest eine Konsole und gibst dort folgendes ein:
COPY CON Testdatei.Txt
Hallo Welt!
^Z

Jetzt hast Du eine Textdatei mit Namen: Testdatei.Txt die den Text:
"Hallo Welt!" gefolgt von einem Zeilenumbruch enthält.

Jetzt kannst Du folgenden Befehl absetzen:

COPY Textdatei.Txt COM1:

Hiermit sendest Du die Datei über die serielle Schnittstelle.

Den Befehl kannst Du beliebig oft wiederholen oder in eine Batchdatei 
verpacken und aus einem Fenster starten.

von Lobert (Gast)


Lesenswert?

Sorry, aber das hat nichts mit dem zutun was ich vorhabe.

von amateur (Gast)


Lesenswert?

@Lobert

Sorry!

Die Zeile
COPY XXX CON1:
öffnet die serielle Schnittstelle und sendet die Sequenz aus XXX:
hier >>Hallo Welt!<<
über die serielle Schnittstelle.

von Karl H. (kbuchegg)


Lesenswert?

Lobert schrieb:
> Sorry, aber das hat nichts mit dem zutun was ich vorhabe.

Das nicht.
Aber es zeigt, dass 'COM1:' vom System wie eine normale Datei behandelt 
wird.
Es zeigt, dass für das Betriebssystem es keinen Unterschied gibt 
zwischen Dateien und Seriellen Schnittstellen (oder auch parallelen 
Schnittstellen). Kopieren ist Kopieren. Ob das jetzt von Datei zu Datei 
ist, oder von Datei zu Serieller Schnittstelle, oder von Konsole zu 
serieller Schnittstelle oder von Konsole auf Datei oder von Serieller 
Schnittstelle auf Konsole oder .... ist für dich als Programmierer 
uninteressant. Alles wird wie eine Datei behandelt.

Dass es natürlich noch Möglichkeiten geben muss, wie man zb auf einer 
Seriellen Schnittstelle die Übertragungsparamter einstellt, ist klar. 
Das ändert aber nichts daran, dass die COM im Datenhandling erst mal wie 
eine Datei behandelt wird.

von Karl H. (kbuchegg)


Lesenswert?

Lobert schrieb:

> Als Moderator könntest du uns ja alle an deinem fundierten Fachwissen in
> Form von Artikeln im Bezug auf "Windows-Spezialfunktionen" teilhaben
> lassen.


Gibt es alles längst da draussen im Web.

Ausserdem hab ich keine Lust nur für dich ein 2500 Seiten Tutorial zu 
schreiben. :-)

Was mich ärgert (und warum ich mich überhaupt da eingemischt habe) ist 
diese 'huhuhuhu, ich bin so arm' Attitüde. Dieses "schluchz, ich bin nun 
mal nicht mit dem Wissen geboren worden will mich aber auch nicht erst 
mal durch die ersten 20 Goggle Links durchackern. Bitte kaut mir alles 
speziell nur für mich nochmal vor" Ansinnen.
Keiner hier ist zur Welt gekommen und wusste das alles. Und ja, wir 
wissen es, weil wir uns durchgerackert haben. Zum Teil noch ohne 
Internet.

von Robert L. (lrlr)


Lesenswert?

zum thema "ich hab nix gefunden"

das ist mein 1. google treffer

http://www.robbayer.com/files/serial-win.pdf

ich finde den nicht SOO schlecht...

zum thema "ist ja alles das selbe"
bei einer Datei kann man natürlich "navigieren" (positionieren) das geht 
bei seriellen Schnittstelle natürlich nicht ganz so gut ;-)

von Coder (Gast)


Lesenswert?

TEAM Arbeit = >T<oll >e<in >a<nderer >m<acht (die) Arbeit.
Aber in der Regel bringt Eigeninitative einenm meist schneller an die 
Arbeit...

von W.S. (Gast)


Lesenswert?

Lobert schrieb:
> Als Moderator könntest du uns ja alle an deinem fundierten Fachwissen in
> Form von Artikeln im Bezug auf...

Nanana, mein Lieber!

So sieht unsereiner die Angelegenheit nicht, auch wenn ich hier zu 
diesem Kinderkram bislang nix gesagt habe. Karl-Heinz HAT die Sache 
euch bereits mehrfach erklärt, aber es ist einfach zu viel verlangt, daß 
er euch auch noch die Arbeit machen soll.

Also:
Ne serielle Schnittstelle wird generell so ähnlich behandelt wie eine 
Datei, aber nicht genauso, denn es müssen Betriebsparameter (Baudrate, 
Bitzahl, Parität...) abgefragt und eingestellt werden. Dafür gibt's 
API-Calls bei Windows.
Öffnen mit CreateFile
Params mit GetCommState und SetCommState

Zum Empfangen wird über ClearCommError und eine TCOMSTAT-Struktur die 
Anzahl der vom BS zwischengespeicherten Zeichen (sowie etwaige Fehler 
usw.) abgefragt und dann über ReadFile soviel davon wie beliebt gelesen. 
Der Rest bleibt im BS gepuffert bis zum nächsten Abholen.

So. Haben wir's endlich?
Das Ganze hätte man schon vor über 10 Jahren bei Microsoft nachlesen 
können, einschließlich Beispielen.

W.S.

von Reinhard Kern (Gast)


Lesenswert?

W.S. schrieb:
> aber es ist einfach zu viel verlangt, daß
> er euch auch noch die Arbeit machen soll.

Das ist so eine Eigenart dieser Elektronik-Foren. Bei Sport-Foren käme 
doch keiner auf die Idee, dass der Moderator für die User schwimmen 
gehen oder radfahren soll, weil sie selber zu bequem sind.

BTW, das Windows-API ist eher 20 Jahre alt.

Gruss Reinhard

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.