//--------------------------------------------------------------------------- #pragma hdrstop #include "stdafx.h" //--------------------------------------------------------------------------- #include "ComPort.h" #include "Windows.h" #include //#include #include //--------------------------------------------------------------------------- #if defined( _BORLAND ) #pragma package(smart_init) #endif //--------------------------------------------------------------------------- /*template std::string toString2(T val) { std::ostringstream oss; oss << val; return oss.str(); }*/ //--------------------------------------------------------------------------- /*std::string getComName(int num) { // if(num<10) return "COM"+IntToStr(num); // else return "\\\\.\\COM"+toString2(num); }*/ //------------------------------------------------------------------------------ ComPort::ComPort() { m_time=500; //Время по умолчанию hCom=0; ComNumber=1; BaudRate=115200; bOpen=false; } //------------------------------------------------------------------------------ ComPort::~ComPort() { } //------------------------------------------------------------------------------ void ComPort::CheckBaudRate() { if(BaudRate==0) BaudRate=1200; if(BaudRate==1) BaudRate=2400; if(BaudRate==2) BaudRate=4800; if(BaudRate==3) BaudRate=9600; if(BaudRate==4) BaudRate=19200; if(BaudRate==5) BaudRate=38400; if(BaudRate==6) BaudRate=57600; if(BaudRate==7) BaudRate=115200; } //------------------------------------------------------------------------------ bool ComPort::Open(int ComNumber) { if(hCom!=0) Close(); //Если открыт ком порт закроем this->ComNumber=ComNumber; std::string port="\\\\.\\COM"; port+=IntToStdStr(ComNumber); hCom = CreateFileA(port.c_str(), GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hCom == INVALID_HANDLE_VALUE) bOpen=false; else bOpen=true; return bOpen; } //------------------------------------------------------------------------------ bool ComPort::Close() { CloseHandle(hCom); if(hCom == INVALID_HANDLE_VALUE){ hCom=0; return false; } else { hCom=0; bOpen=false; return true; } } //------------------------------------------------------------------------------ //num - номер настроек под разное оборудование (num=1 то атоловские настройки для ком порта) bool ComPort::Setup(int num) { CheckBaudRate(); //из 1,2,3... в 1200,2400,4800... int RxBufferSize = 2048; int TxBufferSize = 2048; if(!SetupComm(hCom, RxBufferSize, TxBufferSize)) return false; DCB dcb; if(num==0) //Настройки для ПОРТ 300 100 { //if(!GetCommState(hCom, &dcb)) return false; memset(&dcb,0,sizeof(dcb)); dcb.DCBlength = sizeof (DCB); dcb.BaudRate=BaudRate; dcb.fBinary=1; //dcb.fDtrControl=DTR_CONTROL_ENABLE; //Без этого 0x03 не принималось с принтера а потом начала принимать и без... dcb.fRtsControl=RTS_CONTROL_ENABLE; dcb.XonLim=2048; dcb.XoffLim=512; dcb.ByteSize=8; dcb.XonChar=17; dcb.XoffChar=19; }else if(num==1) //Настройки для Аура-01ФР-KZ { memset(&dcb,0,sizeof(dcb)); dcb.DCBlength = sizeof (DCB); dcb.BaudRate=BaudRate; dcb.fBinary=1; dcb.XonLim=2048; dcb.XoffLim=512; dcb.ByteSize=8; dcb.XonChar=17; dcb.XoffChar=19; }else if(num==2) //Настройки для CashCode { if(!GetCommState(hCom, &dcb)) return false; dcb.BaudRate=BaudRate; dcb.ByteSize=8; dcb.Parity=NOPARITY; dcb.StopBits=ONESTOPBIT; dcb.fDtrControl=DTR_CONTROL_ENABLE; }else //Свои настройки { memset(&dcb,0,sizeof(dcb)); if(!GetCommState(hCom, &dcb)) return false; //Берём текущие настройки dcb.BaudRate = BaudRate; // Current baud rate (115200) dcb.fBinary = TRUE; // В винде только двоичный режим всегда 1 dcb.fParity = TRUE; // Если этот член структуры - ИСТИНА (TRUE), выполняется проверка четности и сообщается об ошибках... dcb.ByteSize = 8; // Number of bits/byte, 4-8 dcb.Parity = NOPARITY; // Используемая схема четности. (EVENPARITY Проверка по четности MARKPARITY Проверка четности по метке NOPARITY Без проверки четности ODDPARITY Проверка по нечетности SPACEPARITY Проверка четности по паузе) dcb.fTXContinueOnXoff = FALSE; // Если FALSE то будет следить за переполнением принимающего буфера. dcb.fNull = TRUE; dcb.StopBits = ONESTOPBIT; /*EFlowControl fc; switch (fc) { case ENoFlowControl: // No HandShaking { dcb.fOutxCtsFlow = FALSE; // Disable CTS(Clear To Send) monitoring dcb.fOutxDsrFlow = FALSE; // Disable DSR(Data Set Ready) monitoring dcb.fDtrControl = DTR_CONTROL_DISABLE; //Сигнал DTR (готовности терминала к передаче данных) управления потоком данных. Этот член структуры может быть одним из следующих значений. //DTR_CONTROL_ENABLE Включает линию DTR, когда устройство открывается и оставляет ее включенной. //DTR_CONTROL_HANDSHAKE Отключает линию DTR, когда устройство открывается и оставляет ее заблокированной. //DTR_CONTROL_DISABLE Включает процедуру установления связи DTR. Если процедура установления связи включена, она является ошибкой для приложения, которое корректировать линию, используя функцию EscapeCommFunction. dcb.fRtsControl = RTS_CONTROL_DISABLE; // Disable RTS (Ready To Send) monitoring dcb.fOutX = FALSE; // Disable XON/XOFF for transmission (Управление потоком (это своойство есть в гипертерминале)) dcb.fInX = FALSE; // Disable XON/XOFF for receiving break; } case EXonXoffFlowControl: // Software Handshaking { dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fOutX = TRUE; dcb.fInX = TRUE; dcb.XonChar = 0x11; dcb.XoffChar = 0x13; dcb.XoffLim = 100; dcb.XonLim = 100; break; } case EFullHardwareFlowControl: // Hardware Handshaking {*/ dcb.fOutxCtsFlow = TRUE; dcb.fOutxDsrFlow = TRUE; dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; dcb.fOutX = FALSE; dcb.fInX = FALSE; /*} case ECtsRtsFlowControl: { dcb.fOutxCtsFlow = TRUE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; dcb.fOutX = FALSE; dcb.fInX = FALSE; break; } case ECtsDtrFlowControl: { dcb.fOutxCtsFlow = TRUE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fOutX = FALSE; dcb.fInX = FALSE; break; } case EDsrRtsFlowControl: { dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = TRUE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; dcb.fOutX = FALSE; dcb.fInX = FALSE; break; } case EDsrDtrFlowControl: { dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = TRUE; dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fOutX = FALSE; dcb.fInX = FALSE; break; } default: { RETAILMSG(1,(_T("CSerial::Setup - %s flow control assigned Failed!!"), sPort)); return; } }*/ } if(!SetCommState(hCom, &dcb)) return false; //Заебался и по умолчанию сделал асинхронно (операция чтени Read не ждёт данные и за временем нужно следить самому). if(!SetTimeout(m_time)) return false; return true; } //------------------------------------------------------------------------------ //Сколько ждать данных в миллисекундах (Для чтения и запииси) //Операция чтения работает асинхронно те. не ждёт данные за временем нужно следить самому ! (читать байты в цикле с задержкой) bool ComPort::SetTimeout(unsigned long time) { m_time=time; COMMTIMEOUTS CommTimeouts; /* CommTimeouts.ReadIntervalTimeout = MAXDWORD; //Максимальное время, которое допускается для интервала между поступлением двух символов CommTimeouts.ReadTotalTimeoutMultiplier = 0; //Множитель умножается на число проч. байтов получаются милисекунды которые прибовляются к нижнему CommTimeouts.ReadTotalTimeoutConstant = time; //Это время простоя прибавляется к (ReadTotalTimeoutMultiplier * кол-во прочитанных байт) CommTimeouts.WriteTotalTimeoutMultiplier = 0; //Множитель умножается на число зап. байтов получаются милисекунды которые прибовляются к нижнему CommTimeouts.WriteTotalTimeoutConstant = time; //Это время простоя для записи прибавляется к (WriteTotalTimeoutMultiplier * кол-во записанных байт) */ CommTimeouts.ReadIntervalTimeout = 400; CommTimeouts.ReadTotalTimeoutMultiplier = 0; CommTimeouts.ReadTotalTimeoutConstant = 400; CommTimeouts.WriteTotalTimeoutMultiplier = 0; CommTimeouts.WriteTotalTimeoutConstant = 400; return SetCommTimeouts(hCom, &CommTimeouts)!=0; //В MSDN так написанно } //------------------------------------------------------------------------------ /*bool ComPort::setBaudRate() { CheckBaudRate(); //Чтоб скорость была в //TDCB dcb; DCB dcb; if(!GetCommState(hCom, &dcb)) return false; dcb.BaudRate=BaudRate; dcb.ByteSize=8; dcb.Parity=NOPARITY; dcb.StopBits=ONESTOPBIT; // dcb.Flags=DTR_CONTROL_ENABLE; dcb.fDtrControl=DTR_CONTROL_ENABLE; if(!SetCommState(hCom, &dcb)) return false; return true; }*/ //------------------------------------------------------------------------------ //Записать буфер в COM порт unsigned long ComPort::Write(const void* lpBuffer,unsigned long nNumberOfBytesToWrite) { unsigned long lpNumberOfBytesWritten; WriteFile(hCom, lpBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, NULL); return lpNumberOfBytesWritten; } //------------------------------------------------------------------------------ //Записать строку в COM порт unsigned long ComPort::WriteString(std::string str) { return Write(str.c_str(),str.length()); } //------------------------------------------------------------------------------ //Записать 1 байт в COM порт char ComPort::WriteChar(char ch) { return (char)Write(&ch,1); } //------------------------------------------------------------------------------ //Прочитать байты из COM порта в буфер unsigned long ComPort::Read(void* lpBuffer,unsigned long nNumberOfBytesToRead) { unsigned long lpNumberOfBytesRead; ReadFile(hCom, lpBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead, NULL); if(nNumberOfBytesToRead>255) throw "(ComPort::Read) Переполнение буфера!"; return lpNumberOfBytesRead; } //------------------------------------------------------------------------------