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