Serielle Schnittstelle Com1 ansteuern
-
Hallo!
Ich weiß, dass man zum dem Thema im Inet einiges findet.
Leider habe ich es noch nicht hinbekommen einen Text zu senden und zu empfangen.Auf http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfiles/html/msdn_serial.asp
findet man einige Beispielfunktionen.
Leider sind die ziemlich komplex und einiges fehlt.
Zum Beispiel finde ich keine Funktion, um die Schnittstelle wieder zu schließen.Ich hoffe jemand kann mir helfen.
MfG ACU
-
Deine Frage?
-
Mit welcher Funktion kann und Senden und mit welcher Empfangen, bei den Beispielen muß man soviele Parameter eintragen, da steige ich nicht ganz durch.
-
ReadFile / WriteFile

-
Nehmen wir einmal die Funktion fürs senden:
DWORD dwRead; BOOL fWaitingOnRead = FALSE; OVERLAPPED osReader = {0}; // Create the overlapped event. Must be closed before exiting // to avoid a handle leak. osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (osReader.hEvent == NULL) // Error creating overlapped event; abort. if (!fWaitingOnRead) { // Issue read operation. if (!ReadFile(hComm, lpBuf, READ_BUF_SIZE, &dwRead, &osReader)) { if (GetLastError() != ERROR_IO_PENDING) // read not delayed? // Error in communications; report it. else fWaitingOnRead = TRUE; } else { // read completed immediately HandleASuccessfulRead(lpBuf, dwRead); } }Aber wo muß ich jetzt den Text übergeben, der gesendet werden soll?
MfG ACU
-
nirgendwo. das ist ein beispiel zum empfangen

-
hier mal ein ganz simples beispiel. nicht überlappend, d.h. es wird solange gelesen und gesendet, bis etwas ankommt.
// Schnittstelle öffnen (Port ist "COM1", "COM2", usw.) HANDLE OpenComm(char *Port) { HANDLE hCom = ::CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hCom == INVALID_HANDLE_VALUE) { // ... Fehler } return hCom; } // Schnittstelle schliessen void CloseComm(HANDLE hCom) { PurgeComm(hCom, PURGE_RXABORT); CloseHandle(hCom); } // Port konfigurieren (Parameter siehe MSDN) void SetDeviceControlBlock(HANDLE hCom, DWORD BaudRate, BYTE ByteSize, BYTE Parity, BYTE StopBits) { if (hCom == INVALID_HANDLE_VALUE) return; DCB dcb; // Schnittstelle auslesen if (!::GetCommState(hCom, &dcb)) { // ... Fehler } dcb.BaudRate = BaudRate; dcb.ByteSize = ByteSize; dcb.Parity = Parity; dcb.StopBits = StopBits; // Schnittstelle konfigurieren if (!::SetCommState(hCom, &dcb)) { // ... Fehler } }Data ist der Datenpuffer, Length die Laenge des Puffers, hCom ist das Handle auf die Serielle Schnittstelle (Com1, usw.)
//--------------------------------------------------------------------------- int SendData(HANDLE hCom, char *Data, int Length) { DWORD NumberOfBytesWritten; if (!::WriteFile(hCom, Data, Length, &NumberOfBytesWritten, 0)) { // ... Fehler } return NumberOfBytesWritten; } //--------------------------------------------------------------------------- DWORD ReceiveData(HANDLE hCom, char *Data, int Length) { DWORD NumberOfBytesRead; if (!::ReadFile(hCom, Data, Length, &NumberOfBytesRead, 0)) { // ... Fehler } return NumberOfBytesRead; }verwendung dann zum beispiel so:
void __fastcall TForm1::Button1Click(TObject *Sender) { HANDLE hCom; // COM-Port öffnen und initialisieren if ((hCom = OpenComm("COM1")) != INVALID_HANDLE_VALUE) SetDeviceControlBlock(hCom, CBR_9600, 8, NOPARITY, ONESTOPBIT); }
-
Vielen Dank für die ausführliche Hilfe.
Sobald ich kann werde ich es ausprobieren.MfG ACU
-
@ Sunday:
Warum gibst du der Fkt.
int SendData(HANDLE hCom, char *Data, int Length)int Length mit, das könnte man doch dann in der Fkt abfragen mit Data.Length() oder strlen(Data).
Oder würde das nicht funktionieren? Warum?
mfg
Tom
-
seit wann hat ein array eine eine funktion Length()? das array weiss doch nicht wie gross es ist.
strlen ermittelt die länge einer zeichenkette und bei binären daten funktioniert das dann nicht mehr, da strlen bis zum ersten \0 zeichen liest.
-
Aber ich übergebe der Fkt doch eh nur ein Element und von diesem Element, in dem mein Text steht, den ich senden will, müsste ich doch die Länge auch direkt herausbekommen. Da müsste es doch egal sein ob ich die Länge vorher über eine Fkt bestimme oder direkt "inline"?
oder, täsuche ich mich, da?
mfg
TomPS: Wie würde deine Fkt aussehen die dann die SendData(....) aufruft?
-
vielleicht solltest du dich noch einmal mit den grundlagen von c/c++ beschäftigen...
const int BufSize = 25; char *Buffer = new char[BufSize]; // Puffer fuellen strcpy(Buffer, "blahfasel dumdidum"); DWORD BytesWritten = SendData(hCom, Buffer, BufSize); // 25 zeichen senden DWORD BytesRead = ReceiveData(hCom, Buffer, BufSize); // 25 zeichen empfangen delete [] Buffer;
-
strcpy(Buffer, "blahfasel dumdidum");Hier hast du doch nen String in Buffer kopiert und wenn ich dann:
strlen(Buffer) mache müsste ich doch die Länge von dem Ding bekommen, oder etwa nicht?StrLen gibt die Anzahl der Zeichen ohne das abschließende Nullbyte eines Strings zurück. -> steht so in der Hilfe.
Also entweder habe ich jetzt nen gewaltigen Denkfehler, dann tuts mir leid, wenn ich lästig war oder ich hab recht dann

mfg
Tom
-
man man man... der string ist doch nur ein beispiel gewesen.
stell dir vor du hast ne kamera an der seriellen schnittstelle haengen, die sendet dir keine strings sondern bilder und die liegen binär vor. diesen enthalten also auch nullbytes bei denen strlen abbrechen würde! deswegen benötigts du die grösse des puffers. die kamera stellt dann z.b. befehle zur verfügung um die grösse eine bildes vor dem transfer abzufragen um entspr. den puffer anzupassen.
capito?!
-
ja, ok, thx, hab nicht beachtet dass es auch möglich ist, dass wie du schon sagst ein NULLBYTE öfters vorkommen kann.
mfg
Tom
-
Ich bins nochmal.
Bei der Funktion zum schließen der Schnittstelle habe ich noch eine Frage, was muß ich als Handle übergeben, damit ich die zuvor geöffnete Com1 wieder schließen kann?void CloseComm(HANDLE hCom) { PurgeComm(hCom, PURGE_RXABORT); CloseHandle(hCom); }MfG ACU
-
ACU schrieb:
Ich bins nochmal.
Bei der Funktion zum schließen der Schnittstelle habe ich noch eine Frage, was muß ich als Handle übergeben, damit ich die zuvor geöffnete Com1 wieder schließen kann?void CloseComm(HANDLE hCom) { PurgeComm(hCom, PURGE_RXABORT); CloseHandle(hCom); }MfG ACU
Das Richtige!
-
Danke für die aufschlußreiche Antwort.
Das ich das Richtige übergeben muß, habe ich mir selber schon fast gedacht.
Weil wenn ich das falsche übergebe, geht es nicht.Aber was ist das Richtige den nun?
ACU
-
Das von CreateFile zurückgegebene Handle.
-
Öffnen und schließen der Schnittstelle funktioniert jetzt.
Ich habe aber noch ein paar kleine Probleme.
Zum Beispiel funktioniert die Konfiguration der Schnittstelle nicht.Die Konfiguration rufe ich mit SetDeviceControlBlock(Schnittstelle,9600,8,0,1);auf.
Auch das Senden macht noch Probleme (vielleicht auch wegen der Konfiguration).
Ich möchte eine String mit ASCII Zeichen an die Serielle Schnittstelle senden.
Dazu habe ich folgenden Code verwendet:char *ch = new char[Form1->Edit1->Text.Length()]; strcpy(ch, Form1->Edit1->Text.c_str());int Laenge;
SendData(Schnittstelle,ch,Edit1->Text.Length());[/code]
Empfangen tu ich nur sinnlose Werte, die in Keinster Weise den ASCII werten entsprechen.Wäre toll, wenn jemand helfen könnte.
MfG ACU