Forum: PC-Programmierung RS232 Basics


von Chris (Gast)


Lesenswert?

Hallo Leute,
folgendes Problem/Aufgabe:
Ich habe eine Elektronik-Hardware aufgebaut, die mit einer RS232
Schnittstelle ausgestattet ist. Nun kann ich auch mit dieser
kommunizieren über bestehende Programme
hyperterminal,CodeVision(Terminal), etc.
               Wo ist nun das Problem?
Ich möchte jedoch eine eigene Software schreiben in C (!!!) und
wirklich nur in C, mit der ich mit meiner Hardware kommunizieren kann.
Hierzu fehlt mir jedoch die Ansteuerung des Com-Ports (lesen,
schreiben). Ich habe mich auch schon etwas umgeschaut hier im Forum und
habe auch Libraries für C++ gefunden. Aber wie gesagt würde ich gerne
rein in C-Programmieren (auf einer Windows-Maschine --- kein Linux).
Ich hoffe, ich langweile euch nicht, da solche Anfragen schon
dutzendweise gestellt wurden.
Wer trotzdem einen heißen Tipp für mich hat, darf diesen beruhigt
posten.
Vielen Dank schon im Voraus für eure Hilfe.

Gruß Chris

von Kurzschluß (Gast)


Lesenswert?

Also bei Linux gehts ganz leicht, da kann man direkt auf die gewünschten
Ports zugreifen (als root), aber bei Windoof....?

von Alex (Gast)


Lesenswert?

Welchem Compiler verwendest du?

Falls VC kannst du die WinAPI Funktionen nutzen, ist alles im MSDN zu
finden (liegt der Software bei).

Wird aber ein kleiner Krampf werden, VC++ mit ner Wrapper-Klasse bringt
die Sache in einem Bruchteil der Zeit zum laufen.

von Tobi (Gast)


Lesenswert?

Sind die CreateFile etc Befehle nicht auch mit reinem C benutzbar? Damit
ginge alles ganz einfach

von Rufus, das dicke Ei (Gast)


Lesenswert?

"Also bei Linux gehts ganz leicht, da kann man direkt auf die
gewünschten Ports zugreifen (als root), aber bei Windoof....?"

1. Bei Linux kann nicht nur root auf Schnittstellen zugreifen, das
hängt allein von den Zugriffsrechten ab. Wäre ja auch sonst
schwachsinnig.

2. Geht natürlich bei Windoof auch.


"Falls VC kannst du die WinAPI Funktionen nutzen, ist alles im MSDN
zu
finden (liegt der Software bei)."

WinAPI kann man auch mit anderen Compilern nutzen. Wo soll das Problem
sein?


"Wird aber ein kleiner Krampf werden, VC++ mit ner Wrapper-Klasse
bringt die Sache in einem Bruchteil der Zeit zum laufen."

Häh, wieso das denn?
RS232 sind ein paar Zeilen Code, nichts Aufregendes. Selbst asynchron
ist das nix Wildes.

von Alex (Gast)


Lesenswert?

Weil es ein paar mehr Zeilen werden und eine fertige Klasse kompakter zu
handhaben ist ...

von Schoaschi (Gast)


Lesenswert?

Ich verwende immer CVI und da sind es genau 4 zeilen die zur
kommunikation benötigt werde:
1.) COM-Port öffnen:
OpenComConfig (int COMPort, char deviceName[], long baudRate, int
parity, int dataBits, int stopBits, int inputQueueSize, int
outputQueueSize);

oder
OpenCom (int COMPort, char deviceName[]); //Aber hier kannst du die
Einstellungen(Baudrate und Co) nicht vornehmen.

2.) Daten hinausschreiben:
ComWrt (int COMPort, char buffer[], int count);

3.) Daten einlesen:
ComWrt (int COMPort, char buffer[], int count);

4.) COM-Port schliessen:
CloseCom (int COMPort);

PS: Google ist dein Freund;-) oder geh einfach auf die HP der Firma von
der du den Compailer hast und such nach Sample Codes

von Andreas (Gast)


Lesenswert?

"PS: Google ist dein Freund;-) oder geh einfach auf die HP der Firma
von der du den Compailer hast und such nach Sample Codes"

oder geh hier ins Code-forum und such da.
Da gibt es bereits fertige Klassen (Windows) dafür. :)

von Chris (Gast)


Lesenswert?

Sers Leute,
ich benutze den freeware DEV-C++ compiler von bloodshed.
Gruß Chris

von Rufus T. Firefly (Gast)


Lesenswert?

Die im Internet verfügbare MSDN dokumentiert die zur Ansteuerung von
seriellen Schnittstellen Win32-API-Funktionen, die sich mit jedem
C-Compiler verwenden lassen müssten, der Win32-Executables erzeugen
kann.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/communications_functions.asp


Eine Anleitung mit Kommentaren findet sich hier:
http://www.luxoncreations.com/tutorials/serial_read/

Das ist zwar auf den ersten Blick C++, das wird dort aber nur in Form
von I/O-Streams für irgendwelche Ausgaben verwendet; es sollte daher
nicht zu schwer sein, das in reines C zu übersetzen.

von Blackbird (Gast)


Angehängte Dateien:

Lesenswert?

So geht es in C (ist aber nur eine Beispiel von vielen ...):
siehe Anhang

WriteFile kann man von überall aus aufrufen.

Blackbird

von Schoaschi (Gast)


Lesenswert?

Ich muss schon sagen... sehr übersichtlich und genau das richtige um
damit anzufangen (ich hoffe man hört meinen Sarkasmus). Und ist das
nicht in C++ geschrieben?!?

von Blackbird (Gast)


Lesenswert?

Es ist strukturiertes C, C++ -Elemente wie new, delete, class, private,
... fehlen.
Nicht übersichtlich genug? Nun ja, ich könnte die einzelnen Funktionen
noch ein wenig aufdröseln, verpacken und in eine DLL schieben. Dann
würden solch einfache Aufrufe wie OpenCom(...), RTS(), CTS(),
CloseCom(), ReadCom(...), WriteCom(...), usw. rauskommen.

Dann kann man aber gleich die port.dll oder die rsapi.dll und den
zugehörigen header port.h nehmen.
Der Code wird dann zwar übersichtlicher, aber an der
Grundfunktionalität ändert sich nichts. Einfacher hats BillyBoy nun mal
nicht vorgesehen.

Einen eigenen Thread/process aufsetzen zum Lesen des COM-Ports wird man
immer machen müssen, wenn man nicht pollen will.

Mein Beispiel ist schon vereinfacht, die Fehlerbehandlung ist nämlich
nur rudimentär.

@Schoaschi, was hast Du denn erwartet?

Blackbird

von Rolf F. (Gast)


Lesenswert?

Es gibt das serial Programming Howto:

www.ibiblio.org/pub/Linux/docs/HOWTO/
other-formats/pdf/Serial-Programming-HOWTO.pdf

Außer ANSI-C und etwas Posix braucht man sonst nix.
Ein Programm muß einiges mit der Schnittstelle machen: Parameter setzen
(Baudrate, Parität etc.), exklusiv öffnen (weil sonst mehrere Programme
sich die Daten gegenseitig wegnehmen bzw. zusammenstückeln), zuerst die
Puffer leeren und vor allem mit Select auslesen, da Polling nie genommen
werden sollte.

von SChoasch (Gast)


Lesenswert?

Man muss aber nicht immer Poolen, auch wenn man keinen eigenen Thread
erstellen will. es gibt sogenannte eventCallbacks... sprich interrupts
;-) die sind da recht praktisch :-)

von Tobi (Gast)


Lesenswert?

Gibts in der WinAPI keine Idle-Events? Sowas lässt sich auch immer gut
nutzen

von Chris (Gast)


Lesenswert?

> Gibts in der WinAPI keine Idle-Events? Sowas lässt sich auch immer
> gut nutzen

Schon, man muss sie nur implementieren (direkt im Sinne von "diese
Nachricht kommt wenn keine Nachrichten anstehen" gibts die allerdings
nicht).

Man muss dafür GetMessage (in der Messageloop) durch PeekMessage
ersetzen und die Schleife entsprechend anpassen. Wenn keine Nachrichten
anstehen, wartet Peekmessage nicht wie GetMessage, sondern kehrt direkt
zurück.
Das führt aber zwangsläufig dazu, dass das Programm 100% CPU-Auslastung
bekommt, da es zu keiner Zeit Rechenzeit freiwillig abgibt. Wenn andere
Prozesse auf gleicher oder niedrigerer Priorität laufen, werden die
mehr oder weniger stark ausgebremst.

von Blackbird (Gast)


Lesenswert?

Wozu?

"WaitForSingleObject(...)" und "WaitForMultipleObject(...)" machen
das doch viel besser ohne die Windows message loop zu bemühen (die 'eh
schon genug zu tun hat). Das Programm wartet an genau der Stelle, bis
ein vorher definierter Event eintritt und macht dann weiter. Nur sollte
es eben NICHT das Hauptprogramm sein (weil das ja dann steht), sondern
ein eigener Thread. Alternativ kann man den Thread auch ohne die beiden
Funktionen betreiben, aber dann im "polling" und nicht im
"Interrupt" -Modus.

Die Kommentare im Beispiel-SourceCode "ByteTransmission.cpp" sind
doch verständlich, oder nicht?

Die "while()"-Schleife kommt in einen eigenen Thread, der vom
Hauptprogramm aus gestartet wird - fertig.

Die Endung ".cpp" statt ".c" habe ich nur gewählt, weil ich den
CPP-Compiler benutze - wegen der besseren Typprüfung und der
Zeilenkommentare "//".

Blackbird
Wenn es zum Verständnis der Bedienung der seriellen Schnittstelle unter
32bit-Windows beiträgt, so kann ich noch ein paar Beispiele posten. Mit
eigenem Thread, Daten-Queue, Pattern-Generierung über die serielle
Schnittstelle, Zeitmessung auf 20 Mikrosekunden genau und noch mehr
Spielchen.

von Tobi (Gast)


Lesenswert?

"Zeitmessung auf 20 Mikrosekunden genau und noch mehr Spielchen."

Wärst du so nett, dieses Beispiel zu posten?

Hab ein sehr gutes Beispiel zu dem Thema gefunden, von MS selber. Lesen
lohnt sich:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfiles/html/msdn_serial.asp

von Blackbird (Gast)


Angehängte Dateien:

Lesenswert?

Ist aus mehreren source und header files zusammenkopiert. printf habe
ich nur als Beispiel einer möglichen "Daten-Ausgabe" eingefügt. In
einem Windows-Programm ist hier die Ausgabe in ein Editfenster,
Static-Control, Liste oder sonstwas besser.

Zum Aufbau/Ablauf:
main erstellt einen Thread, der nur die Aufgabe hat, Ereignisse
auszugeben/zu bearbeiten/speichern etc. (was eben länger dauern kann).
Damit nichts verloren geht, hat dieser Thread (Monitorthread) eine
Message-Queue, in der alle Nachnichten gespeichert werden, auch wenn
sie nicht sofort bearbeitet werden können.
Der nächste Thread bedient nur die COM-Schnittstelle, und zwar lesend.
Sobald sich an den 4 Inputpins (dwEvtMaskIn: alle hab' ich nicht
auprogrammiert) was tut, rennt WaitForSingleObject(...) weiter und die
Eventmaske (dwEvtMask) wird mit einer TimeStamp versehen an den
Monitorthread gesendet.
QueryPerformanceCounter() liefert zwar mikrosekundengenaue Angaben,
aber die Eigenverzögerung (ca. 4 mikrosec.) und die paar Befehle in der
Schleife verlängeren die Zeit. Deshalb "Zeitmessung auf 20
Mikrosekunden genau ...".

Dieses Code-Beispiel kann man beliebig aufpeppen und noch mehr
Ereignisse abfragen (siehe dwEvtMaskIn) und auch von anderen
Programmen! und auch anderen Threads des gleichen Programms (und auch
der Windows-CallBack-Routine) messages senden lassen.

Viel Spaß beim programmieren.

Blackbird

von Rolf F. (Gast)


Lesenswert?

Naja, der Thread-Ansatz ist schon richtig (verwende ich auch),
funktioniert aber nur unter MS-Win. Mit Posix-Threads und
Posix-Funktionen zum Zugreifen auf die serielle Schnittstelle wäre es
portable.

von Blackbird (Gast)


Lesenswert?

Portabilität (für C) zwischen Linux und Win für die serielle
Schnittstelle gibt es nicht. In C (und auch C++) gibt es keine
seriellen Schnittstellen. Die Zugriffe sind ja immer OS-abhängig. Man
kann jede Menge Wrapper drumherum schreiben, um dann irgendwann sagen
zu können: "jetzt sehen die C-Programme aber gleich aus (=
Portabel)", aber die Libs unterscheiden sich grundlegend.

Schön wär's ja, aber so haben die Programmierer wenigsten immer wieder
Arbeit :))

Also "back-to-the-roots".

Die Frage des Thread-Erstellers war "serieller Portzugriff unter Win
mit C".

Blackbird

von Eduard Strasser (Gast)


Lesenswert?

Mit Visual C++ geht es recht einfach. Dazu können API Funktionen wie
"CreateFile();, WriteFile();, ReadFile(); benutzt werden. Bei
"CreateFile(benötigte Parameter);" muss dann als Parameter "COM1"
oder "COM2" neben allen anderen angegeben sein.

Das kann man alles in "MSDN" zu Visual C++ nachgelesen werden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

... und mit Visual C++ hat das von Eduard genannte überhaupt nichts zu
tun, das sind die normalen Win32-API-Funktionen, die mit jedem
C-Compiler verwendet werden können, der Win32-Executables erzeugen
kann.

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.