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
Also bei Linux gehts ganz leicht, da kann man direkt auf die gewünschten Ports zugreifen (als root), aber bei Windoof....?
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.
Sind die CreateFile etc Befehle nicht auch mit reinem C benutzbar? Damit ginge alles ganz einfach
"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.
Weil es ein paar mehr Zeilen werden und eine fertige Klasse kompakter zu handhaben ist ...
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
"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. :)
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.
So geht es in C (ist aber nur eine Beispiel von vielen ...): siehe Anhang WriteFile kann man von überall aus aufrufen. Blackbird
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?!?
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
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.
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 :-)
> 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.
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.
"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
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
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.
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
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.
... 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.