первый
This commit is contained in:
611
devices/ComPort.cpp
Normal file
611
devices/ComPort.cpp
Normal file
@ -0,0 +1,611 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//#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;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user