Soap 2day.

Форум — Ответы     (  К темам )
 ?  _Владимир_: Модуль для работы с COM-портом. (21-05-2003 16:50:59)
Вот h и c++ файлы, которые образуют модуль для работы
с COM-портом. Написал я это на API под VisualC++.
Это можно без труда портировать в Builder.

//**** h file********************************************

typedef struct _COM_ST
{
BYTE parity;
BYTE stop_bits;
BYTE byte_size;
DWORD baud;
BYTE num;
}COM_ST;

class CCom
{
COMMTIMEOUTS timeouts;
DWORD dws;
COMMCONFIG commcon;
HANDLE hCom;
public:
bool IsOpen();
void Escape(DWORD func);
BOOL Write(BYTE *s, BYTE len);
BOOL Read(BYTE *s, WORD len);
void Purge();
void Destroy();
BOOL Create(COM_ST &st);
CCom();
virtual ~CCom();

private:
void DtrHigh();
void DtrLow();
void RtsHigh();
void RtsLow();
BYTE num;
bool opened;
};

//**** C++ file********************************************
#include "stdafx.h"
#include "Com.h"


#define MAX_RX_BUF_SIZE 12000
#define MAX_TX_BUF_SIZE 2048
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCom::CCom()
{
hCom=0;
opened=false;
}

CCom::~CCom()
{

}

BOOL CCom::Create(COM_ST &st)
{
if(true==opened) return FALSE;

char str[5];
switch(st.num)
{
case 1: num=1; strcpy(str, "COM1"); break;
case 2: num=2; strcpy(str, "COM2"); break;
default: return FALSE;
}

hCom=::CreateFile(str,
GENERIC_WRITE|GENERIC_READ,
NULL,
NULL,
OPEN_EXISTING,
0,
NULL);
//----------------------------------------------
if(hCom==INVALID_HANDLE_VALUE)
{ DWORD dwErr=GetLastError(); return FALSE; }
//--------Test for capability--------------------
COMMPROP CommProp;
BOOL m_Bool=GetCommProperties(hCom, &CommProp);
if(FALSE==m_Bool)
{ CloseHandle(hCom); return FALSE; }

if(PST_RS232!=CommProp.dwProvSubType)
{ CloseHandle(hCom); return FALSE; }
if((PCF_INTTIMEOUTS|PCF_TOTALTIMEOUTS)!=
(CommProp.dwProvCapabilities&
(PCF_INTTIMEOUTS|PCF_TOTALTIMEOUTS)))
{ CloseHandle(hCom); return FALSE; }
if((SP_BAUD|SP_DATABITS|SP_HANDSHAKING|SP_PARITY|
SP_PARITY_CHECK|SP_RLSD|SP_STOPBITS)!=
(CommProp.dwSettableParams&
(SP_BAUD|SP_DATABITS|SP_HANDSHAKING|SP_PARITY|
SP_PARITY_CHECK|SP_RLSD|SP_STOPBITS)))
{ CloseHandle(hCom); return FALSE; }
if(DATABITS_8!=(CommProp.wSettableData&DATABITS_8))
{ CloseHandle(hCom); return FALSE; }
if((STOPBITS_10|PARITY_NONE)!=
(CommProp.wSettableStopParity&
(STOPBITS_10|PARITY_NONE)))
{ CloseHandle(hCom); return FALSE; }

if(st.baud>CommProp.dwMaxBaud)
{ CloseHandle(hCom); return FALSE; }
if(!(st.baud&CommProp.dwSettableBaud))
{ CloseHandle(hCom); return FALSE; }


//Buffer size------------------------------------
SetupComm(hCom, MAX_RX_BUF_SIZE, MAX_TX_BUF_SIZE);



//--------SetCommConfig--------------------------
COMMCONFIG local_commcon;
DWORD local_dws;
GetCommConfig(hCom, &local_commcon, &local_dws);
GetCommConfig(hCom, &commcon, &dws);


local_commcon.dwProviderSubType =PST_RS232;
local_commcon.dcb.BaudRate =st.baud;
if(NOPARITY==st.parity)
local_commcon.dcb.fParity=FALSE;
else
local_commcon.dcb.fParity=TRUE;


local_commcon.dcb.fOutX =FALSE;
local_commcon.dcb.fInX =FALSE;
local_commcon.dcb.fOutxCtsFlow =FALSE;
local_commcon.dcb.fOutxDsrFlow =FALSE;
local_commcon.dcb.fDtrControl =DTR_CONTROL_DISABLE;
local_commcon.dcb.fRtsControl =RTS_CONTROL_DISABLE;
local_commcon.dcb.fOutxCtsFlow =FALSE;
local_commcon.dcb.fOutxDsrFlow =FALSE;
local_commcon.dcb.fDsrSensitivity =FALSE;
local_commcon.dcb.ByteSize =st.byte_size;
local_commcon.dcb.Parity =st.parity;
local_commcon.dcb.StopBits =st.stop_bits;

SetCommConfig(hCom, &local_commcon, local_dws);

//---------COM TimeOuts------------------------------

COMMTIMEOUTS local_timeouts;
GetCommTimeouts(hCom, &local_timeouts);
GetCommTimeouts(hCom, &timeouts);

local_timeouts.ReadIntervalTimeout=0;
local_timeouts.ReadTotalTimeoutMultiplier=10;
local_timeouts.ReadTotalTimeoutConstant=0;

SetCommTimeouts(hCom, &local_timeouts);

opened=true;

return TRUE;
}

void CCom::Destroy()
{
if((false==opened)||(0==hCom)) return;
SetCommConfig(hCom, &commcon, dws);
SetCommTimeouts(hCom, &timeouts);
CloseHandle(hCom);
opened=false;
}

void CCom::Purge()
{
PurgeComm(hCom, PURGE_TXCLEAR|PURGE_RXCLEAR);
}

BOOL CCom::Read(BYTE *s, WORD len)
{
if(!s) return FALSE;
if(!len) return TRUE;

DWORD dw;
BOOL m_Bool=::ReadFile(hCom, s, len, &dw, NULL);
if(len!=dw) m_Bool=FALSE;

return m_Bool;
}

BOOL CCom::Write(BYTE *s, BYTE len)
{
if(!s) return FALSE;
if(!len) return TRUE;

DWORD dw;
BOOL m_Bool=::WriteFile(hCom, s, len, &dw, NULL);
if(len!=dw) m_Bool=FALSE;

return m_Bool;
}


void CCom::Escape(DWORD func)
{
EscapeCommFunction(hCom, func);
}

void CCom::RtsLow()
{
EscapeCommFunction(hCom, CLRRTS);
}

void CCom::RtsHigh()
{
EscapeCommFunction(hCom, SETRTS);
}

void CCom::DtrLow()
{
EscapeCommFunction(hCom, CLRDTR);
}

void CCom::DtrHigh()
{
EscapeCommFunction(hCom, SETDTR);
}

bool CCom::IsOpen()
{
return opened;
}
 Георгий (21-05-2003 21:36:35)
спасибо за заботу о нуждающихся, но в FAQ вроде был какой — то обьект для работы с тем, что выглядит как RS 232. так же надо отметить отсутствие возможности настройти временных характеристик и присутствие приверки возможностей порта (до такой вещи я сам не додумался), но это разве не ухудшит переносимость обьекта?
 _Владимир_ (21-05-2003 22:28:01)
Конечно этот модуль не является универсальным
а поэтому удобным во всех случаях. Это код из
живой программы, заточенный на конкретику.
Ему далеко до универсального компонента.
Думаю что код только поможет разобраться
с тем как работать с портом.