瀏覽代碼

重点:
如果是异步,在ReadFile后,还是要使用WaitForSingleObject等待一段时间(或直接Sleep等待),不然的话,cbInQue里显示的是27个字符,但缓冲区里的数据可能还没更新到,导致获取的Buffer是空的。

sat23 4 年之前
父節點
當前提交
95491b3cee

+ 38 - 4
Serail-Demo/Demo/Demo.cpp

@@ -15,6 +15,7 @@ CWinApp theApp;
 
 using namespace std;
 
+extern VOID _dprintf(CHAR* pszStr, ...);
 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 {
 	int nRetCode = 0;
@@ -29,6 +30,34 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 	else
 	{
 		// TODO: 在此处为应用程序的行为编写代码。
+#if 1
+		CBaseSerial sb(0);
+		if ( sb.Open(23, _T("baud=115200 parity=N data=8 stop=1") ) )
+		{
+			sb.SetTimeouts();
+			std::vector<CommandParam> vtCommandParams;
+			parse_cmd_param_from_file("F:\\source\\scbc_repos\\Serail-Demo\\Demo\\command.data", vtCommandParams);
+			for ( std::vector<CommandParam>::iterator it = vtCommandParams.begin(); it != vtCommandParams.end(); it++ )
+			{
+				if ( !_tcsicmp(it->name.c_str(), _T("LeaveFactory")) )
+					break;
+				byte szData[1024] = {0};
+				std::string cmd = PackingCommand(*it, _T(""), 0);
+				//sb.Read(szData, 1024, 100);
+				if ( sb.WriteSync((void*)cmd.c_str(), cmd.size()) )
+				{
+					Sleep(it->read_wait_time);
+					int c = sb.ReadSync(szData, 1024);
+					std::string str = BytesToHexString(szData, c, ' ');
+					_dprintf("结果:%s", str.c_str());
+					
+					Sleep(it->cmd_wait_time);
+				}
+
+				sb.ClearCommBuffer();
+			}
+		}
+#else
 		CBaseSerial sb;
 		if ( sb.Open(23, _T("baud=115200 parity=N data=8 stop=1") ) )
 		{
@@ -37,20 +66,25 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 			parse_cmd_param_from_file("F:\\source\\scbc_repos\\Serail-Demo\\Demo\\command.data", vtCommandParams);
 			for ( std::vector<CommandParam>::iterator it = vtCommandParams.begin(); it != vtCommandParams.end(); it++ )
 			{
+				if ( !_tcsicmp(it->name.c_str(), _T("LeaveFactory")) )
+					break;
 				byte szData[1024] = {0};
 				std::string cmd = PackingCommand(*it, _T(""), 0);
 				//sb.Read(szData, 1024, 100);
 				if ( sb.Write((void*)cmd.c_str(), cmd.size()) )
 				{
 					Sleep(it->read_wait_time);
-					int c = sb.Read(szData, 1024);
+					int c = sb.Read(szData, 1024, 200);
+					std::string str = BytesToHexString(szData, c, ' ');
+					_dprintf("结果:%s", str.c_str());
 
-					int a = 0;
+					Sleep(it->cmd_wait_time);
 				}
+
+				sb.ClearCommBuffer();
 			}
 		}
-
-
+#endif
 		system("pause");
 	}
 

+ 2 - 2
Serail-Demo/Demo/Serial.cpp

@@ -122,7 +122,7 @@ bool CBaseSerial::Open(DWORD dwPort, TCHAR *lpszSetStr /* = _T("baud/* =115200 p
 	return SetState(lpszSetStr);
 }
 
-DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime /* = 10 */)
+DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime /* = 100 */)
 {
 	if (!IsOpen())
 		return 0;
@@ -144,7 +144,7 @@ DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime /*
 	unsigned long uReadLength = 0;
 	// dwBufferLength = dwBufferLength > Stat.cbInQue ? Stat.cbInQue : dwBufferLength;//会越界;
 	if (!::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, &_ReadOverlapped))  { // 可能Buffer不够大,装不完;
-		// WaitForSingleObject(_ReadOverlapped.hEvent, dwWaitTime); // 没必要这里等;
+		WaitForSingleObject(_ReadOverlapped.hEvent, dwWaitTime); // 等待异步操作完成;
 		if (::GetLastError() == ERROR_IO_PENDING) {
 			while (!::GetOverlappedResult(_hCommHandle, &_ReadOverlapped, &uReadLength, false)) {
 				dwError = ::GetLastError();

+ 8 - 3
Serail-Demo/Demo/Serial.h

@@ -60,9 +60,9 @@ public:
 	bool SetTimeouts(
 		DWORD ReadIntervalTimeout = 5, 
 		DWORD ReadTotalTimeoutMultiplier = 10, 
-		DWORD ReadTotalTimeoutConstant = 500, 
+		DWORD ReadTotalTimeoutConstant = 1500, 
 		DWORD WriteTotalTimeoutMultiplier = 10, 
-		DWORD WriteTotalTimeoutConstant = 500);
+		DWORD WriteTotalTimeoutConstant = 1500);
     bool SetTimeouts(LPCOMMTIMEOUTS lpCO);
     // 设置串口的I/O缓冲区大小
     bool SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize);
@@ -90,7 +90,7 @@ public:
 	bool Open(DWORD dwPort, TCHAR *lpszSetStr = _T("baud=115200 parity=N data=8 stop=1") );
     
     // 读取串口 dwBufferLength个字符到 Buffer 返回实际读到的字符数 可读任意数据
-    DWORD Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime = 10);    
+    DWORD Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime = 100);    
     // 读取串口 dwBufferLength - 1 个字符到 szBuffer 返回ANSI C 模式字符串指针 适合一般字符通讯
     char *ReadString(char *szBuffer, DWORD dwBufferLength, DWORD dwWaitTime = 20);    
     // 写串口 可写任意数据 "abcd" or "\x0\x1\x2"
@@ -113,6 +113,11 @@ public:
     bool SetRTS(bool OnOrOff);
     // 设置信号状态为中断;
     bool SetBreak(bool OnOrOff);
+	// 清除缓存;
+	void ClearCommBuffer() { 
+		ClearCommError(_hCommHandle, NULL, NULL);
+		::PurgeComm(_hCommHandle, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR); 
+	}
 
 protected:
     volatile DWORD _dwPort;                             // 串口号

+ 3 - 3
Serail-Demo/Demo/command.data

@@ -1,8 +1,6 @@
 # Get Info;
-Name=EnterFactory; HeadCode=AA; Command=10; CMDParam=01; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=EnterFactory; HeadCode=AA; Command=10; CMDParam=01; MultiParams=false; ReadWaitTime=150ms; CMDWaitTime=100ms
 Name=GetSoftVersion; HeadCode=AA; Command=57; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
-Name=LeaveFactory; HeadCode=AA; Command=10; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
-Name=WBInit; HeadCode=AA; Command=16; CMDParam=02; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
 Name=GetProjectID; HeadCode=AA; Command=84; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
 Name=GetDeviceId; HeadCode=AA; Command=BE; CMDParam=01; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
 Name=GetClientType; HeadCode=AA; Command=8C; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
@@ -16,6 +14,8 @@ Name=GetCiKey; HeadCode=AA; Command=EC; CMDParam=01; MultiParams=true; ReadWaitT
 Name=GetOSDLanguage; HeadCode=AA; Command=97; CMDParam=00; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
 Name=GetShopLanguage; HeadCode=AA; Command=97; CMDParam=01; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
 Name=GetChannel; HeadCode=AA; Command=97; CMDParam=13; MultiParams=true; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=LeaveFactory; HeadCode=AA; Command=10; CMDParam=00; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
+Name=WBInit; HeadCode=AA; Command=16; CMDParam=02; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
 # Set Info;
 Name=SetProjectId; HeadCode=AA; Command=70; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms
 Name=SetDeviceID; HeadCode=AA; Command=B2; CMDParam=/; MultiParams=false; ReadWaitTime=100ms; CMDWaitTime=100ms

+ 1 - 1
Serail-Demo/Demo/stdafx.cpp

@@ -333,7 +333,7 @@ std::string PackingCommand(CommandParam &cmdPara, std::string data, const int &d
 	// crcУÑé;
 	byte szcrc[2] = {0};
 	//WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), command.size()); // Èç¹ûÓÐ0¶Ï¿ªÓÐΣÏÕ;
-	WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), len);
+	WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), len - 2);
 	szcrc[0] = (usCRCValue >> 8) & 0xFF;
 	szcrc[1] = usCRCValue & 0xFF;
 	command.append((char *)szcrc, 2);

+ 2 - 0
Serail-Demo/Demo/stdafx.h

@@ -46,4 +46,6 @@ bool parse_key(std::string &value, std::string strLine, TCHAR *lpszText);
 int parse_cmd_param_from_file(char *file_name, std::vector<CommandParam> &vtCommandParams);
 unsigned char TwoHexCharToInteger(char high, char low);
 std::string PackingCommand(CommandParam &cmdPara, std::string data, const int &dataLen);
+std::string BytesToHexString(const unsigned char *pbuffer, int nLen);
+std::string BytesToHexString(const unsigned char *pbuffer, int nLen, char chSpace);
 // TODO: 在此处引用程序需要的其他头文件