QuakeGod
2022-01-16 326d3e312c74726814c39c9d112faab03c4a167c
提交 | 用户 | 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;    //两个字符之间的时间
121     comtimeout1.ReadTotalTimeoutMultiplier = 1;    //每个字符等待的时间,读多个字符则等待时间为单个时间乘以字符个数
122     comtimeout1.ReadTotalTimeoutConstant = 2;        //读取时,再另外多等待的时间。
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);
231     SetCommMask(hCom1, EV_RXCHAR| EV_TXEMPTY);
232
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
256     COMSTAT cs;
257     OVERLAPPED os;
258     DWORD dwTrans;
259     DWORD dwReaded;
260     for (; MyThreadProc1ToRun == 1;)
261     {
262
263         DWORD dwEvtMask = 0;
264 /*
265         BOOL result = WaitCommEvent(hCom1, &dwEvtMask, &os);
266         if (!result)
267         {
268             if (GetLastError() == ERROR_IO_PENDING)
269             {
270                 GetOverlappedResult(hCom1, &os, &dwTrans, true);
271                 if (dwEvtMask & EV_RXCHAR)
272                 {
273                     ClearCommError(hCom1, &m_dwError, &cs);
274                     int bytes = cs.cbInQue;
275                     dwReaded = 0;
276                     ReadFile(hCom1,RecvBuf,bytes,&dwReaded,NULL);
277                 }
278             }
279         }
280         //EscapeCommFunction(hCom1, SETDTR);
281 //*/        
282         Sleep(1);
283     }
284     //SysLog(_T("跳出接收循环\r\n"));
285     //    hcurDC.SelectObject(def_font); 
286 //    CloseHandle(hCom);
287     //SysLog(_T("线程结束运行\r\n\r\n"));
288     MyThreadProc1Running = 0;
289     return 0;
290 }
291
292
293 int HvSerialPort::Send(void * pBuf, int len1)
294 {
295     // TODO: 在此处添加实现代码.
296     CString s1;
297     int i, j;
298     DWORD numsent;
299
300     if (!m_bOpened) { return R_ERR; }
301
302     j = WriteFile(hCom1, pBuf, len1, &numsent, NULL);
303
304     if (j != 0)
305     {
306         m_strResult.Format(_T("Send To COM%d OK %dB : "), this->m_nPort, numsent);
307         for (i = 0; (unsigned)i < numsent; i++)
308         {
309             m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
310         }
311         m_strResult.AppendFormat(_T("\r\n"));
312     }
313     else
314     {
315         m_dwError = GetLastError();
316         m_strResult.Format(_T("Send To COM%d fail. Error:%d  SentBytes:%d "), this->m_nPort, m_dwError, numsent);
317     }
318     SendBytes += numsent;
319     TotalSendBytes += numsent;
320     return numsent;
321
322     return R_OK;
323 }
324
325
326 int HvSerialPort::Recv(void * pBuf, int len1)
327 {
328     // TODO: 在此处添加实现代码.
329     CString s1;
330     int i, j;
331     DWORD numreaded;
332     if (!m_bOpened) { return R_ERR; }
333     int len2 = 0;
334     //Sleep(n/10);
335     int nTryCount2 = 0;
336     m_strResult.Format(_T("ToRead %d "), len1);
337     for (int i = 0; i < m_nCountToTry; i++)
338     {
339         numreaded = 0;
340         
341         j = ReadFile(hCom1, (char *)pBuf + len2, len1 - len2, &numreaded, NULL);
342         if (j != 0) {
343             len2 += numreaded;
344             ((char *)pBuf)[len2] = 0;
345             if (len2 >= len1) break;
346             nTryCount2 = 0;
347         }
348         else {
349             if (len2 > 0) {
350                 nTryCount2++;
351                 if (nTryCount2 >= m_nCountToWait) break;
352             }
353         }
354         if (len2 > 0 && nTryCount2 >= m_nCountToWait) break;
355     }
356     numreaded = len2;
357     if (numreaded > 0) {
358         m_strResult.AppendFormat(_T("Read From COM%d OK %dB "), this->m_nPort, numreaded);
359         for (i = 0; (unsigned)i < numreaded; i++)
360         {
361             m_strResult.AppendFormat(_T("%c"), ((char *)pBuf)[i]);
362         }
363         m_strResult.AppendFormat(_T("\r\n"));
364     }
365     else {
366         m_strResult.Format(_T("Read From COM%d failed \r\n"),this->m_nPort);
367     }
368
369     RecvBytes += numreaded;
370     TotalRecvBytes += numreaded;
371
372     return numreaded;
373     return R_OK;
374 }