[an error occurred while processing this directive]
Исходник класса для работы с COM портом
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Роман. 31 октября 2002 г. 10:50
В ответ на: "Программа тестировалась на нескольких машинах" - (+) отправлено Дятел 31 октября 2002 г. 10:19

Header:
class TCommPort
{
public:
TCommPort();
~TCommPort();
void OpenCommPort(void);
void CloseCommPort(void);

void SetCommPort(const std::string & port);
std::string GetCommPort(void);
void SetBaudRate(unsigned int newBaud);
unsigned int GetBaudRate(void);
void SetParity(BYTE newParity); // see source for possible values
BYTE GetParity(void);
void SetByteSize(BYTE newByteSize);
BYTE GetByteSize(void);
void SetStopBits(BYTE newStopBits);
BYTE GetStopBits(void);

void SetCommDCBProperties(DCB &properties); // avoid using DCB interface
void GetCommDCBProperties(DCB &properties); // Use SetBaudRate et al instead

void GetCommProperties(COMMPROP &properties);

void WriteString(const char *outString);
void WriteBuffer(BYTE *buffer, unsigned int ByteCount);
void WriteBufferSlowly(BYTE *buffer, unsigned int ByteCount);
int ReadString(char *string, unsigned int MaxBytes);
int ReadBytes(BYTE *bytes, unsigned int byteCount);
void DiscardBytes(unsigned int MaxBytes);
void PurgeCommPort(void);
void FlushCommPort(void);

void PutByte(BYTE value);
BYTE GetByte();
unsigned int BytesAvailable(void);

bool GetConnected()
{
return m_CommOpen;
}

HANDLE GetHandle() // allow access to the handle in case the user needs to
{ // do something hardcore. Avoid this if possible
return m_hCom;
}

private:
// Note: the destructor of the commport class automatically closes the
// port. This makes copy construction and assignment impossible.
// That is why I privatize them, and don't define them. In order
// to make copy construction and assignment feasible, we would need
// to employ a reference counting scheme.
TCommPort(const TCommPort &); // privatize copy construction
TCommPort & operator=(const TCommPort&); // and assignment.

void VerifyOpen()
{
if(!m_CommOpen)
throw ECommError(ECommError::PORT_NOT_OPEN) ;
}
void VerifyClosed()
{
if(m_CommOpen)
throw ECommError(ECommError::PORT_ALREADY_OPEN) ;
}

// this stuff is private because we want to hide these details from clients
bool m_CommOpen;
COMMTIMEOUTS m_TimeOuts;
std::string m_CommPort;
DCB m_dcb; // a DCB is a windows structure used for configuring the port
HANDLE m_hCom; // handle to the comm port.
};

/////////////
Source:

#include "comm.h"

TCommPort::TCommPort():m_CommOpen(false),m_CommPort("COM1"),m_hCom(0)
{
m_dcb.DCBlength = sizeof(DCB);
m_dcb.BaudRate =9600;
m_dcb.ByteSize =8;
m_dcb.Parity =NOPARITY;
m_dcb.StopBits =ONESTOPBIT;
}

TCommPort::~TCommPort()
{
if(m_CommOpen)
CloseCommPort();
}

void TCommPort::OpenCommPort(void)
{
if(m_CommOpen)
return;

DCB tempDCB;
tempDCB.BaudRate = m_dcb.BaudRate;
tempDCB.ByteSize = m_dcb.ByteSize;
tempDCB.Parity = m_dcb.Parity;
tempDCB.StopBits = m_dcb.StopBits;

m_hCom = CreateFile(m_CommPort.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);

if(m_hCom == INVALID_HANDLE_VALUE)
throw ECommError(ECommError::OPEN_ERROR);

if(!GetCommState(m_hCom,&m_dcb))
{
CloseHandle(m_hCom);
throw ECommError(ECommError::GETCOMMSTATE);
}

m_dcb.BaudRate = tempDCB.BaudRate;
m_dcb.ByteSize = tempDCB.ByteSize;
m_dcb.Parity = tempDCB.Parity;
m_dcb.StopBits = tempDCB.StopBits;

if(!SetCommState(m_hCom,&m_dcb))
{
CloseHandle(m_hCom);
throw ECommError(ECommError::SETCOMMSTATE);
}

if(!SetupComm(m_hCom, 1024*32, 1024*9))
{
CloseHandle(m_hCom);
throw ECommError(ECommError::SETUPCOMM);
}

m_TimeOuts.ReadIntervalTimeout = 15;
m_TimeOuts.ReadTotalTimeoutMultiplier = 1;
m_TimeOuts.ReadTotalTimeoutConstant = 250;
m_TimeOuts.WriteTotalTimeoutMultiplier = 1;
m_TimeOuts.WriteTotalTimeoutConstant = 250;
if(!SetCommTimeouts(m_hCom, &m_TimeOuts))
{
CloseHandle(m_hCom);
throw ECommError(ECommError::SETCOMMTIMEOUTS);
}

m_CommOpen = true;
}

void TCommPort::CloseCommPort(void)
{
if(!m_CommOpen)
return;

if(CloseHandle(m_hCom) != 0)
{
m_CommOpen = false;
}
else
throw ECommError(ECommError::CLOSE_ERROR);
}
void TCommPort::SetCommDCBProperties(DCB &properties)
{
if(m_CommOpen)
{
if(!SetCommState(m_hCom,&properties))
throw ECommError(ECommError::SETCOMMSTATE);
else
m_dcb = properties;
}
else
m_dcb = properties;
}

void TCommPort::GetCommDCBProperties(DCB &properties)
{
properties = m_dcb;
}

void TCommPort::SetBaudRate(unsigned int newBaud)
{
unsigned int oldBaudRate = m_dcb.BaudRate;
m_dcb.BaudRate = newBaud;

if(m_CommOpen)
{
if(!SetCommState(m_hCom,&m_dcb))
{
m_dcb.BaudRate = oldBaudRate;
throw ECommError(ECommError::BAD_BAUD_RATE);
}
}
}
void TCommPort::SetByteSize(BYTE newByteSize)
{
BYTE oldByteSize = m_dcb.ByteSize;
m_dcb.ByteSize = newByteSize
if(m_CommOpen)
{
if(!SetCommState(m_hCom,&m_dcb))
{
m_dcb.ByteSize = oldByteSize;
throw ECommError (ECommError::BAD_BYTESIZE); }
}
}
void TCommPort::SetParity(BYTE newParity)
{
BYTE oldParity = m_dcb.Parity; parity
m_dcb.Parity = newParity;

if(m_CommOpen)
{
if(!SetCommState(m_hCom,&m_dcb)) { m_dcb.Parity = oldParity; // restore old parity
throw ECommError(ECommError::BAD_PARITY); // bomb out
}
}
}
///// end of TCommPort::SetParity()
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
///// TCommPort::SetStopBits()
/////
///// scope: TCommPort public function.
///// purpose : set the number of stop bits.
///// args : int arg for number of stopbits.
///// returns : bool to indicate success (true) or failure
///// written : 10/31/96 by H Howe
///// remarks : If the port is open, SetCommState will be used to try and
///// set the # of stop bits immediately. Otherwise the best we
///// can do is save the new parity in our private data member.
///// Note, the arg to this function should be one of the windows
///// #defines for stop bits(ONESTOPBIT ONE5STOPBITS TWOSTOPBITS)
///// methods : first, make a copy of the old stopbits # in case we fail.
///// Then change the stop bit member of dcb. If the port is open
///// open, try to set the new stop bit number.
void TCommPort::SetStopBits(BYTE newStopBits)
{
BYTE oldStopBits = m_dcb.StopBits; // make a backup of old #of stop bits
m_dcb.StopBits = newStopBits; // assign new # of stop bits

if(m_CommOpen) // check for open comm port
{
if(!SetCommState(m_hCom,&m_dcb)) // try to set the new comm settings
{ // if failure
m_dcb.StopBits = oldStopBits; // restore old # of stop bits
throw ECommError(ECommError::BAD_STOP_BITS); // bomb out
}
}
}
///// end of TCommPort::SetParity()
////////////////////////////////////////////////////////////////////////////////

unsigned int TCommPort::GetBaudRate(void)
{
return m_dcb.BaudRate;
}

BYTE TCommPort::GetByteSize(void)
{
return m_dcb.ByteSize;
}

BYTE TCommPort::GetParity(void)
{
return m_dcb.Parity;
}

BYTE TCommPort::GetStopBits(void)
{
return m_dcb.StopBits;
}

void TCommPort::WriteBuffer(BYTE *buffer, unsigned int ByteCount)
{
VerifyOpen();
DWORD dummy;
if( (ByteCount == 0) || (buffer == NULL))
return;

if(!WriteFile(m_hCom,buffer,ByteCount,&dummy,NULL))
throw ECommError(ECommError::WRITE_ERROR);
}

void TCommPort::WriteBufferSlowly(BYTE *buffer, unsigned int ByteCount)
{
VerifyOpen();
DWORD dummy;
BYTE *ptr = buffer;

for (unsigned int j=0; j {
if(!WriteFile(m_hCom,ptr,1,&dummy,NULL))
throw ECommError(ECommError::WRITE_ERROR);

// Use FlushCommPort to wait until the character has been sent.
FlushCommPort();
++ptr;
}
}

void TCommPort::WriteString(const char *outString)
{
VerifyOpen();

DWORD dummy;
if(!WriteFile(m_hCom,outString, strlen(outString),&dummy,NULL))
throw ECommError(ECommError::WRITE_ERROR);
}

int TCommPort::ReadBytes(BYTE *buffer, unsigned int MaxBytes)
{
VerifyOpen();
DWORD bytes_read;

if(!ReadFile(m_hCom,buffer,MaxBytes,&bytes_read,NULL))
throw ECommError(ECommError::READ_ERROR);

// add a null terminate if bytes_read < byteCount
// if the two are equal, there is no space to put a null terminator
if(bytes_read < MaxBytes)
buffer[bytes_read]='\0';

return bytes_read;
}

int TCommPort::ReadString(char *str, unsigned int MaxBytes)
{
VerifyOpen();

if(MaxBytes == 0u)
return 0;
str[0]='\0';
if(BytesAvailable() ==0)
return 0;

BYTE NewChar;
unsigned int Index=0;
while(Index < MaxBytes)
{
NewChar = GetByte();

// if the byte is a \r or \n, don't add it to the string
if( (NewChar != '\r') && (NewChar != '\n'))
{
str[Index] = (char) NewChar;
Index++;
}

// when /r is received, we are done reading the string, so return
// don't forget to terminate the string with a \0.
if(NewChar == '\r')
{
str[Index] = '\0';
return Index +1;
}
}

// if the while loop false through, then MaxBytes were received without
// receiveing a \n. Add null terminator to the string and return the number
str[MaxBytes-1]='\0';
return MaxBytes;
}

void TCommPort::DiscardBytes(unsigned int MaxBytes)
{
VerifyOpen();
if(MaxBytes == 0)
return;

BYTE *dummy= new BYTE[MaxBytes];
ReadBytes(dummy, MaxBytes);
delete []dummy;
}

void TCommPort::PurgeCommPort(void)
{
VerifyOpen();
if(!PurgeComm(m_hCom,PURGE_RXCLEAR))
throw ECommError(ECommError::PURGECOMM);

}

void TCommPort::FlushCommPort(void)
{
VerifyOpen();

if(!FlushFileBuffers(m_hCom))
throw ECommError(ECommError::FLUSHFILEBUFFERS);
}

void TCommPort::PutByte(BYTE value)
{
VerifyOpen();

DWORD dummy;
if(!WriteFile(m_hCom,&value,1,&dummy,NULL))
throw ECommError(ECommError::WRITE_ERROR);
}


BYTE TCommPort::GetByte()
{
VerifyOpen();

DWORD dummy;
BYTE value;
if(!ReadFile(m_hCom,&value,1,&dummy,NULL))
throw ECommError(ECommError::READ_ERROR);

return value;
}


unsigned int TCommPort::BytesAvailable(void)
{
VerifyOpen();

COMSTAT comstat;
DWORD dummy;

if(!ClearCommError(m_hCom, &dummy, &comstat))
throw ECommError(ECommError::CLEARCOMMERROR);
return comstat.cbInQue;
}

void TCommPort::SetCommPort(const std::string & port)
{
VerifyClosed(); // can't change comm port once comm is open
// could close and reopen, but don't want to

m_CommPort = port;
}

std::string TCommPort::GetCommPort(void)
{
return m_CommPort;
}

void TCommPort::GetCommProperties(COMMPROP &properties)
{
VerifyOpen();

COMMPROP prop;
ZeroMemory(&prop, sizeof(COMMPROP));
::GetCommProperties(m_hCom, &prop);

properties = prop;
}

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru