#include "pch.h"
|
#include "HvSerialPort.h"
|
|
|
int HvSerialPort::Init()
|
{
|
return R_OK;
|
}
|
|
int HvSerialPort::SetParams(int nPortNum, int BaudRate, CString Settings)
|
{
|
m_nPort = nPortNum;
|
m_nBaudRate = BaudRate;
|
m_Settings = Settings;
|
return R_OK;
|
}
|
|
int HvSerialPort::Open()
|
{
|
// TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë.
|
//Open Port
|
int j;
|
CString s1, s2;
|
CString ComPortName;
|
if (this->m_nPort == 0)
|
{
|
m_strResult.Format(_T("COM not specified %d"),m_nPort);
|
return R_ERR;
|
}
|
if (this->m_bOpened)
|
{
|
m_strResult.Format(_T("COM%d already Opened"),m_nPort);
|
return R_ERR;
|
}
|
ComPortName.Format(_T("\\\\.\\COM%d"), this->m_nPort);
|
hCom1 = CreateFile(ComPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED
|
if (hCom1 == INVALID_HANDLE_VALUE)
|
{
|
m_dwError = GetLastError();
|
m_bOpened = false;
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, m_dwError, 0, s1.GetBuffer(2048), 2048, NULL);
|
s1.ReleaseBuffer();
|
|
m_strResult.Format(_T("Open COM%d Err %d ,%s "), this->m_nPort, this->m_dwError, s1);
|
return R_ERR;
|
}
|
else
|
{
|
m_dwError = GetLastError();
|
|
m_strResult.Format(_T("COM%d OK."), this->m_nPort);
|
LastTime = GetTimeMs();
|
TotalSendBytes = 0; TotalRecvBytes = 0;
|
LastSendBytes = 0; SendBytes = 0; RecvBytes = 0;
|
LastRecvBytes = 0; SendSpeed = 0; RecvSpeed = 0;
|
}
|
|
j = SetupComm(hCom1, 256, 256);
|
|
DCB dcb1;
|
j = GetCommState(hCom1, &dcb1);
|
BuildCommDCB(m_Settings, &dcb1);
|
|
dcb1.BaudRate = m_nBaudRate;
|
|
if (m_Settings.Find(_T("8")) != -1) { dcb1.ByteSize = 8; }
|
else if (m_Settings.Find(_T("7")) != -1) { dcb1.ByteSize = 8; }
|
else if (m_Settings.Find(_T("6")) != -1) { dcb1.ByteSize = 8; }
|
else if (m_Settings.Find(_T("5")) != -1) { dcb1.ByteSize = 8; }
|
|
if (m_Settings.Find(_T("N")) != -1) { dcb1.fParity = FALSE; dcb1.Parity = NOPARITY; }
|
else if (m_Settings.Find(_T("O")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = ODDPARITY; }
|
else if (m_Settings.Find(_T("E")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = EVENPARITY; }
|
else if (m_Settings.Find(_T("M")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = MARKPARITY; }
|
else if (m_Settings.Find(_T("S")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = SPACEPARITY; }
|
|
if (m_Settings.Find(_T("1.5")) != -1) { dcb1.StopBits = ONE5STOPBITS; }
|
else if (m_Settings.Find(_T("1")) != -1) { dcb1.StopBits = ONESTOPBIT; }
|
else if (m_Settings.Find(_T("2")) != -1) { dcb1.StopBits = TWOSTOPBITS; }
|
|
dcb1.fDtrControl = 0;
|
dcb1.fDsrSensitivity = false;
|
dcb1.fBinary = 1;
|
dcb1.fOutxCtsFlow = false;
|
dcb1.fOutxDsrFlow = false;
|
dcb1.fRtsControl = RTS_CONTROL_DISABLE;
|
|
j = SetCommState(hCom1, &dcb1);
|
if (j == 0)
|
{
|
m_strResult.Format(_T("SetCommState Fail %d %s \r\n"), m_nBaudRate, m_Settings);
|
CloseHandle(hCom1);
|
m_bOpened = false;
|
return R_ERR;
|
}
|
j = GetCommState(hCom1, &dcb1);
|
|
CString strParity;
|
CString strStopBit;
|
|
if (dcb1.Parity == NOPARITY) { strParity = _T("N"); }
|
else if (dcb1.Parity == EVENPARITY) { strParity = _T("E"); }
|
else if (dcb1.Parity == ODDPARITY) { strParity = _T("O"); }
|
else if (dcb1.Parity == MARKPARITY) { strParity = _T("M"); }
|
else if (dcb1.Parity == SPACEPARITY) { strParity = _T("S"); }
|
else { strParity = _T("X"); }
|
|
if (dcb1.StopBits == ONESTOPBIT) { strStopBit = _T("1"); }
|
else if (dcb1.StopBits == ONE5STOPBITS) { strStopBit = _T("1.5"); }
|
else if (dcb1.StopBits == TWOSTOPBITS) { strStopBit = _T("2"); }
|
else { strStopBit = _T("3"); }
|
|
s1.Format(_T("%d %d-%s-%s"), dcb1.BaudRate, dcb1.ByteSize, strParity, strStopBit);
|
m_strResult += s1;
|
|
COMMTIMEOUTS comtimeout1;
|
COMSTAT comstat1;
|
GetCommTimeouts(hCom1, &comtimeout1);
|
|
comtimeout1.ReadIntervalTimeout = 1; //Á½¸ö×Ö·ûÖ®¼äµÄʱ¼ä
|
comtimeout1.ReadTotalTimeoutMultiplier = 0; //ÿ¸ö×Ö·ûµÈ´ýµÄʱ¼ä£¬¶Á¶à¸ö×Ö·ûÔòµÈ´ýʱ¼äΪµ¥¸öʱ¼ä³ËÒÔ×Ö·û¸öÊý
|
comtimeout1.ReadTotalTimeoutConstant = 1; //¶Áȡʱ£¬ÔÙÁíÍâ¶àµÈ´ýµÄʱ¼ä¡£
|
comtimeout1.WriteTotalTimeoutMultiplier = 0; //дÈëʱ£¬Ã¿¸ö×Ö·ûµÈ´ýµÄʱ¼ä£¬Ð´Èë¶à¸ö×Ö·ûÔòµÈ´ýʱ¼äΪµ¥¸öʱ¼ä³ËÒÔ×Ö·û¸öÊý¡£
|
comtimeout1.WriteTotalTimeoutConstant = 0; //дÈëʱ£¬ÔÙÁíÍâ¶àµÈ´ýµÄʱ¼ä¡£
|
|
SetCommTimeouts(hCom1, &comtimeout1);
|
j = ClearCommError(hCom1, &m_dwError, &comstat1);
|
s1.Format(_T("ClearCommError j %d errors %d "), j, m_dwError);
|
s2 = s1;
|
s1.Format(_T("cbInQue %d "), comstat1.cbInQue);
|
s2 += s1;
|
s1.Format(_T("cbOutQue %d "), comstat1.cbOutQue);
|
s2 += s1;
|
PurgeComBuf();
|
m_bOpened = true;
|
|
//Start Read Thread
|
|
MyThreadProc1ToRun = 1;
|
AfxBeginThread(MyJumper1, (LPVOID)this);
|
|
return R_OK;
|
}
|
|
int HvSerialPort::ClearStatData()
|
{
|
LastSendBytes = 0;
|
LastRecvBytes = 0;
|
SendBytes = 0;
|
RecvBytes = 0;
|
SendSpeed = 0;
|
RecvSpeed = 0;
|
return R_OK;
|
}
|
|
int HvSerialPort::CalSpeed()
|
{
|
double thistime = GetTimeMs();
|
double diftime = thistime - LastTime;
|
if (diftime >= 500)
|
{
|
SendSpeed = (DWORD)(SendBytes * 1000 / diftime);
|
RecvSpeed = static_cast<DWORD> (RecvBytes * 1000 / diftime);
|
LastSendBytes = SendBytes; SendBytes = 0;
|
LastRecvBytes = RecvBytes; RecvBytes = 0;
|
LastTime = thistime;
|
}
|
return 0;
|
}
|
|
int HvSerialPort::Close()
|
{
|
// TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë.
|
if (m_bOpened)
|
{
|
// SendSign(STOP);
|
MyThreadProc1ToRun = 0;
|
// wait for Thread stop
|
//WaitForMultipleObjects(nCount);
|
// close port
|
CloseHandle(hCom1);
|
m_bOpened = 0;
|
hCom1 = INVALID_HANDLE_VALUE;
|
m_strResult.Format(_T("COM%d Closed"), m_nPort);
|
return R_OK;
|
}
|
else
|
{
|
m_strResult.Format(_T("COM%d not Opened"),m_nPort);
|
return R_ERR;
|
}
|
}
|
|
int HvSerialPort::SetRecvDoneCallBack(pRecvDone pRecvDoneFunc)
|
{
|
// TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë.
|
if (pRecvDoneFunc != NULL)
|
{
|
RecvDoneCB = pRecvDoneFunc;
|
m_bRecvDoneCBSet = 1;
|
}
|
else
|
{
|
RecvDoneCB = NULL;
|
m_bRecvDoneCBSet = 0;
|
}
|
return R_OK;
|
}
|
|
UINT HvSerialPort::MyJumper1(LPVOID pParam) //Ïß³ÌÌø°å
|
{
|
HvSerialPort *pInput = (HvSerialPort *)pParam; //·´Ìøµ½ÕæÕýµÄÖ´ÐгÌÐò
|
return pInput->MyThreadProc1(0);
|
}
|
|
DWORD WINAPI HvSerialPort::MyThreadProc1(LPVOID pParam)
|
{
|
//´®¿Ú½ÓÊÕÊý¾Ýº¯Êý
|
|
//½ÓÊÕµ½µÄÊý¾Ý ֪ͨ·½Ê½
|
// 1. windowsÏûÏ¢¶ÓÁÐ
|
// 2. callback º¯Êý // ²»Í¬Ïß³Ì
|
// 3. Event
|
// 4. Buffer
|
|
OVERLAPPED osRead;
|
HANDLE hEventArr[2];
|
memset(&osRead, 0, sizeof(OVERLAPPED));
|
osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
SetCommMask(hCom1, EV_RXCHAR| EV_TXEMPTY);
|
|
hEventArr[0] = osRead.hEvent;
|
// hEventArr[1] = *g_OutPutList.GetEvent();
|
|
CString s1, s2;
|
// SysLog(_T("Ï߳̿ªÊ¼ÔËÐÐ\r\n"));
|
MyThreadProc1Running = 1;
|
|
/*
|
static OVERLAPPED ovlap1, ovlap2;
|
*/
|
|
//SysLog(_T("×¼±¸½ÓÊÕ\r\n"));
|
DWORD dNumtoRead = 1000;
|
dNumtoRead = 64;
|
//nDataToSend = 0;
|
DWORD wCount2 = 0;
|
DWORD dwSent = 0;
|
int nRunCount = 0;
|
//¼ÆËã½ÓÊÕËÙ¶È;
|
|
int LastSpeedTime = (int)GetTimeMs();
|
int nThisRecv = 0;
|
|
COMSTAT cs;
|
OVERLAPPED os;
|
DWORD dwTrans;
|
DWORD dwReaded;
|
for (; MyThreadProc1ToRun == 1;)
|
{
|
|
DWORD dwEvtMask = 0;
|
/*
|
BOOL result = WaitCommEvent(hCom1, &dwEvtMask, &os);
|
if (!result)
|
{
|
if (GetLastError() == ERROR_IO_PENDING)
|
{
|
GetOverlappedResult(hCom1, &os, &dwTrans, true);
|
if (dwEvtMask & EV_RXCHAR)
|
{
|
ClearCommError(hCom1, &m_dwError, &cs);
|
int bytes = cs.cbInQue;
|
dwReaded = 0;
|
ReadFile(hCom1,RecvBuf,bytes,&dwReaded,NULL);
|
}
|
}
|
}
|
//EscapeCommFunction(hCom1, SETDTR);
|
//*/
|
Sleep(1);
|
}
|
//SysLog(_T("Ìø³ö½ÓÊÕÑ»·\r\n"));
|
// hcurDC.SelectObject(def_font);
|
// CloseHandle(hCom);
|
//SysLog(_T("Ï߳̽áÊøÔËÐÐ\r\n\r\n"));
|
MyThreadProc1Running = 0;
|
return 0;
|
}
|
|
|
int HvSerialPort::Send(void * pBuf, int len1)
|
{
|
// TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë.
|
CString s1;
|
int i, j;
|
DWORD numsent;
|
|
if (!m_bOpened) { return R_ERR; }
|
|
j = WriteFile(hCom1, pBuf, len1, &numsent, NULL);
|
|
if (j != 0)
|
{
|
m_strResult.Format(_T("Send To COM%d OK %dB : "), this->m_nPort, numsent);
|
for (i = 0; (unsigned)i < numsent; i++)
|
{
|
m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
|
}
|
m_strResult.AppendFormat(_T("\r\n"));
|
}
|
else
|
{
|
m_dwError = GetLastError();
|
m_strResult.Format(_T("Send To COM%d fail. Error:%d SentBytes:%d "), this->m_nPort, m_dwError, numsent);
|
}
|
SendBytes += numsent;
|
TotalSendBytes += numsent;
|
return numsent;
|
|
return R_OK;
|
}
|
|
|
int HvSerialPort::Recv(void * pBuf, int len1)
|
{
|
// TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë.
|
CString s1;
|
int i, j;
|
DWORD numreaded;
|
if (!m_bOpened) { return R_ERR; }
|
int len2 = 0;
|
//Sleep(n/10);
|
int nTryCount2 = 0;
|
m_strResult.Format(_T("ToRead %d "), len1);
|
for (int i = 0; i < m_nCountToTry; i++)
|
{
|
numreaded = 0;
|
|
j = ReadFile(hCom1, (char *)pBuf + len2, len1 - len2, &numreaded, NULL);
|
if (j != 0) {
|
len2 += numreaded;
|
((char *)pBuf)[len2] = 0;
|
if (len2 >= len1) break;
|
nTryCount2 = 0;
|
}
|
else {
|
if (len2 > 0) {
|
nTryCount2++;
|
if (nTryCount2 >= m_nCountToWait) break;
|
}
|
}
|
if (len2 > 0 && nTryCount2 >= m_nCountToWait) break;
|
}
|
numreaded = len2;
|
if (numreaded > 0) {
|
m_strResult.AppendFormat(_T("Read From COM%d OK %dB "), this->m_nPort, numreaded);
|
for (i = 0; (unsigned)i < numreaded; i++)
|
{
|
m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
|
}
|
m_strResult.AppendFormat(_T("\r\n"));
|
}
|
else {
|
m_strResult.Format(_T("Read From COM failed \r\n"));
|
}
|
|
RecvBytes += numreaded;
|
TotalRecvBytes += numreaded;
|
|
return numreaded;
|
return R_OK;
|
}
|