提交 | 用户 | age
|
0ed438
|
1 |
#include "pch.h"
|
Q |
2 |
#include "HvSerialPort.h"
|
|
3 |
|
|
4 |
|
|
5 |
int HvSerialPort::Init()
|
|
6 |
{
|
|
7 |
return R_OK;
|
|
8 |
}
|
|
9 |
|
|
10 |
int HvSerialPort::SetParams(int nPortNum, int BaudRate, CString Settings)
|
|
11 |
{
|
|
12 |
m_nPort = nPortNum;
|
|
13 |
m_nBaudRate = BaudRate;
|
|
14 |
m_Settings = Settings;
|
|
15 |
return R_OK;
|
|
16 |
}
|
|
17 |
|
|
18 |
int HvSerialPort::Open()
|
|
19 |
{
|
|
20 |
// TODO: 在此处添加实现代码.
|
|
21 |
//Open Port
|
|
22 |
int j;
|
|
23 |
CString s1, s2;
|
|
24 |
CString ComPortName;
|
|
25 |
if (this->m_nPort == 0)
|
|
26 |
{
|
|
27 |
m_strResult.Format(_T("COM not specified %d"),m_nPort);
|
|
28 |
return R_ERR;
|
|
29 |
}
|
|
30 |
if (this->m_bOpened)
|
|
31 |
{
|
|
32 |
m_strResult.Format(_T("COM%d already Opened"),m_nPort);
|
|
33 |
return R_ERR;
|
|
34 |
}
|
|
35 |
ComPortName.Format(_T("\\\\.\\COM%d"), this->m_nPort);
|
|
36 |
hCom1 = CreateFile(ComPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED
|
|
37 |
if (hCom1 == INVALID_HANDLE_VALUE)
|
|
38 |
{
|
|
39 |
m_dwError = GetLastError();
|
|
40 |
m_bOpened = false;
|
|
41 |
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, m_dwError, 0, s1.GetBuffer(2048), 2048, NULL);
|
|
42 |
s1.ReleaseBuffer();
|
|
43 |
|
|
44 |
m_strResult.Format(_T("Open COM%d Err %d ,%s "), this->m_nPort, this->m_dwError, s1);
|
|
45 |
return R_ERR;
|
|
46 |
}
|
|
47 |
else
|
|
48 |
{
|
|
49 |
m_dwError = GetLastError();
|
|
50 |
|
|
51 |
m_strResult.Format(_T("COM%d OK."), this->m_nPort);
|
326d3e
|
52 |
LastTime = GetTimemS();
|
0ed438
|
53 |
TotalSendBytes = 0; TotalRecvBytes = 0;
|
Q |
54 |
LastSendBytes = 0; SendBytes = 0; RecvBytes = 0;
|
|
55 |
LastRecvBytes = 0; SendSpeed = 0; RecvSpeed = 0;
|
|
56 |
}
|
|
57 |
|
|
58 |
j = SetupComm(hCom1, 256, 256);
|
|
59 |
|
|
60 |
DCB dcb1;
|
|
61 |
j = GetCommState(hCom1, &dcb1);
|
|
62 |
BuildCommDCB(m_Settings, &dcb1);
|
|
63 |
|
|
64 |
dcb1.BaudRate = m_nBaudRate;
|
|
65 |
|
|
66 |
if (m_Settings.Find(_T("8")) != -1) { dcb1.ByteSize = 8; }
|
|
67 |
else if (m_Settings.Find(_T("7")) != -1) { dcb1.ByteSize = 8; }
|
|
68 |
else if (m_Settings.Find(_T("6")) != -1) { dcb1.ByteSize = 8; }
|
|
69 |
else if (m_Settings.Find(_T("5")) != -1) { dcb1.ByteSize = 8; }
|
|
70 |
|
|
71 |
if (m_Settings.Find(_T("N")) != -1) { dcb1.fParity = FALSE; dcb1.Parity = NOPARITY; }
|
|
72 |
else if (m_Settings.Find(_T("O")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = ODDPARITY; }
|
|
73 |
else if (m_Settings.Find(_T("E")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = EVENPARITY; }
|
|
74 |
else if (m_Settings.Find(_T("M")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = MARKPARITY; }
|
|
75 |
else if (m_Settings.Find(_T("S")) != -1) { dcb1.fParity = TRUE; dcb1.Parity = SPACEPARITY; }
|
|
76 |
|
|
77 |
if (m_Settings.Find(_T("1.5")) != -1) { dcb1.StopBits = ONE5STOPBITS; }
|
|
78 |
else if (m_Settings.Find(_T("1")) != -1) { dcb1.StopBits = ONESTOPBIT; }
|
|
79 |
else if (m_Settings.Find(_T("2")) != -1) { dcb1.StopBits = TWOSTOPBITS; }
|
|
80 |
|
|
81 |
dcb1.fDtrControl = 0;
|
|
82 |
dcb1.fDsrSensitivity = false;
|
|
83 |
dcb1.fBinary = 1;
|
|
84 |
dcb1.fOutxCtsFlow = false;
|
|
85 |
dcb1.fOutxDsrFlow = false;
|
|
86 |
dcb1.fRtsControl = RTS_CONTROL_DISABLE;
|
|
87 |
|
|
88 |
j = SetCommState(hCom1, &dcb1);
|
|
89 |
if (j == 0)
|
|
90 |
{
|
|
91 |
m_strResult.Format(_T("SetCommState Fail %d %s \r\n"), m_nBaudRate, m_Settings);
|
|
92 |
CloseHandle(hCom1);
|
|
93 |
m_bOpened = false;
|
|
94 |
return R_ERR;
|
|
95 |
}
|
|
96 |
j = GetCommState(hCom1, &dcb1);
|
|
97 |
|
|
98 |
CString strParity;
|
|
99 |
CString strStopBit;
|
|
100 |
|
|
101 |
if (dcb1.Parity == NOPARITY) { strParity = _T("N"); }
|
|
102 |
else if (dcb1.Parity == EVENPARITY) { strParity = _T("E"); }
|
|
103 |
else if (dcb1.Parity == ODDPARITY) { strParity = _T("O"); }
|
|
104 |
else if (dcb1.Parity == MARKPARITY) { strParity = _T("M"); }
|
|
105 |
else if (dcb1.Parity == SPACEPARITY) { strParity = _T("S"); }
|
|
106 |
else { strParity = _T("X"); }
|
|
107 |
|
|
108 |
if (dcb1.StopBits == ONESTOPBIT) { strStopBit = _T("1"); }
|
|
109 |
else if (dcb1.StopBits == ONE5STOPBITS) { strStopBit = _T("1.5"); }
|
|
110 |
else if (dcb1.StopBits == TWOSTOPBITS) { strStopBit = _T("2"); }
|
|
111 |
else { strStopBit = _T("3"); }
|
|
112 |
|
|
113 |
s1.Format(_T("%d %d-%s-%s"), dcb1.BaudRate, dcb1.ByteSize, strParity, strStopBit);
|
|
114 |
m_strResult += s1;
|
|
115 |
|
|
116 |
COMMTIMEOUTS comtimeout1;
|
|
117 |
COMSTAT comstat1;
|
|
118 |
GetCommTimeouts(hCom1, &comtimeout1);
|
|
119 |
|
|
120 |
comtimeout1.ReadIntervalTimeout = 1; //两个字符之间的时间
|
fc8a81
|
121 |
comtimeout1.ReadTotalTimeoutMultiplier = 0; //每个字符等待的时间,读多个字符则等待时间为单个时间乘以字符个数
|
0ed438
|
122 |
comtimeout1.ReadTotalTimeoutConstant = 2; //读取时,再另外多等待的时间。
|
Q |
123 |
comtimeout1.WriteTotalTimeoutMultiplier = 0; //写入时,每个字符等待的时间,写入多个字符则等待时间为单个时间乘以字符个数。
|
|
124 |
comtimeout1.WriteTotalTimeoutConstant = 0; //写入时,再另外多等待的时间。
|
|
125 |
|
|
126 |
SetCommTimeouts(hCom1, &comtimeout1);
|
|
127 |
j = ClearCommError(hCom1, &m_dwError, &comstat1);
|
|
128 |
s1.Format(_T("ClearCommError j %d errors %d "), j, m_dwError);
|
|
129 |
s2 = s1;
|
|
130 |
s1.Format(_T("cbInQue %d "), comstat1.cbInQue);
|
|
131 |
s2 += s1;
|
|
132 |
s1.Format(_T("cbOutQue %d "), comstat1.cbOutQue);
|
|
133 |
s2 += s1;
|
|
134 |
PurgeComBuf();
|
|
135 |
m_bOpened = true;
|
|
136 |
|
|
137 |
//Start Read Thread
|
|
138 |
|
|
139 |
MyThreadProc1ToRun = 1;
|
|
140 |
AfxBeginThread(MyJumper1, (LPVOID)this);
|
|
141 |
|
|
142 |
return R_OK;
|
|
143 |
}
|
|
144 |
|
|
145 |
int HvSerialPort::ClearStatData()
|
|
146 |
{
|
|
147 |
LastSendBytes = 0;
|
|
148 |
LastRecvBytes = 0;
|
|
149 |
SendBytes = 0;
|
|
150 |
RecvBytes = 0;
|
|
151 |
SendSpeed = 0;
|
|
152 |
RecvSpeed = 0;
|
|
153 |
return R_OK;
|
|
154 |
}
|
|
155 |
|
|
156 |
int HvSerialPort::CalSpeed()
|
|
157 |
{
|
326d3e
|
158 |
double thistime = GetTimemS();
|
0ed438
|
159 |
double diftime = thistime - LastTime;
|
Q |
160 |
if (diftime >= 500)
|
|
161 |
{
|
|
162 |
SendSpeed = (DWORD)(SendBytes * 1000 / diftime);
|
|
163 |
RecvSpeed = static_cast<DWORD> (RecvBytes * 1000 / diftime);
|
|
164 |
LastSendBytes = SendBytes; SendBytes = 0;
|
|
165 |
LastRecvBytes = RecvBytes; RecvBytes = 0;
|
|
166 |
LastTime = thistime;
|
|
167 |
}
|
|
168 |
return 0;
|
|
169 |
}
|
|
170 |
|
|
171 |
int HvSerialPort::Close()
|
|
172 |
{
|
|
173 |
// TODO: 在此处添加实现代码.
|
|
174 |
if (m_bOpened)
|
|
175 |
{
|
|
176 |
// SendSign(STOP);
|
|
177 |
MyThreadProc1ToRun = 0;
|
|
178 |
Sleep(10);
|
|
179 |
// wait for Thread stop
|
|
180 |
//WaitForMultipleObjects(nCount);
|
|
181 |
// close port
|
|
182 |
CloseHandle(hCom1);
|
|
183 |
m_bOpened = 0;
|
|
184 |
hCom1 = INVALID_HANDLE_VALUE;
|
|
185 |
m_strResult.Format(_T("COM%d Closed"), m_nPort);
|
|
186 |
return R_OK;
|
|
187 |
}
|
|
188 |
else
|
|
189 |
{
|
|
190 |
m_strResult.Format(_T("COM%d not Opened"),m_nPort);
|
|
191 |
return R_ERR;
|
|
192 |
}
|
|
193 |
}
|
|
194 |
|
|
195 |
int HvSerialPort::SetRecvDoneCallBack(pRecvDone pRecvDoneFunc)
|
|
196 |
{
|
|
197 |
// TODO: 在此处添加实现代码.
|
|
198 |
if (pRecvDoneFunc != NULL)
|
|
199 |
{
|
|
200 |
RecvDoneCB = pRecvDoneFunc;
|
|
201 |
m_bRecvDoneCBSet = 1;
|
|
202 |
}
|
|
203 |
else
|
|
204 |
{
|
|
205 |
RecvDoneCB = NULL;
|
|
206 |
m_bRecvDoneCBSet = 0;
|
|
207 |
}
|
|
208 |
return R_OK;
|
|
209 |
}
|
|
210 |
|
|
211 |
UINT HvSerialPort::MyJumper1(LPVOID pParam) //线程跳板
|
|
212 |
{
|
|
213 |
HvSerialPort *pInput = (HvSerialPort *)pParam; //反跳到真正的执行程序
|
|
214 |
return pInput->MyThreadProc1(0);
|
|
215 |
}
|
|
216 |
|
|
217 |
DWORD WINAPI HvSerialPort::MyThreadProc1(LPVOID pParam)
|
|
218 |
{
|
|
219 |
//串口接收数据函数
|
|
220 |
|
|
221 |
//接收到的数据 通知方式
|
|
222 |
// 1. windows消息队列
|
|
223 |
// 2. callback 函数 // 不同线程
|
|
224 |
// 3. Event
|
|
225 |
// 4. Buffer
|
|
226 |
|
|
227 |
OVERLAPPED osRead;
|
|
228 |
HANDLE hEventArr[2];
|
|
229 |
memset(&osRead, 0, sizeof(OVERLAPPED));
|
|
230 |
osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
fc8a81
|
231 |
SetCommMask(hCom1, EV_RXCHAR | EV_TXEMPTY);
|
0ed438
|
232 |
|
Q |
233 |
hEventArr[0] = osRead.hEvent;
|
|
234 |
// hEventArr[1] = *g_OutPutList.GetEvent();
|
|
235 |
|
|
236 |
CString s1, s2;
|
|
237 |
// SysLog(_T("线程开始运行\r\n"));
|
|
238 |
MyThreadProc1Running = 1;
|
|
239 |
|
|
240 |
/*
|
|
241 |
static OVERLAPPED ovlap1, ovlap2;
|
|
242 |
*/
|
|
243 |
|
|
244 |
//SysLog(_T("准备接收\r\n"));
|
|
245 |
DWORD dNumtoRead = 1000;
|
|
246 |
dNumtoRead = 64;
|
|
247 |
//nDataToSend = 0;
|
|
248 |
DWORD wCount2 = 0;
|
|
249 |
DWORD dwSent = 0;
|
|
250 |
int nRunCount = 0;
|
|
251 |
//计算接收速度;
|
|
252 |
|
326d3e
|
253 |
int LastSpeedTime = (int)GetTimemS();
|
0ed438
|
254 |
int nThisRecv = 0;
|
Q |
255 |
|
fc8a81
|
256 |
COMSTAT cs;
|
Q |
257 |
OVERLAPPED os;
|
|
258 |
DWORD dwTrans;
|
|
259 |
DWORD dwReaded;
|
0ed438
|
260 |
for (; MyThreadProc1ToRun == 1;)
|
Q |
261 |
{
|
|
262 |
|
|
263 |
DWORD dwEvtMask = 0;
|
fc8a81
|
264 |
///*
|
Q |
265 |
// BOOL result = WaitCommEvent(hCom1, &dwEvtMask, NULL); // &os);
|
|
266 |
// if (!result)
|
0ed438
|
267 |
{
|
fc8a81
|
268 |
// if (GetLastError() == ERROR_IO_PENDING)
|
Q |
269 |
// {
|
|
270 |
// GetOverlappedResult(hCom1, &os, &dwTrans, true);
|
|
271 |
|
|
272 |
// }
|
|
273 |
// if (dwEvtMask & EV_RXCHAR)
|
|
274 |
if (1) { Sleep(1); } else
|
0ed438
|
275 |
{
|
fc8a81
|
276 |
ClearCommError(hCom1, &m_dwError, &cs);
|
Q |
277 |
int bytes = cs.cbInQue;
|
|
278 |
dwReaded = 0;
|
|
279 |
if (bytes > 0)
|
0ed438
|
280 |
{
|
fc8a81
|
281 |
int j = ReadFile(hCom1, RecvBuf2, bytes, &dwReaded, NULL);
|
Q |
282 |
if (j > 0)
|
|
283 |
{
|
|
284 |
m_CS1.Lock();
|
|
285 |
memcpy(RecvBuf + RecvBufDataLen, RecvBuf2, dwReaded);
|
|
286 |
RecvBufDataLen += dwReaded;
|
|
287 |
m_CS1.Unlock();
|
|
288 |
}
|
|
289 |
}
|
|
290 |
else
|
|
291 |
{
|
|
292 |
Sleep(1);
|
0ed438
|
293 |
}
|
Q |
294 |
}
|
|
295 |
}
|
fc8a81
|
296 |
if (RecvBufDataLen > 1024) { RecvBufDataLen = 0; }
|
0ed438
|
297 |
//EscapeCommFunction(hCom1, SETDTR);
|
Q |
298 |
//*/
|
|
299 |
}
|
|
300 |
//SysLog(_T("跳出接收循环\r\n"));
|
|
301 |
// hcurDC.SelectObject(def_font);
|
|
302 |
// CloseHandle(hCom);
|
|
303 |
//SysLog(_T("线程结束运行\r\n\r\n"));
|
|
304 |
MyThreadProc1Running = 0;
|
|
305 |
return 0;
|
|
306 |
}
|
|
307 |
|
fc8a81
|
308 |
int HvSerialPort::ClearBuf()
|
Q |
309 |
{
|
|
310 |
PurgeComm(hCom1, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_TXCLEAR);
|
|
311 |
RecvBufDataLen = 0;
|
|
312 |
RecvBufPos = 0;
|
|
313 |
return 0;
|
|
314 |
}
|
0ed438
|
315 |
|
Q |
316 |
int HvSerialPort::Send(void * pBuf, int len1)
|
|
317 |
{
|
|
318 |
// TODO: 在此处添加实现代码.
|
|
319 |
CString s1;
|
|
320 |
int i, j;
|
|
321 |
DWORD numsent;
|
|
322 |
|
|
323 |
if (!m_bOpened) { return R_ERR; }
|
|
324 |
|
|
325 |
j = WriteFile(hCom1, pBuf, len1, &numsent, NULL);
|
|
326 |
|
|
327 |
if (j != 0)
|
|
328 |
{
|
|
329 |
m_strResult.Format(_T("Send To COM%d OK %dB : "), this->m_nPort, numsent);
|
|
330 |
for (i = 0; (unsigned)i < numsent; i++)
|
|
331 |
{
|
|
332 |
m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
|
|
333 |
}
|
|
334 |
m_strResult.AppendFormat(_T("\r\n"));
|
|
335 |
}
|
|
336 |
else
|
|
337 |
{
|
|
338 |
m_dwError = GetLastError();
|
|
339 |
m_strResult.Format(_T("Send To COM%d fail. Error:%d SentBytes:%d "), this->m_nPort, m_dwError, numsent);
|
|
340 |
}
|
|
341 |
SendBytes += numsent;
|
|
342 |
TotalSendBytes += numsent;
|
|
343 |
return numsent;
|
|
344 |
|
|
345 |
return R_OK;
|
|
346 |
}
|
|
347 |
int HvSerialPort::Recv(void * pBuf, int len1)
|
fc8a81
|
348 |
{
|
Q |
349 |
return RecvFromCom(pBuf, len1);
|
|
350 |
}
|
|
351 |
|
|
352 |
int HvSerialPort::RecvFromBuf(void * pBuf, int len1)
|
|
353 |
{
|
|
354 |
CString s1;
|
|
355 |
int i, j;
|
|
356 |
DWORD numreaded = 0;
|
|
357 |
int numtoread = len1;
|
|
358 |
m_strResult.Format(_T("ToRead %d "), len1);
|
|
359 |
for (i = 0; i < 20; i++)
|
|
360 |
{
|
|
361 |
int k = m_CS1.Lock();
|
|
362 |
if (RecvBufDataLen)
|
|
363 |
{
|
|
364 |
if (RecvBufDataLen >= numtoread)
|
|
365 |
{
|
|
366 |
memcpy((char *)pBuf+numreaded, RecvBuf, numtoread);
|
|
367 |
numreaded += numtoread;
|
|
368 |
RecvBufDataLen -= numtoread;
|
|
369 |
numtoread = 0;
|
|
370 |
memmove(RecvBuf, RecvBuf + numtoread, RecvBufDataLen);
|
|
371 |
}
|
|
372 |
else
|
|
373 |
{
|
|
374 |
memcpy((char *)pBuf + numreaded, RecvBuf, RecvBufDataLen);
|
|
375 |
numreaded += RecvBufDataLen;
|
|
376 |
RecvBufDataLen = 0;
|
|
377 |
RecvBufPos = 0;
|
|
378 |
numtoread -= RecvBufDataLen;
|
|
379 |
}
|
|
380 |
}
|
|
381 |
m_CS1.Unlock();
|
|
382 |
if (numtoread == 0) break;
|
|
383 |
Sleep(1);
|
|
384 |
}
|
|
385 |
if (numreaded > 0) {
|
|
386 |
m_strResult.AppendFormat(_T("Read From COM%d OK %dB "), this->m_nPort, numreaded);
|
|
387 |
for (i = 0; (unsigned)i < numreaded; i++)
|
|
388 |
{
|
|
389 |
m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
|
|
390 |
}
|
|
391 |
m_strResult.AppendFormat(_T("\r\n"));
|
|
392 |
}
|
|
393 |
else {
|
|
394 |
m_strResult.Format(_T("Read From COM%d failed \r\n"), this->m_nPort);
|
|
395 |
}
|
|
396 |
m_strResult.AppendFormat(_T("ToRun %d, Running %d"), MyThreadProc1ToRun, MyThreadProc1Running);
|
|
397 |
|
|
398 |
return numreaded;
|
|
399 |
}
|
|
400 |
int HvSerialPort::RecvFromCom(void * pBuf, int len1)
|
0ed438
|
401 |
{
|
Q |
402 |
// TODO: 在此处添加实现代码.
|
|
403 |
CString s1;
|
|
404 |
int i, j;
|
|
405 |
DWORD numreaded;
|
|
406 |
if (!m_bOpened) { return R_ERR; }
|
|
407 |
int len2 = 0;
|
|
408 |
//Sleep(n/10);
|
|
409 |
int nTryCount2 = 0;
|
|
410 |
m_strResult.Format(_T("ToRead %d "), len1);
|
|
411 |
for (int i = 0; i < m_nCountToTry; i++)
|
|
412 |
{
|
|
413 |
numreaded = 0;
|
|
414 |
|
|
415 |
j = ReadFile(hCom1, (char *)pBuf + len2, len1 - len2, &numreaded, NULL);
|
|
416 |
if (j != 0) {
|
|
417 |
len2 += numreaded;
|
|
418 |
((char *)pBuf)[len2] = 0;
|
|
419 |
if (len2 >= len1) break;
|
|
420 |
nTryCount2 = 0;
|
|
421 |
}
|
|
422 |
else {
|
|
423 |
if (len2 > 0) {
|
|
424 |
nTryCount2++;
|
fc8a81
|
425 |
if (nTryCount2 > m_nCountToWait) break;
|
0ed438
|
426 |
}
|
Q |
427 |
}
|
fc8a81
|
428 |
if (len2 > 0 && nTryCount2 > m_nCountToWait) break;
|
0ed438
|
429 |
}
|
Q |
430 |
numreaded = len2;
|
|
431 |
if (numreaded > 0) {
|
|
432 |
m_strResult.AppendFormat(_T("Read From COM%d OK %dB "), this->m_nPort, numreaded);
|
|
433 |
for (i = 0; (unsigned)i < numreaded; i++)
|
|
434 |
{
|
|
435 |
m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
|
|
436 |
}
|
|
437 |
m_strResult.AppendFormat(_T("\r\n"));
|
|
438 |
}
|
|
439 |
else {
|
|
440 |
m_strResult.Format(_T("Read From COM%d failed \r\n"),this->m_nPort);
|
|
441 |
}
|
|
442 |
|
|
443 |
RecvBytes += numreaded;
|
|
444 |
TotalRecvBytes += numreaded;
|
|
445 |
|
|
446 |
return numreaded;
|
|
447 |
return R_OK;
|
|
448 |
}
|