16. januar 2003 - 11:01
#1
-------------------------------------------------------------------------
------------- header ----------------------------------------------------
-------------------------------------------------------------------------
// Serial_IO.h: interface for the Serial_IO class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SERIAL_IO_H__9BBF62C3_234D_11D5_AAF3_00105A30208C__INCLUDED_)
#define AFX_SERIAL_IO_H__9BBF62C3_234D_11D5_AAF3_00105A30208C__INCLUDED_
#include "FrameBuffer.h"
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
class Serial_IO : public CFrameBuffer
{
public:
CString GetConnectionStr();
void ClearBuffer();
int ReadData( void *pBuffer, int nLimit );
int SendData( const unsigned char *pBuffer, int nSize );
void Close();
bool Open( char szPort[], DWORD nBaud, DWORD nData, DWORD nParity, DWORD nStop );
void SetHWnd( HWND hWnd );
HWND GetWindow();
Serial_IO( HWND hWnd, int nBufferSize = 128 );
virtual ~Serial_IO();
private:
bool m_bPortOpen;
HWND m_hWnd;
HANDLE m_hIDComDev;
CString m_szConnectionStr;
};
#endif // !defined(AFX_SERIAL_IO_H__9BBF62C3_234D_11D5_AAF3_00105A30208C__INCLUDED_)
-------------------------------------------------------------------------
----- cpp ---------------------------------------------------------------
-------------------------------------------------------------------------
// Serial_IO.cpp: implementation of the Serial_IO class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Monitor.h"
#include "Serial_IO.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Serial_IO::Serial_IO( HWND hWnd, int nBufferSize ) : CFrameBuffer( nBufferSize )
{
// store hWnd for posting messages to main application
m_hWnd = hWnd;
// port not open
m_bPortOpen = false;
}
Serial_IO::~Serial_IO()
{
}
HWND Serial_IO::GetWindow()
{
// return creator of IO
return m_hWnd;
}
bool Serial_IO::Open(char szPort [ ], DWORD nBaud, DWORD nData, DWORD nParity, DWORD nStop)
{
// if port open, close port
m_szConnectionStr = "Not connected";
if( m_bPortOpen )
{
Close();
}
DCB dcb;
// open port
m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL /*| FILE_FLAG_OVERLAPPED*/, NULL );
// return false if creation failed
if( m_hIDComDev == NULL )
{
return false;
}
// read call blocks until data, write returns after a timeout of 5 secs or when data was written to port
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );
// setup port structure
dcb.DCBlength = sizeof( DCB );
GetCommState( m_hIDComDev, &dcb );
dcb.BaudRate = nBaud;
dcb.ByteSize = (unsigned char)nData;
dcb.Parity = (unsigned char)nParity;
dcb.StopBits = (unsigned char)nStop;
dcb.ErrorChar = (unsigned char)0xFF;
// setup port and set recieve/send buffers to 65k each
if( !SetCommState( m_hIDComDev, &dcb ) ||!SetupComm( m_hIDComDev, 0x8000, 0x8000 ) )
{
// if failed return false
CloseHandle( m_hIDComDev );
return false;
}
m_szConnectionStr = szPort;
// port is open
m_bPortOpen = true;
return m_bPortOpen;
}
void Serial_IO::Close()
{
// if port open and device valid
if( (m_bPortOpen) && (m_hIDComDev != NULL) )
{
// close device
CloseHandle( m_hIDComDev );
// port closed
m_bPortOpen = false;
m_hIDComDev = NULL;
}
}
void Serial_IO::SetHWnd(HWND hWnd)
{
// set main application's hWnd
m_hWnd = hWnd;
}
int Serial_IO::SendData( const unsigned char *pBuffer, int nSize )
{
BOOL bWriteStat;
DWORD dwBytesWritten = 0;
// if port open and device valid
if( (m_bPortOpen) && (m_hIDComDev != NULL) )
{
// write data to port
bWriteStat = WriteFile( m_hIDComDev, pBuffer, nSize, &dwBytesWritten, NULL );
// if successful
if( !bWriteStat )
{
// tell failure
AfxMessageBox( "Failed to send data to serial port" );
ASSERT( NULL );
}
}
// return bytes written to port
return (int)dwBytesWritten;
}
int Serial_IO::ReadData( void *pBuffer, int nLimit )
{
BOOL bReadStatus;
DWORD dwBytesRead = 0, dwErrorFlags;
COMSTAT ComStat;
// if port open and device valid
if( (m_bPortOpen) && (m_hIDComDev != NULL) )
{ // clear any comm errors and get bytes in IN cue
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
// bytes in IN cue
dwBytesRead = (DWORD) ComStat.cbInQue;
// if more bytes in que than space in buffer supplied, limit reading to max buffer space
if( nLimit < (int)dwBytesRead ) dwBytesRead = (DWORD)nLimit;
// read into buffer
bReadStatus = ReadFile( m_hIDComDev, pBuffer, dwBytesRead, &dwBytesRead, NULL );
// if successful
if( !bReadStatus )
{
// tell failure
AfxMessageBox( "Failed to read data from serial port" );
ASSERT( NULL );
}
}
// return bytes read
return (int)dwBytesRead;
}
void Serial_IO::ClearBuffer()
{
DWORD dwBytesRead = 0, dwErrorFlags;
COMSTAT ComStat;
memset( &ComStat, 0x00, sizeof(ComStat) );
char szBuffer[512];
// if port open and device valid
if( (m_bPortOpen) && (m_hIDComDev != NULL) )
{
// while data in system port buffer
while( ComStat.cbInQue != 0 )
{
// clear any port errors
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
// if any data
if( ComStat.cbInQue != 0 )
{
// read max 512 bytes
ReadFile( m_hIDComDev, szBuffer, 512, &dwBytesRead, NULL );
}
}
}
// clear frame buffer
Clear();
}
CString Serial_IO::GetConnectionStr()
{
return m_szConnectionStr;
}
21. januar 2003 - 09:43
#3
Her er et eksempel...
// Port.h
#ifndef PORT_H
#define PORT_H
typedef enum {SUCCES, CANNOT_OPEN_PORT, CANNOT_CLOSE_PORT, INVALID_PORT_HANDLE, CANNOT_CONFIGURE_PORT, CANNOT_SET_PORT_TIMEOUT, CANNOT_WRITE_TO_PORT} ERROR_CODE;
class Port
{
public:
Port();
int PortInitialize(CString lpszPortName);
int PortWrite(BYTE Byte);
int PortClose();
private:
HANDLE m_hPort;
HANDLE m_hReadThread;
};
#endif
/***********************************************************************
Port.cpp
***********************************************************************/
#include "Port.h"
#define BUFFER_LENGTH 128
Port::Port()
: m_hPort(NULL), m_hReadThread(NULL)
{
}
/***********************************************************************
PortInitialize(LPTSTR lpszPortName)
***********************************************************************/
int Port::PortInitialize(CString lpszPortName)
{
DWORD dwThreadID;
DCB PortDCB;
COMMTIMEOUTS CommTimeouts;
// Open the serial port.
m_hPort = CreateFile(lpszPortName, // Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE, // Access (read/write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING, // How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute to copy
if(m_hPort == INVALID_HANDLE_VALUE)
{
// Could not open the port.
return CANNOT_OPEN_PORT;
}
PortDCB.DCBlength = sizeof(DCB);
// Get the default port setting information.
GetCommState (m_hPort, &PortDCB);
// Change the DCB structure settings.
PortDCB.BaudRate = CBR_57600; // Current baud
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = TRUE; // Enable parity checking.
PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type
PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx
PortDCB.fOutX = FALSE; // No XON/XOFF out flow control
PortDCB.fInX = FALSE; // No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE; // Disable error replacement.
PortDCB.fNull = FALSE; // Disable null stripping.
PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control
PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on error.
PortDCB.ByteSize = 8; // Number of bits/bytes, 4-8
PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
// Configure the port according to the specifications of the DCB structure.
if(!SetCommState(m_hPort, &PortDCB))
{
// Could not create the read thread.
return CANNOT_CONFIGURE_PORT;
}
// Retrieve the time-out parameters for all read and write operations on the port.
GetCommTimeouts(m_hPort, &CommTimeouts);
// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
// Set the time-out parameters for all read and write operations on the port.
if(!SetCommTimeouts(m_hPort, &CommTimeouts))
{
// Could not create the read thread.
return CANNOT_SET_PORT_TIMEOUT;
}
// Direct the port to perform extended functions SETDTR and SETRTS.
// SETDTR: Sends the DTR (data-terminal-ready) signal.
// SETRTS: Sends the RTS (request-to-send) signal.
EscapeCommFunction(m_hPort, SETDTR);
EscapeCommFunction(m_hPort, SETRTS);
// Create a read thread for reading data from the communication port.
if(m_hReadThread = CreateThread(NULL, 0, PortReadThread, this, 0, &dwThreadID))
{
CloseHandle(m_hReadThread);
}
else
{
// Could not create the read thread.
return FALSE;
}
return SUCCES;
}
/***********************************************************************
PortWrite (BYTE Byte)
***********************************************************************/
int Port::PortWrite(BYTE Byte)
{
DWORD dwNumBytesWritten;
if(!WriteFile(m_hPort, // Port handle
&Byte, // Pointer to the data to write
1, // Number of bytes to write
&dwNumBytesWritten, // Pointer to the number of bytes
// written
NULL)) // Must be NULL for Windows CE
{
// WriteFile failed. Report error.
return CANNOT_WRITE_TO_PORT;
}
return SUCCES;
}
/***********************************************************************
PortClose()
***********************************************************************/
int Port::PortClose()
{
if(m_hPort != INVALID_HANDLE_VALUE)
{
// Close the communication port.
if(!CloseHandle(m_hPort))
{
return CANNOT_CLOSE_PORT;
}
else
{
m_hPort = INVALID_HANDLE_VALUE;
return SUCCES;
}
}
return INVALID_PORT_HANDLE;
}