123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- #include "StdAfx.h"
- #include "SynSerial.h"
- CSynSerial::CSynSerial(void) :m_hSerialPort(NULL)
- , m_dwInQueue(1024)
- , m_dwOutQueue(1024)
- {
- memset(&m_dcb, 0, sizeof(DCB));
- memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
- memset(&m_szSerialPort, 0, sizeof(TCHAR)*MAX_PORT_LEN);
- }
- CSynSerial::~CSynSerial(void)
- {
- CloseSerialPort();
- }
- BOOL CSynSerial::OpenSerialPort(IN CONST BYTE & byCommPort, IN CONST DWORD & dwBaudRate, IN CONST BYTE & bySize, IN CONST BYTE & byParity, IN CONST BYTE & byStopBits, IN CONST BYTE & byStartAddr, IN CONST INT & nInterval)
- {
- ASSERT(byCommPort);
- CloseSerialPort();
- _stprintf_s(m_szSerialPort, _T("\\\\.\\com%d"), (int)byCommPort);
- m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL);
- if (m_hSerialPort == INVALID_HANDLE_VALUE)
- {
- // 打开串口失败;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- BOOL bResult = FALSE;
- // SetupComm设置缓冲区大小;
- bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 在串口读写之前,清除缓冲区;
- bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // GetCommState获取设备控制块状态;
- memset(&m_dcb, 0, sizeof(DCB));
- bResult = GetCommState(m_hSerialPort, &m_dcb);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- m_dcb.Parity = byParity;
- if (m_dcb.Parity == NOPARITY)
- m_dcb.fParity = FALSE;
- else
- m_dcb.fParity = TRUE;
- m_dcb.BaudRate = dwBaudRate;
- m_dcb.ByteSize = bySize;
- m_dcb.StopBits = byStopBits;
- if (m_dcb.ByteSize == 8)
- m_dcb.StopBits = ONESTOPBIT;
- // SetCommState设置设备的控制块状态;
- memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
- bResult = SetCommState(m_hSerialPort, &m_dcb);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 获取设备的超时值;
- bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 两字符之间最大的延时,设置0表示参数不起作用;
- m_cts.ReadIntervalTimeout = 50;
- m_cts.ReadTotalTimeoutMultiplier = 100;
- m_cts.ReadTotalTimeoutConstant = 8000;
- m_cts.WriteTotalTimeoutMultiplier = 100;
- m_cts.WriteTotalTimeoutConstant = 5000;
- // 设置设备的超时值;
- bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- return TRUE;
- }
- BOOL CSynSerial::ReOpenSerialPort()
- {
- ASSERT(_tcslen(m_szSerialPort));
- CloseSerialPort();
- m_hSerialPort = CreateFile(m_szSerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL);
- if (m_hSerialPort == INVALID_HANDLE_VALUE)
- {
- // 打开串口失败;
- DWORD dwError = GetLastError();
- return FALSE;
- }
- BOOL bResult = FALSE;
- // SetupComm设置缓冲区大小;
- bResult = SetupComm(m_hSerialPort, m_dwInQueue, m_dwOutQueue);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 在串口读写之前,清除缓冲区;
- bResult = PurgeComm(m_hSerialPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // SetCommState设置设备的控制块状态;
- memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
- bResult = SetCommState(m_hSerialPort, &m_dcb);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 设置设备的超时值;
- bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- return TRUE;
- }
- void CSynSerial::CloseSerialPort()
- {
- if (m_hSerialPort != NULL && m_hSerialPort != INVALID_HANDLE_VALUE)
- CloseHandle(m_hSerialPort);
- m_hSerialPort = NULL;
- }
- BOOL CSynSerial::SetSerialPort(IN CONST DWORD & dwBaudRate, IN CONST BYTE & byByteSize, IN CONST BYTE & byParity, IN CONST BYTE & byStopBits, IN CONST BYTE & byStartAddr, IN CONST DWORD & dwInQueue, IN CONST DWORD & dwOutQueue)
- {
- if (!IsOpen())
- return FALSE;
- BOOL bResult = FALSE;
- // GetCommState获取设备控制块状态;
- memset(&m_dcb, 0, sizeof(DCB));
- bResult = GetCommState(m_hSerialPort, &m_dcb);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- m_dcb.Parity = byParity;
- if (m_dcb.Parity == NOPARITY)
- m_dcb.fParity = FALSE;
- else
- m_dcb.fParity = TRUE;
- m_dcb.BaudRate = dwBaudRate;
- m_dcb.ByteSize = byByteSize;
- m_dcb.StopBits = byStopBits;
- if (m_dcb.ByteSize == 8)
- m_dcb.StopBits = ONESTOPBIT;
- // SetCommState设置设备的控制块状态;
- memset(&m_cts, 0, sizeof(COMMTIMEOUTS));
- bResult = SetCommState(m_hSerialPort, &m_dcb);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 获取设备的超时值;
- bResult = GetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- // 两字符之间最大的延时,设置0表示参数不起作用;
- m_cts.ReadIntervalTimeout = 50;
- m_cts.ReadTotalTimeoutMultiplier = 100;
- m_cts.ReadTotalTimeoutConstant = 8000;
- m_cts.WriteTotalTimeoutMultiplier = 100;
- m_cts.WriteTotalTimeoutConstant = 3000;
- // 设置设备的超时值;
- bResult = SetCommTimeouts(m_hSerialPort, &m_cts);
- if (!bResult)
- {
- DWORD dwError = GetLastError();
- return FALSE;
- }
- return TRUE;
- }
- void CSynSerial::SetSerialDCB(IN CONST DCB & dcb)
- {
- }
- void CSynSerial::SetSerialCommTimeouts(IN CONST COMMTIMEOUTS & commTimeouts)
- {
- }
- DWORD CSynSerial::WriteComm(IN BYTE * pWirteBuf, IN CONST INT32 nWriteSize)
- {
- if (!IsOpen())
- return 0;
- if (pWirteBuf == NULL || !::AfxIsValidAddress(pWirteBuf, nWriteSize, FALSE))
- {
- return 0;
- }
-
- DWORD dwErrorFlags;
- DWORD dwBytesWritten = 0; // 实际写入的字节数;
- // 写前, 清除错误;
- COMSTAT ComStat;
- ClearCommError(m_hSerialPort, &dwErrorFlags, &ComStat);
- // 写前,清空缓存区;
- PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
- if ( !WriteFile(m_hSerialPort, pWirteBuf, nWriteSize, &dwBytesWritten, NULL) )
- {
- DWORD dwError = GetLastError();
- }
- // 返回写入字节数;
- return dwBytesWritten;
- }
- DWORD CSynSerial::ReadComm(IN BYTE * pReadBuf, IN CONST DWORD & dwReadSize)
- {
- if (!IsOpen())
- return 0;
- if (pReadBuf == NULL || !::AfxIsValidAddress(pReadBuf, dwReadSize, FALSE))
- {
- return 0;
- }
- DWORD dwBytesRead = 0;
- DWORD dwErrorFlags = 0;
- // ReadFile前,使用ClearCommError清除错误;
- COMSTAT ComStat = {0};
- DWORD dwLastLen = 0;
- ULONGLONG ulTick = GetTickCount64();
- // 直到有数据为止,超时3秒;
- while (true)
- {// cbInQue表示输入缓冲区的字节数;
- Sleep(300);
- if (GetTickCount64() - ulTick > 3000)
- break;
- ClearCommError(m_hSerialPort, &dwErrorFlags, &ComStat);
- // 防止读一次没读完,再读一次;二次长度一样表示读完;
- if (ComStat.cbInQue != 0 && dwLastLen == ComStat.cbInQue)
- break;
- dwLastLen = ComStat.cbInQue;
- }
- if (ComStat.cbInQue == 0)
- {
- // 串口超时,无数据返回;
- return 0;
- }
- dwBytesRead = ComStat.cbInQue;
- if (dwReadSize < dwBytesRead)
- {
- dwBytesRead = dwReadSize;
- }
- if (ReadFile(m_hSerialPort, pReadBuf, dwBytesRead, &dwBytesRead, NULL))
- {
- return (INT)dwBytesRead;
- }
- return dwBytesRead;
- }
- void CSynSerial::SetTimeouts(COMMTIMEOUTS& timeouts)
- {
- ASSERT(IsOpen());
- if (!SetCommTimeouts(m_hSerialPort, &timeouts))
- {
- DWORD dwLastError = GetLastError();
- }
- }
|