📄 serial.cpp
字号:
LONG CSerial::SetupHandshaking (EHandshake eHandshake)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::SetupHandshaking - Device is not opened\n");
return m_lLastError;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::SetupHandshaking - Unable to obtain DCB information\n");
return m_lLastError;
}
// Set the handshaking flags
switch (eHandshake)
{
case EHandshakeOff:
dcb.fOutxCtsFlow = false; // Disable CTS monitoring
dcb.fOutxDsrFlow = false; // Disable DSR monitoring
dcb.fDtrControl = DTR_CONTROL_DISABLE; // Disable DTR monitoring
dcb.fOutX = false; // Disable XON/XOFF for transmission
dcb.fInX = false; // Disable XON/XOFF for receiving
dcb.fRtsControl = RTS_CONTROL_DISABLE; // Disable RTS (Ready To Send)
break;
case EHandshakeHardware:
dcb.fOutxCtsFlow = true; // Enable CTS monitoring
dcb.fOutxDsrFlow = true; // Enable DSR monitoring
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; // Enable DTR handshaking
dcb.fOutX = false; // Disable XON/XOFF for transmission
dcb.fInX = false; // Disable XON/XOFF for receiving
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; // Enable RTS handshaking
break;
case EHandshakeSoftware:
dcb.fOutxCtsFlow = false; // Disable CTS (Clear To Send)
dcb.fOutxDsrFlow = false; // Disable DSR (Data Set Ready)
dcb.fDtrControl = DTR_CONTROL_DISABLE; // Disable DTR (Data Terminal Ready)
dcb.fOutX = true; // Enable XON/XOFF for transmission
dcb.fInX = true; // Enable XON/XOFF for receiving
dcb.fRtsControl = RTS_CONTROL_DISABLE; // Disable RTS (Ready To Send)
break;
default:
// This shouldn't be possible
_ASSERTE(false);
m_lLastError = E_INVALIDARG;
return m_lLastError;
}
// Set the new DCB structure
if (!::SetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::SetupHandshaking - Unable to set DCB information\n");
return m_lLastError;
}
// Return successful
return m_lLastError;
}
LONG CSerial::SetupReadTimeouts (EReadTimeout eReadTimeout)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::SetupReadTimeouts - Device is not opened\n");
return m_lLastError;
}
// Determine the time-outs
COMMTIMEOUTS cto;
if (!::GetCommTimeouts(m_hFile,&cto))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::SetupReadTimeouts - Unable to obtain timeout information\n");
return m_lLastError;
}
// Set the new timeouts
switch (eReadTimeout)
{
case EReadTimeoutBlocking:
cto.ReadIntervalTimeout = 0;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
break;
case EReadTimeoutNonblocking:
cto.ReadIntervalTimeout = MAXDWORD;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
break;
default:
// This shouldn't be possible
_ASSERTE(false);
m_lLastError = E_INVALIDARG;
return m_lLastError;
}
// Set the new DCB structure
if (!::SetCommTimeouts(m_hFile,&cto))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::SetupReadTimeouts - Unable to set timeout information\n");
return m_lLastError;
}
// Return successful
return m_lLastError;
}
// Posto sam uveo mogucnost za 'user defined' baud rate,
// moram da ga razlikujem od predefinisanih ( enumerisanih ) vrednosti.
bool CSerial::EnumeratedBaudrate(DWORD BaudRate){
if ( BaudRate == (DWORD) EBaud110 ||
BaudRate == (DWORD) EBaud300 ||
BaudRate == (DWORD) EBaud600 ||
BaudRate == (DWORD) EBaud1200 ||
BaudRate == (DWORD) EBaud2400 ||
BaudRate == (DWORD) EBaud4800 ||
BaudRate == (DWORD) EBaud9600 ||
BaudRate == (DWORD) EBaud14400 ||
BaudRate == (DWORD) EBaud19200 ||
BaudRate == (DWORD) EBaud38400 ||
BaudRate == (DWORD) EBaud56000 ||
BaudRate == (DWORD) EBaud57600 ||
BaudRate == (DWORD) EBaud115200 ||
BaudRate == (DWORD) EBaud128000 ||
BaudRate == (DWORD) EBaud256000 )
return true;
else
return false;
}
CSerial::EBaudrate CSerial::GetBaudrate (DWORD& userBaudrate)
{
userBaudrate = 0;
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::GetBaudrate - Device is not opened\n");
return EBaudUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::GetBaudrate - Unable to obtain DCB information\n");
return EBaudUnknown;
}
// Return the appropriate baudrate
// ( ovo je malo modifikovano da bi podrzao 'user defined' baud rate )
userBaudrate = dcb.BaudRate;
if ( EnumeratedBaudrate( dcb.BaudRate ) )
return EBaudrate(dcb.BaudRate);
else {
return EBaudUserDef;
}
}
CSerial::EDataBits CSerial::GetDataBits (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::GetDataBits - Device is not opened\n");
return EDataUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::GetDataBits - Unable to obtain DCB information\n");
return EDataUnknown;
}
// Return the appropriate bytesize
return EDataBits(dcb.ByteSize);
}
CSerial::EParity CSerial::GetParity (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::GetParity - Device is not opened\n");
return EParUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::GetParity - Unable to obtain DCB information\n");
return EParUnknown;
}
// Check if parity is used
if (!dcb.fParity)
{
// No parity
return EParNone;
}
// Return the appropriate parity setting
return EParity(dcb.Parity);
}
CSerial::EStopBits CSerial::GetStopBits (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::GetStopBits - Device is not opened\n");
return EStopUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::GetStopBits - Unable to obtain DCB information\n");
return EStopUnknown;
}
// Return the appropriate stopbits
return EStopBits(dcb.StopBits);
}
DWORD CSerial::GetEventMask (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::GetEventMask - Device is not opened\n");
return 0;
}
// Return the event mask
return m_dwEventMask;
}
BYTE CSerial::GetEventChar (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::GetEventChar - Device is not opened\n");
return 0;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::GetEventChar - Unable to obtain DCB information\n");
return 0;
}
// Set the new event character
return BYTE(dcb.EvtChar);
}
bool CSerial::GetSpeedSettings( DWORD& baudrate, BYTE& databits,
BYTE& paritybits, double& stopbits ){
bool izlaz = true;
// baud rate
EBaudrate ebr = GetBaudrate( baudrate );
if ( ebr == EBaudrate::EBaudUnknown ) {
baudrate = CBR_110; // uzimam najsporiji baud rate da bi dobio najduze vreme prenosa
izlaz = false;
}
// data bits
EDataBits edb = GetDataBits();
if ( edb == EDataBits::EDataUnknown ){
databits = 8;
izlaz = false;
}
else {
databits = (BYTE) edb;
}
// parity bits
EParity epar = GetParity();
if ( epar == EParity::EParNone )
paritybits = 0;
else
paritybits = 1;
if ( epar == EParity::EParUnknown ) {
izlaz = false;
}
// stop bits
EStopBits esb = GetStopBits();
if ( esb == EStopBits::EStop1 ) stopbits = 1.0;
else if ( esb == EStopBits::EStop1_5 ) stopbits = 1.5;
else stopbits = 2.0;
if ( esb == EStopBits::EStopUnknown ){
izlaz = false;
}
return izlaz;
}
CSerial::EHandshake CSerial::GetHandshaking (void)
{
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::GetHandshaking - Device is not opened\n");
return EHandshakeUnknown;
}
// Obtain the DCB structure for the device
CDCB dcb;
if (!::GetCommState(m_hFile,&dcb))
{
// Obtain the error code
m_lLastError = ::GetLastError();
// Display a warning
_RPTF0(_CRT_WARN,"CSerial::GetHandshaking - Unable to obtain DCB information\n");
return EHandshakeUnknown;
}
// Check if hardware handshaking is being used
if ((dcb.fDtrControl == DTR_CONTROL_HANDSHAKE) && (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE))
return EHandshakeHardware;
// Check if software handshaking is being used
if (dcb.fOutX && dcb.fInX)
return EHandshakeSoftware;
// No handshaking is being used
return EHandshakeOff;
}
LONG CSerial::Write (const void* pData, size_t iLen, DWORD* pdwWritten, LPOVERLAPPED lpOverlapped, DWORD dwTimeout)
{
// Overlapped operation should specify the pdwWritten variable
_ASSERTE(!lpOverlapped || pdwWritten);
// Check if time-outs are supported
CheckTimeout(dwTimeout);
// Reset error state
m_lLastError = ERROR_SUCCESS;
// Use our own variable for read count
DWORD dwWritten;
if (pdwWritten == 0)
{
pdwWritten = &dwWritten;
}
// Reset the number of bytes written
*pdwWritten = 0;
// Check if the device is open
if (m_hFile == 0)
{
// Set the internal error code
m_lLastError = ERROR_INVALID_HANDLE;
// Issue an error and quit
_RPTF0(_CRT_WARN,"CSerial::Write - Device is not opened\n");
return m_lLastError;
}
// Wait for the event to happen
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -