You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
6.0 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "global.h"
#include "DeviceStr.h"
DeviceStr::DeviceStr()
{
}
DeviceStr::~DeviceStr()
{
CloseDev();
}
void DeviceStr::SetDevType(int type)
{
m_hDev = NULL;
m_ov.hEvent = NULL;
m_printType = type;
}
int DeviceStr::InitStr()
{
return 0;
}
//
int DeviceStr::OpenDev(char * pDev, UINT baud, int type)
{
int iRet;
m_printType = type;
if (m_hDev != NULL)
{
CloseHandle(m_hDev);
m_hDev = NULL;
}
// create events
if (m_ov.hEvent != NULL)
{
ResetEvent(m_ov.hEvent);
}
else
{
m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
switch (type)
{
case PRINTTYPE_COM:
iRet = OpenComDev(pDev, baud);
break;
case PRINTTYPE_LPT:
case PRINTTYPE_USBLPT:
iRet = OpenLptDev(pDev);
break;
default:
return -1;
break;
}
return iRet;
}
//
int DeviceStr::OpenComDev(char * portnr, UINT baud)
{
char parity = 'N'; //奇偶校验
UINT databits = 8; //数据位
UINT stopbits = 1; //停止位
DWORD dwCommEvents = EV_RXCHAR; //消息类型
sprintf(szPort, "\\\\.\\%s", portnr);///可以显示COM10以上端口//add by itas109 2014-01-09
sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);
m_hDev = CreateFile(szPort, // communication port string (COMX)
GENERIC_READ | GENERIC_WRITE, // read/write types
0, // comm devices must be opened with exclusive access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, // Async I/O
0); // template must be 0 for comm devices
///创建失败
if (m_hDev == ((HANDLE)(-1)))
{
m_hDev = NULL;
return -1;
}
// set the timeout values
///设置超时
m_CommTimeouts.ReadIntervalTimeout = 1000;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
m_CommTimeouts.WriteTotalTimeoutConstant = 1000;
if (!SetCommTimeouts(m_hDev, &m_CommTimeouts)) ///设置超时
{
CloseDev();
return -2;
}
if (!SetCommMask(m_hDev, dwCommEvents)) ///设置通信事件
{
CloseDev();
return -3;
}
if (GetCommState(m_hDev, &m_dcb))///获取当前DCB参数
{
m_dcb.EvtChar = 'q';///设置字件字符
m_dcb.fRtsControl = RTS_CONTROL_ENABLE;
if (BuildCommDCB(szBaud, &m_dcb))///填写DCB结构
{
if (!SetCommState(m_hDev, &m_dcb)) ///配置DCB
{
CloseDev();
return -4;
}
}
else
{
CloseDev();
return -4;
}
}
else
{
CloseDev();
return -5;
}
// flush the port
///终止读写并清空接收和发送
PurgeComm(m_hDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
return 0;
}
//
int DeviceStr::OpenLptDev(char * pDev)
{
m_ov.Offset = 0;
m_ov.OffsetHigh = 0;
m_hDev = CreateFile(pDev, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (m_hDev == ((HANDLE)(-1)))
{
m_hDev = NULL;
return -1;
}
return 0;
}
int DeviceStr::WriteToDev(mySendFrame * ptr)
{
BOOL bWrite = TRUE;
BOOL bResult = TRUE;
DWORD BytesSent = 0;
/* DWORD dwError = 0;
if (ClearCommError(m_hDev, &dwError, NULL))
{
PurgeComm(m_hDev, PURGE_TXABORT | PURGE_TXCLEAR);
}
*/
// Clear buffer
Sleep(20);
if (PRINTTYPE_COM == m_printType)
{
PurgeComm(m_hDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
}
m_ov.Offset = 0;
m_ov.OffsetHigh = 0;
///写入
bResult = WriteFile(m_hDev, // Handle to COMM Port
ptr->buf, // Pointer to message buffer in calling finction
// strlen((char*)port->m_szWriteBuffer), // Length of message to send
ptr->iDatalen, // Length of message to send // add by mrlong
&BytesSent, // Where to store the number of bytes sent
&m_ov);
if (bResult)
{
return 0;
}
DWORD dwError = GetLastError();
switch (dwError)
{
case ERROR_IO_PENDING:
// continue to GetOverlappedResults()
BytesSent = 0;
bWrite = FALSE;
break;
default:
// all other error codes
return -1;
break;
}
mySleep(ptr->iDatalen);
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(m_hDev, // Handle to COMM port
&m_ov, // Overlapped structure
&BytesSent, // Stores number of bytes sent
FALSE); // Wait flag
if (0 == bResult)
{
return -2;
}
}
return 0;
}
int DeviceStr::ReadFromDev(mySendFrame * pFrame)
{
COMSTAT comstat;
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
unsigned char RXBuff;
char * ptr;
ptr = pFrame->buf;
bResult = ClearCommError(m_hDev, &dwError, &comstat);
if (comstat.cbInQue == 0)
{
// break out when all bytes have been read
return -1;
}
///串口读出,读出缓冲区中字节
bResult = ReadFile(m_hDev, // Handle to COMM port
&RXBuff, // RX Buffer Pointer
1, // Read one byte
&BytesRead, // Stores number of bytes read
&m_ov); // pointer to the m_ov structure
// deal with the error code
if (bResult)
{
ptr[0] = RXBuff;
pFrame->iDatalen = 1;
return 0;
}
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
// asynchronous i/o is still in progress
// Proceed on to GetOverlappedResults();
///异步IO仍在进行
bRead = FALSE;
break;
}
default:
{
// Another error has occured. Process this error.
return -2;
break;
//return;///防止读写数据时串口非正常断开导致死循环一直执行。add by itas109 2014-01-09 与上面liquanhai添加防死锁的代码差不多
}
}
if (!bRead)
{
bRead = TRUE;
Sleep(50);
bResult = GetOverlappedResult(m_hDev, // Handle to COMM port
&m_ov, // Overlapped structure
&BytesRead, // Stores number of bytes read
FALSE); // Wait flag
// deal with the error code
if (!bResult)
{
return -3;
//port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
}
else
{
ptr[0] = RXBuff;
pFrame->iDatalen = 1;
return 0;
}
} //
return 0;
}
void DeviceStr::CloseDev()
{
if (m_hDev)
{
CloseHandle(m_hDev);
m_hDev = NULL;
}
if (m_ov.hEvent != NULL)
{
CloseHandle(m_ov.hEvent);
m_ov.hEvent = NULL;
}
}
int DeviceStr::mySleep(int iLen)
{
int iTime;
iTime = 100 + iLen * 2;
Sleep(iTime);
return 0;
}