Форум — Ответы ( К темам )
? | _Владимир_: Модуль для работы с 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) | |
Конечно этот модуль не является универсальным а поэтому удобным во всех случаях. Это код из живой программы, заточенный на конкретику. Ему далеко до универсального компонента. Думаю что код только поможет разобраться с тем как работать с портом. |