Hallo Kann mir bitte jemand sagen, wie man unter WindowsXP die Signale CTS und DSR einer seriellen Schnittstelle (COMx) abfragen kann? Ich habe schon tief in der MSDN gerumgegraben und Kollegen konsultiert, aber ich finde einfach nichts. Es gibt zwar die Möglichkeit abzufragen, ob ein Write durch CTS oder DSR blockiert wird, aber ich finde nichts, wie ich einfach den Zustand (High/Low) der beiden Leitungen abfragen kann. Für entsprechend zielführende Hinweise bedanke ich mich schon im Voraus ganz herzlich. Gruß Franz
GetCommModemStatus http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/getcommmodemstatus.asp?frame=true
Mit dem .Net 2.0 Framework ganz einfach mit Portname.DsrHolding bzw Portname.CtsHolding. Beispiel mit VC# Express: if (serialPort1.DsrHolding) { MessageBox.Show("DSR aktiv!", "RS232", MessageBoxButtons.OK, MessageBoxIcon.Information); } else MessageBox.Show("DSR inaktiv!", "RS232", MessageBoxButtons.OK, MessageBoxIcon.Information);
Danke sehr! Über diese Funktion bin ich in der Hilfe schon gestolpert, konnte aber auf Grund der bescheidenen Beschreibung und des komischen Namens nichts damit anfangen. Schließlich interessiert mich kein Modemstatus, wenn ich garkein Modem angeschlossen habe ;-)) Vielen dank nochmal. Gruß Franz
Hi Auch an Pizzaman - danke :) Ich bin hier leider in einer C++ Umgebung (drunter und drüber), aber ich werde die C# Variante im Hinterkopf behalten. Gruß Franz
C++ oder C ist vollkommen egal. Den COM-Port fragt man mit API-Funktionen ab. Nur ist die Frage gestattet, ob Du im Polling oder ereignisgesteuert abfragen willst? Polling geht so (hier gleich mit Setzen der Ausgaenge): /******************************************* ** Nur Demo der Funktionen ** ** Button an RTS und CTS anschließen: ** An RTS wird Spannung gelegt ("ON"), CTS liest ** noch "LOW", solange der Button nicht gedrückt ** wird. ** ** RTS (Ausgang): Pin7 ist +10V (== AUS) ** Pin7 ist -10V (== EIN) ** CTS (Eingang): Pin8 wird abgefragt *******************************************/ #include <windows.h> int main (void) { HANDLE hPort; DWORD CtsStatus; // COM1 öffnen: hPort = CreateFile (TEXT("COM1"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); EscapeCommFunction (hPort, SETRTS); // RTS setzen (= -10V = ON) //EscapeCommFunction (hPort, CLRRTS); // rücksetzen geht so // Button abfragen: GetCommModemStatus (hPort, &CtsStatus); if ((CtsStatus & MS_CTS_ON)) { // irgendwas machen wenn Button gedrückt wurde ... } // ... CloseHandle (hPort); return 0; } und Ereignisgesteuert geht so (in Klassen packen kannst Du alleine?): /********************************************************************** ** Testprogramm: Wartet auf eine Pegeländerung an DSR, CTS, ... an COM1 ** ** Getestet: OK ab 12/2002! **********************************************************************/ #include <windows.h> #include <stdio.h> #define TIMELIMIT 100000 // Programm läuft 100 Sekunden // zusätzliche Events (DDK) #define SERIAL_EV_RXCHAR 0x0001 // Any Character received #define SERIAL_EV_RXFLAG 0x0002 // Received certain character #define SERIAL_EV_TXEMPTY 0x0004 // Transmitt Queue Empty #define SERIAL_EV_CTS 0x0008 // CTS changed state #define SERIAL_EV_DSR 0x0010 // DSR changed state #define SERIAL_EV_RLSD 0x0020 // RLSD changed state #define SERIAL_EV_BREAK 0x0040 // BREAK received #define SERIAL_EV_ERR 0x0080 // Line status error occurred #define SERIAL_EV_RING 0x0100 // Ring signal detected #define SERIAL_EV_PERR 0x0200 // Printer error occured #define SERIAL_EV_RX80FULL 0x0400 // Receive buffer is 80 percent full #define SERIAL_EV_EVENT1 0x0800 // Provider specific event 1 #define SERIAL_EV_EVENT2 0x1000 // Provider specific event 2 // Prototypes const char* decimalToBinary (const long value, const unsigned length, char* pszBuffer); /******************************************************************** ** DOS32-programm läuft TIMELIMIT / 1000 Sekunden und zeigt alle ** Pegeländerungen an COM 1 an ********************************************************************/ int main (void) { HANDLE hCom; OVERLAPPED o; DWORD dwStart; DWORD dwEvtMaskIn = EV_CTS | EV_DSR | EV_BREAK | EV_RING | EV_RXCHAR | EV_RLSD | EV_ERR | EV_RXFLAG | EV_TXEMPTY | SERIAL_EV_PERR | SERIAL_EV_RX80FULL | SERIAL_EV_EVENT1 | SERIAL_EV_EVENT2; DWORD dwEvtMask = 0; char szString[] = ("\r\nWarte auf Events (Pegelaenderungen) an COM 1:\r\n\ EV_RXCHAR =0x%04x\r\nEV_RXFLAG =0x%04x\r\nEV_TXEMPTY =0x%04x\r\n\ EV_CTS =0x%04x\r\nEV_DSR =0x%04x\r\nEV_RLSD =0x%04x\r\n\ EV_BREAK =0x%04x\r\nEV_ERR =0x%04x\r\nEV_RING =0x%04x\r\n\ EV_PERR =0x%04x\r\nEV_RX80FULL=0x%04x\r\nEV_EVENT1 =0x%04x\r\n\ EV_EVENT2 =0x%04x"); char szBuf[sizeof (DWORD) * 8] = ""; // für decimalToBinary-Funktion SYSTEMTIME SystemTime; // system time TCHAR lpszMsg[127] = ""; printf (szString, EV_RXCHAR, EV_RXFLAG, EV_TXEMPTY, EV_CTS, EV_DSR, EV_RLSD, EV_BREAK, EV_ERR, EV_RING, SERIAL_EV_PERR, SERIAL_EV_RX80FULL, SERIAL_EV_EVENT1, SERIAL_EV_EVENT2); hCom = CreateFile ("COM1", GENERIC_READ | GENERIC_WRITE, 0, // exclusive access NULL, // no security attributes OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (hCom == INVALID_HANDLE_VALUE) return printf ("\r\nCOM1 kann nicht geöffnet werden"); if (!SetCommMask (hCom, dwEvtMaskIn)) return printf ("\r\nSetCommMask fehlgeschlagen"); // Create an event object for use in WaitCommEvent. o.hEvent = CreateEvent ( NULL, // no security attributes FALSE, // auto reset event FALSE, // not signaled NULL); // no name dwStart = GetTickCount (); while (GetTickCount () - dwStart < TIMELIMIT) { WaitCommEvent (hCom, &dwEvtMask, &o); if (WAIT_OBJECT_0 == WaitForSingleObject (o.hEvent, INFINITE)) { GetLocalTime (&SystemTime); printf ("\r\nEvents: %s - ", decimalToBinary (dwEvtMask, sizeof (DWORD) * 8, szBuf)); if (dwEvtMask & EV_DSR) printf ("DSR "); if (dwEvtMask & EV_CTS) printf ("CTS "); if (dwEvtMask & EV_BREAK) printf ("BREAK "); if (dwEvtMask & EV_RING) printf ("RING "); if (dwEvtMask & EV_RXCHAR) //printf ("RXCHAR "); if (dwEvtMask & EV_RLSD) printf ("RLSD "); if (dwEvtMask & EV_ERR) printf ("ERR "); if (dwEvtMask & EV_RXFLAG) printf ("RXFLAG "); if (dwEvtMask & EV_TXEMPTY) printf ("TXEMPTY "); if (dwEvtMask & SERIAL_EV_PERR) printf ("PERR "); if (dwEvtMask & SERIAL_EV_RX80FULL) printf ("RX80FULL "); if (dwEvtMask & SERIAL_EV_EVENT1) printf ("EVENT1 "); if (dwEvtMask & SERIAL_EV_EVENT2) printf ("EVENT2 "); wsprintf (lpszMsg, "%s, den %02d.%02d.%04d um %d:%d Uhr %d,%d Sek.", SystemTime.wDayOfWeek == 1 ? "Mo" : (SystemTime.wDayOfWeek == 2 ? "Di" : (SystemTime.wDayOfWeek == 3 ? "Mi" : (SystemTime.wDayOfWeek == 4 ? "Do" : (SystemTime.wDayOfWeek == 5 ? "Fr" : (SystemTime.wDayOfWeek == 6 ? "Sa" : (SystemTime.wDayOfWeek == 7 ? "So" : "Heute")))))), SystemTime.wDay, SystemTime.wMonth, SystemTime.wYear, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds); printf (": %s", lpszMsg); } } CloseHandle (o.hEvent); CloseHandle (hCom); return printf ("\r\n!ENDE! %d Sekunden sind um!\r\n", TIMELIMIT / 1000); } /*********************************************************************** ****** ** Umwandlung: Dezimal zu Binär ** ** 1. Param: die Zahl ** 2. Param: Anzahl der Binärstellen (von 1..32) ** 3. Param: Zeiger auf ein char-Array, das den String aufnehmen kann ************************************************************************ *****/ const char* decimalToBinary (const long value, const unsigned length, char* pszBuffer) { if ((length == 0) || (length > 32)) { pszBuffer = '\0'; return pszBuffer; } unsigned digit = 1 << (length - 1); char* pszCurrent = pszBuffer; do { if (value & digit) *pszCurrent = '1'; else *pszCurrent = '0'; pszCurrent++; digit /= 2; } while (digit != 0); *pszCurrent = '\0'; return pszBuffer; } Blackbird
> // COM1 öffnen: > hPort = CreateFile (TEXT("COM1"), GENERIC_READ | GENERIC_WRITE, > 0, NULL, OPEN_EXISTING, 0, NULL); Das würde so nicht machen, auch wenn es in diesem speziellen Fall funktioniert. Früher oder später handelst Du Dir mit diesem Vorgehen Probleme ein. Richtig sieht das so aus: hPort = CreateFile (TEXT("\\\\.\\COM1"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); Siehe auch KB115831, http://support.microsoft.com/default.aspx?scid=kb;en-us;115831 Aber hatte sich das eigentliche Problem nicht schon vor zwei Tagen gelöst? BTW: Was ist ein DOS32-Programm?
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.