Files
Tools_CPP/devices/ComPort.cpp
2024-11-01 12:23:13 +05:00

612 lines
27 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//---------------------------------------------------------------------------
//#pragma hdrstop
//#include "stdafx.h"
//---------------------------------------------------------------------------
#include "ComPort.h"
#include <sstream>
#include <iostream>
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
//#define WIN32_LEAN_AND_MEAN //По моему это для выбора функции поиска файлов по умолчанию
//#define NOMINMAX
#include <windows.h>
//#include <minwinbase.h>
#include <winnt.h>
//#include <fileapi.h>
#else
#include <stdio.h> // standard input / output functions
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitionss
#include <time.h> // time calls
#endif
//#include <stdTools.h>
#include <sstream>
//---------------------------------------------------------------------------
#if defined( _BORLAND )
#pragma package(smart_init)
#endif
//---------------------------------------------------------------------------
/*template <typename T>
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=0;
hCom=0;
ComNumber=1;
BaudRate=115200;
bOpen=false;
}
//------------------------------------------------------------------------------
ComPort::~ComPort()
{
Close();
}
//------------------------------------------------------------------------------
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(std::string ComNumber)
{
if(hCom!=0) Close(); //Если открыт ком порт закроем
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
this->ComNumber=ComNumber;
std::string port="\\\\.\\COM";
port+=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;
#else
hCom = open(ComNumber.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if(hCom== -1)
{
//printf("Unable to open /dev/ttyS0. \n");
std::cout << "Unable to open " << ComNumber << std::endl;
bOpen=false;
}else
{
fcntl(hCom, F_SETFL, 0);
//printf("port is open.\n");
bOpen=true;
}
#endif
return bOpen;
}
//------------------------------------------------------------------------------
bool ComPort::Open(std::wstring ComNumber)
{
std::string str( ComNumber.begin(), ComNumber.end() );
return Open(str);
}
//------------------------------------------------------------------------------
bool ComPort::Close()
{
bool result=true;
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
if(bOpen){
if(CloseHandle(hCom))
{
hCom=0;
bOpen=false;
}
}
#else
if(close(hCom) == -1)
{
hCom=0;
result=false;
}else
{
hCom=0;
bOpen=false;
result=true;
}
#endif
return result;
}
//------------------------------------------------------------------------------
bool ComPort::SetupDCB(int BaudRate,int ByteSize)
{
this->BaudRate = BaudRate;
CheckBaudRate(); //из 1,2,3... в 1200,2400,4800...
#if defined(WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
int RxBufferSize = 2048;
int TxBufferSize = 2048;
if (!SetupComm(hCom, RxBufferSize, TxBufferSize)) return false;
DCB dcb; //Описание в https://ru.wikibooks.org/wiki/COM-порт_в_Windows_(программирование)
memset((void *)&dcb, (int)0, (size_t)sizeof(dcb));
dcb.DCBlength = sizeof(DCB);
if(!GetCommState(hCom, &dcb)){ //Берём текущие настройки из винды
return false;
}
dcb.BaudRate = BaudRate;
dcb.ByteSize = ByteSize;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fAbortOnError = FALSE; // Задает игнорирование всех операций чтения/записи при возникновении ошибки. Если это поле равно TRUE, драйвер прекращает все операции чтения/записи для порта при возникновении ошибки. Продолжать работать с портом можно будет только после устранения причины ошибки и вызова функции ClearCommError.
dcb.fDtrControl = DTR_CONTROL_ENABLE; // Задает режим управления обменом для сигнала DTR.
dcb.fRtsControl = RTS_CONTROL_ENABLE; // Задает режим управления потоком для сигнала RTS
dcb.fBinary = TRUE; // Win32 не поддерживает недвоичный режим, поэтому данное поле всегда должно быть равно 1
dcb.fParity = FALSE; // Включает режим контроля четности. Если это поле равно TRUE, то выполняется проверка четности, при ошибке, в вызывающую программу, выдается соответствующий код завершения.
dcb.fInX = FALSE; // Задает использование XON/XOFF управления потоком при приеме. Если это поле равно TRUE, то драйвер передает символ XoffChar, когда в приемном буфере находится более XoffLim, и XonChar, когда в приемном буфере остается менее XonLim символов.
dcb.fOutX = FALSE; // Задает использование XON/XOFF управления потоком при передаче. Если это поле равно TRUE, то передача останавливается при приеме символа XoffChar, и возобновляется при приеме символа XonChar
dcb.XonChar = 0; // Tx and Rx XON character
dcb.XoffChar = (unsigned char)0xFF; // Tx and Rx XOFF character
dcb.fErrorChar = FALSE; // error replacement character
dcb.fNull = FALSE; //Определяет действие выполняемое при приеме нулевого байта. Если это поле TRUE, то нулевые байты отбрасываются при передаче.
dcb.fOutxCtsFlow = FALSE; //Включает режим слежения за сигналом [[|CTS]]. Если это поле равно [[|TRUE]] и сигнал [[|CTS]] сброшен, передача данных приостанавливается до установки сигнала CTS. Это позволяет подключеному к компьютеру прибору приостановить поток передаваемой в него информации, если он не успевает ее обрабатывать.
dcb.fOutxDsrFlow = FALSE; //Включает режим слежения за сигналом [[|DSR]]. Если это поле равно TRUE и сигнал DSR сброшен, передача данных прекращается до установки сигнала DSR.
dcb.XonLim = 128; //Задает минимальное число символов в приемном буфере перед посылкой символа XON.
dcb.XoffLim = 128; //Определяет максимальное количество байт в приемном буфере перед посылкой символа XOFF. Максимально допустимое количество байт в буфере вычисляется вычитанием данного значения из размера приемного буфера в байтах.
if(!SetCommState(hCom, &dcb)) return false;
#else
#endif
return true;
}
//------------------------------------------------------------------------------
//num - номер настроек под разное оборудование (num=1 то атоловские настройки для ком порта)
bool ComPort::Setup(int num)
{
CheckBaudRate(); //из 1,2,3... в 1200,2400,4800...
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
int RxBufferSize = 2048;
int TxBufferSize = 2048;
if(!SetupComm(hCom, RxBufferSize, TxBufferSize)) return false;
DCB dcb;
memset(&dcb,0,sizeof(dcb));
dcb.DCBlength = sizeof (DCB);
GetCommState(hCom,&dcb); //Берём текущие настройки из винды
dcb.BaudRate=BaudRate;
if(num==-1) //Настройки для Фрезерного станка с ЧПУ
{
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fAbortOnError = TRUE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
dcb.fInX = FALSE;
dcb.fOutX = FALSE;
dcb.XonChar = 0;
dcb.XoffChar = (unsigned char)0xFF;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE; //Определяет действие выполняемое при приеме нулевого байта. Если это поле TRUE, то нулевые байты отбрасываются при передаче.
dcb.fOutxCtsFlow = FALSE; //Включает режим слежения за сигналом [[|CTS]]. Если это поле равно [[|TRUE]] и сигнал [[|CTS]] сброшен, передача данных приостанавливается до установки сигнала CTS. Это позволяет подключеному к компьютеру прибору приостановить поток передаваемой в него информации, если он не успевает ее обрабатывать.
dcb.fOutxDsrFlow = FALSE; //Включает режим слежения за сигналом [[|DSR]]. Если это поле равно TRUE и сигнал DSR сброшен, передача данных прекращается до установки сигнала DSR.
dcb.XonLim = 128; //Задает минимальное число символов в приемном буфере перед посылкой символа XON.
dcb.XoffLim = 128; //Определяет максимальное количество байт в приемном буфере перед посылкой символа XOFF. Максимально допустимое количество байт в буфере вычисляется вычитанием данного значения из размера приемного буфера в байтах.
}
else if(num==0) //Настройки для ПОРТ 300 100
{
//if(!GetCommState(hCom, &dcb)) return false;
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
{
dcb.DCBlength = sizeof (DCB);
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.ByteSize=8;
dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT;
dcb.fDtrControl=DTR_CONTROL_ENABLE;
}else
if(num==3) //Настройки для дисплея покупателя WINCOR NIXDORF
{
dcb.ByteSize=8;
dcb.fBinary=1;
//Проверка чётности
dcb.fParity=TRUE;
dcb.Parity=ODDPARITY;
dcb.StopBits=ONESTOPBIT;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
//dcb.fDtrControl=DTR_CONTROL_ENABLE;
}else //Свои настройки
{
if(!GetCommState(hCom, &dcb)) return false; //Берём текущие настройки
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;
#else
int result=-1;
struct termios tty; // structure to store the port settings in
memset (&tty, 0, sizeof tty);
if (tcgetattr (hCom, &tty) != 0)
{
std::cout << "Error read serial port config." << std::endl;
return false;
}
switch(BaudRate)
{
case 1200:
result = cfsetospeed(&tty, B1200);
break;
case 1800:
result = cfsetospeed(&tty, B1800);
break;
case 2400:
result = cfsetospeed(&tty, B2400);
break;
case 4800:
result = cfsetospeed(&tty, B4800);
break;
case 9600:
result = cfsetospeed(&tty, B9600);
break;
case 19200:
result = cfsetospeed(&tty, B19200);
break;
case 38400:
result = cfsetospeed(&tty, B38400);
break;
case 57600:
result = cfsetospeed(&tty, B57600);
break;
case 115200:
result = cfsetospeed(&tty, B115200);
break;
default:
cfsetospeed(&tty, BaudRate);
}
if(result == -1)
{
std::cout << "Error set baud rate \"" << BaudRate << "\"." << std::endl;
}
if(num==0) //Настройки для ПОРТ 300 100
{
//Отключаю "канонический" режим те. возможность редактирования в буфере до получения символа /r или /n
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/*tty.c_lflag &= ~ICANON; // Don't canonicalise
tty.c_lflag &= ~ECHO; // Don't echo
tty.c_lflag &= ~ECHOK; // Don't echo
tty.c_lflag &= ~ECHOE;*/
//Similarly, to disable hardware flow control:
//tty.c_cflag &= ~CNEW_RTSCTS;
// set no parity, stop bits, data bits
tty.c_cflag &= ~PARENB;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; //Размер байта
/*
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
// disable IGNBRK for mismatched speed tests; otherwise receive break
// as \000 chars
tty.c_iflag &= ~IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= 0; //parity; no parity
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
*/
}
if(tcsetattr(hCom, TCSANOW, &tty) != 0)
{
std::cout << "Error set attributes." << std::endl;
return -1;
}
#endif
return true;
}
//------------------------------------------------------------------------------
//Если time=0 то не ждет данные и с разу выдает все что в буфере
//Если задать миллисекунды то это время доожидания следующего байта (не ставить меньше 10 миллисекунд)
//Операция чтения работает асинхронно те. не ждёт данные за временем нужно следить самому ! (читать байты в цикле с задержкой)
//Подробное оисание: http://www.vsokovikov.narod.ru/New_MSDN_API/Comm_res/str_commtimeouts.htm
//time - время в миллисекундах (не ставить меньше 10 миллисекунд)
bool ComPort::SetTimeout(unsigned long time)
{
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
COMMTIMEOUTS CommTimeouts;
CommTimeouts.ReadIntervalTimeout = time; //Максимальное время, которое допускается для интервала между поступлением двух символов в миллисекундах (отсчёт после первого символа)
CommTimeouts.ReadTotalTimeoutMultiplier = 0; //Множитель умножается на число проч. байтов получаются милисекунды которые прибовляются к нижнему
CommTimeouts.ReadTotalTimeoutConstant = time; //Это время простоя прибавляется к (ReadTotalTimeoutMultiplier * кол-во прочитанных байт)
CommTimeouts.WriteTotalTimeoutMultiplier = 0; //Множитель умножается на число зап. байтов получаются милисекунды которые прибовляются к нижнему
CommTimeouts.WriteTotalTimeoutConstant = 0; //Это время простоя для записи прибавляется к (WriteTotalTimeoutMultiplier * кол-во записанных байт)
/*
CommTimeouts.ReadIntervalTimeout = MAXDWORD; //Максимальное время, которое допускается для интервала между поступлением двух символов
CommTimeouts.ReadTotalTimeoutMultiplier = 0; //Множитель умножается на число проч. байтов получаются милисекунды которые прибовляются к нижнему
CommTimeouts.ReadTotalTimeoutConstant = time; //Это время простоя прибавляется к (ReadTotalTimeoutMultiplier * кол-во прочитанных байт)
CommTimeouts.WriteTotalTimeoutMultiplier = 0; //Множитель умножается на число зап. байтов получаются милисекунды которые прибовляются к нижнему
CommTimeouts.WriteTotalTimeoutConstant = time; //Это время простоя для записи прибавляется к (WriteTotalTimeoutMultiplier * кол-во записанных байт)
*/
return SetCommTimeouts(hCom, &CommTimeouts)!=0; //В MSDN так написанно
#else
struct termios termios;
tcgetattr(hCom, &termios);
termios.c_cc[VMIN] = 0; //Не учитываем кол-во байт а только время
termios.c_cc[VTIME] = time/10.0f; //Время в 0.1 секунду поэтому разделил на 10
tcsetattr(hCom, TCSANOW, &termios);
#endif
return true;
}
//------------------------------------------------------------------------------
//Записать буфер в COM порт
unsigned long ComPort::Write(const void* lpBuffer,unsigned long nNumberOfBytesToWrite)
{
if (nNumberOfBytesToWrite == 0) return 0; //А то через блютуз подвисало
unsigned long lpNumberOfBytesWritten=0;
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
WriteFile(hCom, lpBuffer, nNumberOfBytesToWrite, &lpNumberOfBytesWritten, NULL);
#else
lpNumberOfBytesWritten = write(hCom,lpBuffer,nNumberOfBytesToWrite);
#endif
return lpNumberOfBytesWritten;
}
//------------------------------------------------------------------------------
//Записать строку в COM порт
unsigned long ComPort::WriteString(std::string str)
{
return Write(str.c_str(),str.length());
}
//------------------------------------------------------------------------------
//Записать 1 байт в COM порт
unsigned char ComPort::WriteChar(signed char ch)
{
return (unsigned char)Write(&ch,1);
}
//------------------------------------------------------------------------------
unsigned char ComPort::WriteUChar(unsigned char ch)
{
return (unsigned char)Write(&ch,1);
}
//------------------------------------------------------------------------------
unsigned char ComPort::WriteUInt(unsigned int val)
{
return (unsigned char)Write(&val,4);
}
//------------------------------------------------------------------------------
//Прочитать байты из COM порта в буфер
int ComPort::Read(void* lpBuffer,unsigned long nNumberOfBytesToRead)
{
int result=0;
if (nNumberOfBytesToRead == 0) return 0;
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
unsigned long lpNumberOfBytesRead;
BOOL error = ReadFile(hCom, lpBuffer, nNumberOfBytesToRead, &lpNumberOfBytesRead, NULL);
if (!error) {
result=-1; // Указание на ошибку
}else{
result = lpNumberOfBytesRead;
}
#else
result = read(hCom, lpBuffer, nNumberOfBytesToRead);
#endif
return result;
}
//------------------------------------------------------------------------------
//Так как может выдавать данные порциями
int ComPort::ReadAll(void* lpBuffer, unsigned long nNumberOfBytesToRead) {
if (nNumberOfBytesToRead == 0) return 0;
DWORD len=0;
int pos = 0;
while (true) {
ReadFile(hCom, lpBuffer, nNumberOfBytesToRead, &len, NULL);
if (len <= 0) break;
pos += len;
nNumberOfBytesToRead -= len;
if (nNumberOfBytesToRead == 0)
break;
}
return pos;
}
//------------------------------------------------------------------------------
//Читать до символа и этот символ в результат не входит
int ComPort::ReadUntilChar(void* lpBuffer, unsigned long maxLen, char suffix,bool* error){
*error=true;
if(maxLen == 0) return 0;
unsigned long pos=0;
char ch;
while (true) {
if(Read(&ch, 1)!=1){
break;
}else{
if(ch==suffix){
*error=false;
break;
}
((char*)lpBuffer)[pos]=ch;
pos++;
if(maxLen==pos){
break;
}
}
}
return pos;
}
//------------------------------------------------------------------------------
//Прочитать байт из ком порта
unsigned char ComPort::ReadUInt1(bool* b)
{
unsigned char result=0;
if(Read(&result, 1)!=1)
*b=false;
else
*b=true;
return result;
}
//------------------------------------------------------------------------------