📄 20000804014.htm
字号:
<HTML>
<HEAD>
<TITLE>用C++Builder 如何对串行口COM1或COM2进行读写操作</TITLE>
<META content="MSHTML 5.00.2314.1000" name=GENERATOR>
</HEAD>
<BODY aLink=#FF0000 bgColor=#ffffff leftMargin=0 link=#187800 topMargin=0
vLink=#990099>
<div align="center">
<table width="744" border="0" cellspacing="0" cellpadding="0" height="76">
<tr>
<td>
<p align="center"><b><font size="3"><br>
用C++Builder如何对串行口COM1或COM2进行读写操作</font></b>
<p>一个通讯类(对串口的读写),可以不用做修改就用在程序中 <br>
<br>
TSerialPort.h <br>
<br>
#ifndef __SERIALPORT_H__ <br>
#define __SERIALPORT_H__ <br>
<br>
#define WM_COMM_BREAK_DETECTED WM_USER+1 // A break was detected on
input. <br>
#define WM_COMM_CTS_DETECTED WM_USER+2 // The CTS (clear-to-sennd) sig
<br>
nal changed state. <br>
#define WM_COMM_DSR_DETECTED WM_USER+3 // The DSR (data-set-reaady)
si <br>
gnal changed state. <br>
#define WM_COMM_ERR_DETECTED WM_USER+4 // A line-status error ooccurre
<br>
d. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY. <br>
<br>
#define WM_COMM_RING_DETECTED WM_USER+5 // A ring indicator was etec
ted. <br>
#define WM_COMM_RLSD_DETECTED WM_USER+6 // The RLSD (receive-lin <br>
-sig <br>
nal-detect) signal changed state. <br>
#define WM_COMM_RXCHAR WM_USER+7 // A character w <br>
s received and pl <br>
aced in the input buffer. <br>
#define WM_COMM_RXFLAG_DETECTED WM_USER+8 // The event character w <br>
s <br>
received and placed in the input buffer. <br>
#define WM_COMM_TXEMPTY_DETECTED WM_USER+9 // The last character in
<br>
th <br>
e output buffer was sent. <br>
<br>
class TSerialPort <br>
{ <br>
public: <br>
// contruction and destruction <br>
TSerialPort(); <br>
virtual ~TSerialPort(); <br>
<br>
// port initialisation <br>
BOOL InitPort(TForm* pPortOwner, UINT portnr = 1, UINT baud = <br>
19200, <br>
char parity = 'N', UINT databits = 8, UINT stopsbits = 1, DWORD dwCom
<br>
mEvents = EV_RXCHAR | EV_CTS, UINT nBufferSize = 512); <br>
<br>
// start/stop comm watching <br>
BOOL StartMonitoring(); <br>
BOOL RestartMonitoring(); <br>
BOOL StopMonitoring(); <br>
<br>
DWORD GetWriteBufferSize(); <br>
DWORD GetCommEvents(); <br>
DCB GetDCB(); <br>
<br>
void WriteToPort(char* string); <br>
<br>
protected: <br>
// protected memberfunctions <br>
void ProcessErrorMessage(char* ErrorText); <br>
static DWORD _stdcall CommThread(LPVOID pParam); <br>
static void ReceiveChar(TSerialPort* port, COMSTAT comstat); <br>
static void WriteChar(TSerialPort* port); <br>
<br>
// thread <br>
HANDLE m_HThread; <br>
<br>
// synchronisation objects <br>
CRITICAL_SECTION m_csCommunicationSync; <br>
BOOL m_bThreadAlive; <br>
<br>
// handles <br>
HANDLE m_hShutdownEvent; <br>
HANDLE m_hComm; <br>
HANDLE m_hWriteEvent; <br>
<br>
// Event array. <br>
// One element is used for each event. There are two event handles fo
<br>
r each port. <br>
// A Write event and a receive character event which is located in th
<br>
e overlapped structure (m_ov.hEvent). <br>
// There is a general shutdown when the port is closed. <br>
HANDLE m_hEventArray[3]; <br>
<br>
// structures <br>
OVERLAPPED m_ov; <br>
COMMTIMEOUTS m_CommTimeouts; <br>
DCB m_dcb; <br>
<br>
// owner window <br>
TForm* m_pOwner; <br>
<br>
// misc <br>
UINT m_nPortNr; <br>
char* m_szWriteBuffer; <br>
DWORD m_dwCommEvents; <br>
DWORD m_nWriteBufferSize; <br>
}; <br>
<br>
#endif __SERIALPORT_H__ <br>
<br>
<br>
TSerialPort.cpp <br>
<br>
#include <br>
#pragma hdrstop <br>
#include "SerialPort.h" <br>
#include <br>
#include <br>
#pragma package(smart_init) <br>
// <br>
// Constructor <br>
// <br>
TSerialPort::TSerialPort() <br>
{ <br>
m_hComm = NULL; <br>
<br>
// initialize overlapped structure members to zero <br>
m_ov.Offset = 0; <br>
m_ov.OffsetHigh = 0; <br>
<br>
// create events <br>
m_ov.hEvent = NULL; <br>
m_hWriteEvent = NULL; <br>
m_hShutdownEvent = NULL; <br>
<br>
m_szWriteBuffer = NULL; <br>
<br>
m_bThreadAlive = false; <br>
} <br>
<br>
// <br>
// Delete dynamic memory <br>
// <br>
TSerialPort::~TSerialPort() <br>
{ <br>
do <br>
{ <br>
SetEvent(m_hShutdownEvent); <br>
} while (m_bThreadAlive); <br>
<br>
delete [] m_szWriteBuffer; <br>
} <br>
<br>
// <br>
// Initialize the port. This can be port 1 to 4. <br>
// <br>
BOOL TSerialPort::InitPort(TForm* pPortOwner, // the owner (CWnd) of
t <br>
he port (receives message) <br>
UINT portnr, <br>
/ portnumber (1..4) <br>
UINT baud, <br>
/ baudrate <br>
char parity, <br>
/ parity <br>
UINT databits, <br>
/ databits <br>
UINT stopbits, <br>
/ stopbits <br>
DWORD dwCommEvents, // EV_RX <br>
HAR, EV_CTS etc <br>
UINT writebuffersize) <br>
/ size to the writebuffer <br>
{ <br>
assert(portnr > 0 && portnr < 5); <br>
assert(pPortOwner != NULL); <br>
<br>
// if the thread is alive: Kill <br>
if (m_bThreadAlive) <br>
{ <br>
do <br>
{ <br>
SetEvent(m_hShutdownEvent); <br>
} while (m_bThreadAlive); <br>
} <br>
<br>
// create events <br>
if (m_ov.hEvent != NULL) <br>
ResetEvent(m_ov.hEvent); <br>
m_ov.hEvent = CreateEvent(NULL, true, false, NULL); <br>
<br>
if (m_hWriteEvent != NULL) <br>
ResetEvent(m_hWriteEvent); <br>
m_hWriteEvent = CreateEvent(NULL, true, false, NULL); <br>
<br>
if (m_hShutdownEvent != NULL) <br>
ResetEvent(m_hShutdownEvent); <br>
m_hShutdownEvent = CreateEvent(NULL, true, false, NULL); <br>
<br>
// initialize the event objects <br>
m_hEventArray[0] = m_hShutdownEvent; // highest priority <br>
m_hEventArray[1] = m_ov.hEvent; <br>
m_hEventArray[2] = m_hWriteEvent; <br>
<br>
// initialize critical section <br>
InitializeCriticalSection(&m_csCommunicationSync); <br>
<br>
// set buffersize for writing and save the owner <br>
m_pOwner = pPortOwner; <br>
<br>
if (m_szWriteBuffer != NULL) <br>
delete [] m_szWriteBuffer; <br>
m_szWriteBuffer = new char[writebuffersize]; <br>
<br>
m_nPortNr = portnr; <br>
<br>
m_nWriteBufferSize = writebuffersize; <br>
m_dwCommEvents = dwCommEvents; <br>
<br>
BOOL bResult = false; <br>
char *szPort = new char[50]; <br>
char *szBaud = new char[50]; <br>
<br>
// now it critical! <br>
EnterCriticalSection(&m_csCommunicationSync); <br>
<br>
// if the port is already opened: close it <br>
if (m_hComm != NULL) <br>
{ <br>
CloseHandle(m_hComm); <br>
m_hComm = NULL; <br>
} <br>
<br>
// prepare port strings <br>
sprintf(szPort, "COM%d", portnr); <br>
sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, da
<br>
tabits, stopbits); <br>
<br>
// get a handle to the port <br>
m_hComm = CreateFile(szPort, <br>
/ communication port string (COMX) <br>
<br>
GENERIC_READ | GENERIC_WRITE, <br>
/ read/write types <br>
0, <br>
/ comm devices must be opened with exclusive acce <br>
ss <br>
ss <br>
NULL, <br>
/ no security attributes <br>
OPEN_EXISTING, <br>
/ comm devices must use OPEN_EXISTING <br>
FILE_FLAG_OVERLAPPED, <br>
/ Async I/O <br>
0); <br>
/ template must be 0 for comm devices <br>
<br>
if (m_hComm == INVALID_HANDLE_VALUE) <br>
{ <br>
// port not found <br>
delete [] szPort; <br>
delete [] szBaud; <br>
<br>
return false; <br>
} <br>
<br>
// set the timeout values <br>
m_CommTimeouts.ReadIntervalTimeout = 1000; <br>
m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000; <br>
m_CommTimeouts.ReadTotalTimeoutConstant = 1000; <br>
m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000; <br>
m_CommTimeouts.WriteTotalTimeoutConstant = 1000; <br>
<br>
// configure <br>
if (SetCommTimeouts(m_hComm, &m_CommTimeouts)) <br>
{ <br>
if (SetCommMask(m_hComm, dwCommEvents)) <br>
{ <br>
if (GetCommState(m_hComm, &m_dcb)) <br>
{ <br>
m_dcb.fRtsControl = RTS_CONTROL_ENABLE; <br>
/ set RTS bit high! <br>
if (BuildCommDCB(szBaud, &m_dcb)) <br>
{ <br>
if (SetCommState(m_hComm, &m_dcb)) <br>
; // normal operation... continu <br>
<br>
else <br>
ProcessErrorMessage("SetCommStat <br>
()"); <br>
} <br>
else <br>
ProcessErrorMessage("BuildCommDCB()"); <br>
} <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -