Quellcode durchsuchen

整理函数,分类与优化。

sat23 vor 4 Jahren
Ursprung
Commit
8254e0d868

+ 11 - 13
Serail-Demo/Demo/Demo.cpp

@@ -3,6 +3,7 @@
 
 #include "stdafx.h"
 #include "Demo.h"
+#include "TCLCommand.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -30,34 +31,31 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 	{
 		// TODO: 在此处为应用程序的行为编写代码。
 #if 1
-		CBaseSerial sb(0);
-		if ( sb.Open(23, _T("baud=115200 parity=N data=8 stop=1")) )
+		TCLCommand tcl(true);
+		if (tcl.Open(23, _T("baud=115200 parity=N data=8 stop=1")) )
 		{
-			sb.SetTimeouts();
+			tcl.SetTimeouts();
 			std::vector<CommandParam> vtCommandParams;
-			parse_cmd_param_from_file("F:\\source\\scbc_repos\\Serail-Demo\\Demo\\command.data", vtCommandParams);
+			tcl.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()) )
+				std::string cmd = tcl.PackingCommand(*it, _T(""), 0);
+				if (tcl.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());
+					int c = tcl.ReadSync(szData, 1024);
+					std::string str = utils::BytesToHexString(szData, c, ' ');
+					utils::_dprintf("结果:%s", str.c_str());
 
 					str = "";
 					str.append((char*)szData, c);
-					ParseResultString(*it, str, str.size());
+					tcl.ParseResultString(*it, str, str.size());
 					
 					Sleep(it->cmd_wait_time);
 				}
-
-				//sb.ClearCommBuffer();
 			}
 		}
 #else

+ 3 - 1
Serail-Demo/Demo/Demo.vcxproj

@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
@@ -97,6 +97,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="TCLCommand.cpp" />
+    <ClCompile Include="utils.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Demo.h" />
@@ -105,6 +106,7 @@
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="targetver.h" />
     <ClInclude Include="TCLCommand.h" />
+    <ClInclude Include="utils.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Demo.rc" />

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

@@ -131,7 +131,7 @@ DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime /*
 	if (!Stat.cbInQue)
 		return 0; // 缓冲区无数据
 #endif
-	_dprintf("缓冲区数据量:%ld", Stat.cbInQue);
+	utils::_dprintf("缓冲区数据量:%ld", Stat.cbInQue);
 
 	unsigned long uReadLength = 0;
 	// dwBufferLength = dwBufferLength > Stat.cbInQue ? Stat.cbInQue : dwBufferLength;//会越界;
@@ -142,9 +142,9 @@ DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime /*
 				dwError = ::GetLastError();
 				if ( dwError == ERROR_IO_PENDING ) {
 					Sleep(50);
-					_dprintf("读等待:%ld", dwError);
+					utils::_dprintf("读等待:%ld", dwError);
 				} else if ( dwError == ERROR_SUCCESS || dwError == ERROR_IO_INCOMPLETE ) {
-					_dprintf("读完成:%ld,%ld,%ld", dwError, uReadLength,_ReadOverlapped.InternalHigh);
+					utils::_dprintf("读完成:%ld,%ld,%ld", dwError, uReadLength,_ReadOverlapped.InternalHigh);
 					// 奇葩:_ReadOverlapped并不能马上出长度,在超时后才会刷新出来(不知是否与Win平台有关);
 					if ( _ReadOverlapped.InternalHigh )
 						uReadLength = _ReadOverlapped.InternalHigh;
@@ -152,7 +152,7 @@ DWORD CBaseSerial::Read(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime /*
 						uReadLength = Stat.cbInQue;
 					break;
 				} else {
-					_dprintf("读错误:%ld", dwError);
+					utils::_dprintf("读错误:%ld", dwError);
 					uReadLength = 0;
 					break;
 				}
@@ -185,14 +185,14 @@ DWORD CBaseSerial::Write(LPVOID Buffer, DWORD dwBufferLength)
 			while (!GetOverlappedResult(_hCommHandle, &_WriteOverlapped, &uWriteLength, FALSE)) {
 				dwError = GetLastError();
 				if (ERROR_IO_PENDING == dwError) {
-					_dprintf("写等待");
+					utils::_dprintf("写等待");
 					continue;
 				} else if (dwError == ERROR_SUCCESS || dwError == ERROR_IO_INCOMPLETE){
 					uWriteLength = _WriteOverlapped.InternalHigh;
-					_dprintf("写完成:%ld", dwError);
+					utils::_dprintf("写完成:%ld", dwError);
 					break;
 				} else {
-					_dprintf("写出错:%ld",dwError);
+					utils::_dprintf("写出错:%ld",dwError);
 					uWriteLength = 0;
 					ClearCommError(_hCommHandle, &dwError, NULL);
 					break;
@@ -223,13 +223,13 @@ DWORD CBaseSerial::ReadSync(LPVOID Buffer, DWORD dwBufferLength)
 	// 直到有数据为止,超时3秒;
 	while (true) {// cbInQue表示输入缓冲区的字节数; 
 		if (GetTickCount() - ulTick > 3000) {
-			_dprintf("读出错: 超过3秒仍未读完");
+			utils::_dprintf("读出错: 超过3秒仍未读完");
 			break;
 		}
 
 		if ( ::ClearCommError(_hCommHandle, &dwError, &Stat) && dwError > 0 ) {
 			::PurgeComm(_hCommHandle, PURGE_RXABORT | PURGE_RXCLEAR);	// 清空输入缓冲区(PURGE_RXCLEAR)
-			_dprintf("读出错: ClearCommError出错");
+			utils::_dprintf("读出错: ClearCommError出错");
 			break;
 		}
 
@@ -246,14 +246,14 @@ DWORD CBaseSerial::ReadSync(LPVOID Buffer, DWORD dwBufferLength)
 	}
 
 	if (dwBufferLength < Stat.cbInQue) {
-		_dprintf("读出错: 缓冲数据过大 %ld > %ld", dwBufferLength, Stat.cbInQue);
+		utils::_dprintf("读出错: 缓冲数据过大 %ld > %ld", dwBufferLength, Stat.cbInQue);
 	}
 
 	DWORD uReadLength = 0;
 	if ( !::ReadFile(_hCommHandle, Buffer, dwBufferLength, &uReadLength, NULL) )
 	{
 		DWORD dwError = GetLastError();
-		_dprintf("读出错:%ld", dwError);
+		utils::_dprintf("读出错:%ld", dwError);
 	}
 
 	return uReadLength;
@@ -272,7 +272,7 @@ DWORD CBaseSerial::WriteSync(LPVOID Buffer, DWORD dwBufferLength)
 	if ( !::WriteFile(_hCommHandle, Buffer, dwBufferLength, &uWriteLength, NULL) )
 	{
 		DWORD dwError = GetLastError();
-		_dprintf("写出错:%ld", dwError);
+		utils::_dprintf("写出错:%ld", dwError);
 	}
 
 	return uWriteLength;

+ 351 - 1
Serail-Demo/Demo/TCLCommand.cpp

@@ -1,10 +1,360 @@
 #include "StdAfx.h"
 #include "TCLCommand.h"
 
-TCLCommand::TCLCommand(void)
+#define NoneOptLen 5
+
+TCLCommand::TCLCommand(bool bSync):CBaseSerial(bSync ? 0 : FILE_FLAG_OVERLAPPED)
 {
+
 }
 
 TCLCommand::~TCLCommand(void)
 {
+
+}
+
+int TCLCommand::pares_time_value(std::string strTime)
+{
+	int nTimes = 0;
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+	if (strstr(strTime.c_str(), _T("ms")) || strstr(strTime.c_str(), _T("MS")))
+	{
+		nTimes = atol(strTime.c_str());
+	}
+	else if (strstr(strTime.c_str(), _T("s")) || strstr(strTime.c_str(), _T("S")))
+	{
+		nTimes = atol(strTime.c_str()) * 1000;
+	}
+	else if (strstr(strTime.c_str(), _T("m")) || strstr(strTime.c_str(), _T("M")))
+	{
+		nTimes = atol(strTime.c_str()) * 6000;
+	}
+	else
+	{
+		// 不带单位或其他的,默认ms;
+		nTimes = atol(strTime.c_str());
+	}
+#elif _MSC_VER >= 1500
+	if (_tcsstr(strTime.c_str(), _T("ms")) || _tcsstr(strTime.c_str(), _T("MS")))
+	{
+		nTimes = _tstol(strTime.c_str());
+	}
+	else if (_tcsstr(strTime.c_str(), _T("s")) || _tcsstr(strTime.c_str(), _T("S")))
+	{
+		nTimes = _tstol(strTime.c_str()) * 1000;
+	}
+	else if (_tcsstr(strTime.c_str(), _T("m")) || _tcsstr(strTime.c_str(), _T("M")))
+	{
+		nTimes = _tstol(strTime.c_str()) * 6000;
+	}
+	else
+	{
+		// 不带单位或其他的,默认ms;
+		nTimes = _tstol(strTime.c_str());
+	}
+#endif
+
+	return nTimes;
+}
+
+bool TCLCommand::parse_pair_key(std::string& RetValue, std::string strLine, TCHAR* lpszText)
+{
+	TCHAR szText[MAX_PATH] = { 0 };
+	TCHAR szValue[MAX_PATH] = { 0 };
+	// 去除空格;
+#if _MSC_VER > 1900
+	strLine.erase(std::remove_if(strLine.begin(), strLine.end(), [](unsigned char x) {return std::isspace(x); }), strLine.end()); //C++17
+#else
+	for (std::string::iterator it = strLine.begin(); it != strLine.end();) {
+		!isspace(*it) ? it++ : it = it = strLine.erase(it);
+	}
+#endif
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0
+	if (2 == sscanf(strLine.c_str(), _T("%[^=]=%s"), szText, MAX_PATH, szValue, MAX_PATH))
+#else
+	if (2 == _stscanf_s(strLine.c_str(), _T("%[^=]=%s"), szText, MAX_PATH, szValue, MAX_PATH))
+#endif
+	{
+		if (_tcsstr(szText, lpszText))
+		{
+			RetValue = szValue;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+int TCLCommand::parse_cmd_param_from_file(TCHAR* file_name, std::vector<CommandParam>& vtCommandParams)
+{
+	TCHAR buf[MAX_PATH] = { 0 };
+	TCHAR name[MAX_PATH] = { 0 };
+	TCHAR option[MAX_PATH] = { 0 };
+	TCHAR head[MAX_PATH] = { 0 };
+	TCHAR code[MAX_PATH] = { 0 };
+	TCHAR param[MAX_PATH] = { 0 };
+	TCHAR multicode[MAX_PATH] = { 0 };
+	TCHAR cmd_wait_time[MAX_PATH] = { 0 };
+	TCHAR read_wait_time[MAX_PATH] = { 0 };
+
+	int ret = -1;
+	FILE* fp = NULL;
+
+	if (!file_name || file_name[0] == '\0')
+		return ret;
+
+	fp = fopen(file_name, "r");
+	if (!fp)
+		goto EXIT;
+
+	while ((fgets((char*)buf, MAX_PATH, fp) != NULL)) {
+		int tmp_len = 0;
+		unsigned short keycode = 0;
+		unsigned int protocol = 0;
+		unsigned int scancode = 0;
+
+		tmp_len = _tcslen(buf);
+		if (tmp_len >= 1) {
+			if (buf[tmp_len - 1] == '\r' || buf[tmp_len - 1] == '\n')
+				buf[tmp_len - 1] = 0;
+			if (tmp_len >= 2) {
+				if (buf[tmp_len - 2] == '\r' || buf[tmp_len - 2] == '\n')
+					buf[tmp_len - 2] = 0;
+			}
+		}
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0 
+		if (sscanf(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, option, head, code, param, multicode, read_wait_time, cmd_wait_time) == 8)
+#elif _MSC_VER >= 1500 
+		//if ( _stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8) // 等价下面;
+		if (_stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%s", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8)
+#endif
+		{
+			CommandParam cp;
+			parse_pair_key(cp.name, name, _T("Name"));
+			parse_pair_key(cp.head, head, _T("HeadCode"));
+			parse_pair_key(cp.code, code, _T("Command"));
+			parse_pair_key(cp.param, param, _T("CMDParam"));
+
+			std::string value;
+			parse_pair_key(value, option, _T("Option"));
+			if (!_tcsicmp(value.c_str(), _T("None")))
+				cp.nOption = CMDOPT_None;
+			else if (!_tcsicmp(value.c_str(), _T("Get")))
+				cp.nOption = CMDOPT_Get;
+			else if (!_tcsicmp(value.c_str(), _T("Set")))
+				cp.nOption = CMDOPT_Set;
+
+			parse_pair_key(value, multicode, _T("MultiParams"));
+			cp.bMulticode = !_tcsicmp(value.c_str(), _T("true")) ? true : false;
+
+			parse_pair_key(value, read_wait_time, _T("ReadWaitTime"));
+			cp.read_wait_time = pares_time_value(value.c_str());
+
+			parse_pair_key(value, cmd_wait_time, _T("CMDWaitTime"));
+			cp.cmd_wait_time = pares_time_value(value.c_str());
+			cp.UpdateRtnCode();
+
+			vtCommandParams.push_back(cp);
+		}
+	}
+
+	ret = 0;
+EXIT:
+	if (fp)
+		fclose(fp);
+	return ret;
+}
+
+bool TCLCommand::TheFirstPart(CommandParam& cmdPara, std::string data)
+{
+	if (data.size() == NoneOptLen) {
+		if ((byte)data[0] == cmdPara._rtnCode) {
+			// 长度;
+			int nPackageLen = (byte)data[1];
+			if (nPackageLen != NoneOptLen) {
+				cmdPara._rtnError = utils::_dprintf("None长度错误:%ld", (byte)data[1]);
+				return false;
+			}
+
+			// 执行状态;
+			cmdPara._rtnStatus = (byte)data[2];
+			utils::_dprintf(_T("rtnStatus=%02X"), cmdPara._rtnStatus);
+
+			// 校验crc;
+			unsigned short usCRCValue = utils::CRC16Calculate((byte*)data.data(), nPackageLen - 2);
+			if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPackageLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPackageLen - 1])
+			{
+				cmdPara._rtnError = utils::_dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPackageLen - 2], (byte)data[nPackageLen - 1]);
+				return false;
+			}
+		}
+		else {
+			cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
+			return false;
+		}
+	}
+	else {
+		cmdPara._rtnError = utils::_dprintf("长度对不上:Option.None");
+		return false;
+	}
+
+	return true;
+}
+
+bool TCLCommand::TheSecondPart(CommandParam& cmdPara, std::string data)
+{
+	// 数据起始位;
+	int nDataPos = 0;
+	// 数据包长度;
+	int nPackageLen = 0;
+	if ((byte)data[0] == cmdPara._rtnCode) {
+		// 获取长度;
+		if ((byte)data[1] == 0xFE) {
+			nDataPos = 4;
+			nPackageLen = (byte)data[2] << 8 | (byte)data[3];
+			if (data.size() < 255 && data[2] != 0) {
+				cmdPara._rtnError = utils::_dprintf(_T("长度异常"));
+				return false;
+			}
+		}
+		else
+		{
+			nDataPos = 2;
+			nPackageLen = (byte)data[1];
+#if 0 // 如果数据包含有非协议包内的数据,会判断异常;
+			if (data.size() > 255) {
+				//nPackageLen = data[1] << 8 | data[2];
+				cmdPara._rtnError = _dprintf(_T("长度异常"));
+				return false;
+			}
+#endif
+		}
+
+#if 0
+		// 计算出的长度,必等于包长;// 如果包含有其他非包数据,会判断异常;
+		if (nPackageLen != data.size())
+			return false;
+#endif
+
+		if (_tcsicmp(cmdPara.code.c_str(), utils::ByteToChars((byte)data[nDataPos] - 1).c_str()) != 0) {
+			cmdPara._rtnError = utils::_dprintf(_T("返回的指令错误, %s, %02X"), cmdPara.head.c_str(), (byte)data[nDataPos]);
+			return false;
+		}
+
+		// 返回的数据;
+		++nDataPos;// 返回码占一字节;
+		if (cmdPara.bMulticode) {
+			if (_tcsicmp(cmdPara.param.c_str(), utils::ByteToChars((byte)data[nDataPos]).c_str()) != 0) {
+				cmdPara._rtnError = utils::_dprintf(_T("返回的指令参数错误, %s, %02X"), cmdPara.param.c_str(), (byte)data[nDataPos]);
+				return false;
+			}
+
+			++nDataPos;// 指令参数码占一字节;
+		}
+
+		cmdPara._rtnData = data.substr(nDataPos, nPackageLen - nDataPos - 2); //2 = crc;
+		utils::_dprintf(_T("rtnData=%s"), utils::BytesToHexString((byte*)cmdPara._rtnData.c_str(), cmdPara._rtnData.size(), ' ').c_str());
+
+		// 校验crc;
+		unsigned short usCRCValue = utils::CRC16Calculate((byte*)data.data(), nPackageLen - 2);
+		if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPackageLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPackageLen - 1])
+		{
+			cmdPara._rtnError = utils::_dprintf("CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPackageLen - 2], (byte)data[nPackageLen - 1]);
+			return false;
+		}
+
+#if 1
+		if (data.size() > nPackageLen)
+			utils::_dprintf("带有脏数据:%s", data.substr(nPackageLen));
+#endif
+	}
+	else {
+		cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
+		return false;
+	}
+
+	return true;
+}
+
+std::string TCLCommand::PackingCommand(CommandParam& cmdPara, std::string data, const int& dataLen)
+{
+	// Tag:[命令头][全命令长度][命令码]<命令码参数><附加数据>[crc1][crc2]
+	std::string command;
+	// 命令头标识位;
+	command.append(utils::HexStringToBytes(cmdPara.head, 2).c_str(), cmdPara.head.size() / 2);
+	// 命令码;
+	command.append(utils::HexStringToBytes(cmdPara.code, 2).c_str(), cmdPara.code.size() / 2);
+	// 命令码参数;
+	command.append(utils::HexStringToBytes(cmdPara.param, 2).c_str(), cmdPara.param.size() / 2);
+	// 附加的数据;
+	if (dataLen > 0)
+		command.append(data.c_str(), dataLen);
+
+	int len(0);
+	// 长度:可能1字节表示,超过255用2字节表示;
+	byte szlen[2] = { 0 };
+	//if ((byte)command[1] == 0xFE)
+	//if ( cmdPara.head.size() >= 4 && cmdPara.head.find("FE", 2, 2) != std::string::npos )
+	if (_tcsicmp(_T("AAFE"), cmdPara.head.c_str()) == 0)
+	{// 长度超过255,需要2字节表示;
+		len = command.size() + 4;	// 2位crc + 2位长度;
+		szlen[0] = (len >> 8) & 0xFF;
+		szlen[1] = len & 0xFF;
+		command.insert(2, (char*)szlen, 2);
+	}
+	else {
+		// 2位crc + 1位长度;
+		len = command.size() + 3;
+		//if ( _tcsicmp(cmdPara.code.c_str(), "99 00") == 0 )
+		//	len -= 2;
+
+		if (len > 255) {// 长度超过255,多一个占位符;
+			++len;
+			szlen[0] = (len >> 8) & 0xFF;
+			szlen[1] = len & 0xFF;
+			command.insert(1, (char*)szlen, 2);
+		}
+		else {
+			szlen[0] = len & 0xFF;
+			command.insert(1, (char*)szlen, 1);
+		}
+	}
+
+	// crc校验;
+	byte szcrc[2] = { 0 };
+	WORD usCRCValue = utils::CRC16Calculate((byte*)command.c_str(), command.size()); // 如果有0断开有危险;
+	//WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), len - 2);
+	szcrc[0] = (usCRCValue >> 8) & 0xFF;
+	szcrc[1] = usCRCValue & 0xFF;
+	command.append((char*)szcrc, 2);
+
+	utils::_dprintf(_T("指令:%s"), utils::BytesToHexString((byte*)command.c_str(), command.size(), ' ').c_str());
+
+	return command;
+}
+
+void TCLCommand::ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen)
+{
+	// Tag:[返回头][全数据长度][返回码]<返回码子项><附加数据>[crc16]
+	if (!TheFirstPart(cmdPara, data.substr(0, 5)))
+		return;
+
+	if (cmdPara._rtnStatus != 0x0A) {
+		utils::_dprintf("执行结果错误:%02X", cmdPara._rtnStatus);
+		return;
+	}
+
+	switch (cmdPara.nOption)
+	{
+	case CMDOPT_None:
+		break;
+	case CMDOPT_Get:
+	case CMDOPT_Set:
+		TheSecondPart(cmdPara, data.substr(5));
+		break;
+	default:
+		break;
+	}
 }

+ 73 - 1
Serail-Demo/Demo/TCLCommand.h

@@ -1,9 +1,81 @@
 #pragma once
 #include "serial.h"
 
+
+enum CMDOPT
+{
+	CMDOPT_None = 0,
+	CMDOPT_Get = 1,
+	CMDOPT_Set = 2
+};
+
+typedef struct __CMDPARAM__ {
+	std::string name;		// 命令描述;
+	std::string head;		// 命令头;
+	std::string code;		// 命令码;
+	std::string param;		// 命令码参数;
+	// 命令属性类型:
+	// 0=None,只返回一段数据包;
+	// 1=Get,返回一段或两段数据包(成功时返回2段,失败时返回1段);
+	// 2=Set,返回一段或两段数据包(成功时返回1段,失败时返回1段);
+	int nOption;
+	bool bMulticode;		// 命令码是否多参数;
+	int cmd_wait_time;		// 两条串口指令间隔时间;
+	int read_wait_time;	// 写完串口后,等待多久读;
+	byte _rtnCode;
+	byte _rtnStatus;
+	std::string _rtnData;
+	std::string _rtnError;
+	void UpdateRtnCode()
+	{
+		if (!_tcsicmp(_T("AA"), head.c_str())) { // 调试用命令代码引导码;
+			_rtnCode = 0xAB;
+		}
+		else if (!_tcsicmp(_T("AC"), head.c_str())) { // 软件配屏参数调整命令代码引导码;
+			_rtnCode = 0xAD;
+		}
+		else if (!_tcsicmp(_T("AE"), head.c_str())) { // 保留命令发送类型引导码;
+			_rtnCode = 0xAF;
+		}
+	}
+
+	void Clean()
+	{
+		//_rtnCode = 0;
+		_rtnStatus = 0;
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+		_rtnData = "";
+		_rtnError = "";
+#elif _MSC_VER >= 1500
+		_rtnData.clear();
+		_rtnError.clear();
+#endif
+	}
+
+	__CMDPARAM__() {
+		_rtnCode = 0;
+		_rtnStatus = 0;
+		nOption = 0;
+		bMulticode = false;
+		cmd_wait_time = 100;
+		read_wait_time = 100;
+	}
+} CommandParam, * pCommandParam;
+
+
 class TCLCommand :public CBaseSerial
 {
 public:
-	TCLCommand(void);
+	TCLCommand(bool bSync = true);
 	~TCLCommand(void);
+
+public:
+	int pares_time_value(std::string strTime);
+	bool parse_pair_key(std::string& RetValue, std::string strLine, TCHAR* lpszText);
+	int parse_cmd_param_from_file(TCHAR* file_name, std::vector<CommandParam>& vtCommandParams);
+
+	bool TheFirstPart(CommandParam& cmdPara, std::string data);
+	bool TheSecondPart(CommandParam& cmdPara, std::string data);
+	std::string PackingCommand(CommandParam& cmdPara, std::string data, const int& dataLen);
+	void ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen);
 };

+ 0 - 499
Serail-Demo/Demo/stdafx.cpp

@@ -6,502 +6,3 @@
 
 // TODO: 在 STDAFX.H 中
 // 引用任何所需的附加头文件,而不是在此文件中引用
-
-std::string _dprintf(CHAR* pszStr, ...)
-{
-	const int LOGLEN = 3072;
-	char szData[LOGLEN] = { 0 };
-#if _MSC_VER >= 1200 && _MSC_VER < 1500
-	sprintf(szData, _T("[%s %s]\n\t"), _T("Db"), CTime::GetCurrentTime().Format(_T("%H:%M:%S")));
-#elif _MSC_VER >= 1500
-	_stprintf_s(szData, _T("[%s %s]\n\t"), _T("Db"), CTime::GetCurrentTime().Format(_T("%H:%M:%S")).GetString());
-#endif
-	int len = strlen(szData);
-	va_list args;
-	va_start(args, pszStr);
-#if _MSC_VER >= 1200 && _MSC_VER < 1500
-	_vsnprintf(szData + len, LOGLEN - len, pszStr, args);
-#elif _MSC_VER >= 1500
-	_vsntprintf_s(szData + len, LOGLEN - len, _TRUNCATE, pszStr, args);
-#endif
-	va_end(args);
-	if (szData[strlen(szData) - 1] != '\n')
-#if _MSC_VER >= 1200 && _MSC_VER < 1500
-		strcat(szData, "\n");
-#elif _MSC_VER >= 1500
-		strcat_s(szData, "\n");
-#endif
-	OutputDebugStringA(szData);
-
-	return std::string(szData);
-}
-
-bool parse_key(std::string &RetValue, std::string strLine, TCHAR *lpszText)
-{
-	TCHAR szText[MAX_PATH] = {0};
-	TCHAR szValue[MAX_PATH] = {0};
-	// 去除空格;
-#if _MSC_VER > 1900
-	strLine.erase(std::remove_if(strLine.begin(), strLine.end(), [](unsigned char x) {return std::isspace(x); }), strLine.end()); //C++17
-#else
-	for (std::string::iterator it = strLine.begin(); it != strLine.end();)	{
-		!isspace(*it) ? it++ : it = it = strLine.erase(it);
-	}
-#endif
-
-#if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0
-	if ( 2 == sscanf(strLine.c_str(), _T("%[^=]=%s"), szText, MAX_PATH, szValue, MAX_PATH) )
-#else
-	if ( 2 == _stscanf_s(strLine.c_str(), _T("%[^=]=%s"), szText, MAX_PATH, szValue, MAX_PATH) )
-#endif
-	{
-		if ( _tcsstr(szText, lpszText) )
-		{
-			RetValue = szValue;
-			return true;
-		}
-	}
-
-	return false;
-}
-
-// 计算时间;
-// 如: 100ms 100m 100s
-int pares_time_value(std::string strTime)
-{
-	int nTimes = 0;
-#if _MSC_VER >= 1200 && _MSC_VER < 1500
-	if ( strstr(strTime.c_str(), _T("ms")) || strstr(strTime.c_str(), _T("MS")))
-	{
-		nTimes = atol(strTime.c_str());
-	}
-	else if (strstr(strTime.c_str(), _T("s")) || strstr(strTime.c_str(), _T("S")))
-	{
-		nTimes = atol(strTime.c_str()) * 1000;
-	}
-	else if (strstr(strTime.c_str(), _T("m")) || strstr(strTime.c_str(), _T("M")))
-	{
-		nTimes = atol(strTime.c_str()) * 6000;
-	}
-	else
-	{
-		// 不带单位或其他的,默认ms;
-		nTimes = atol(strTime.c_str());
-	}
-#elif _MSC_VER >= 1500
-	if ( _tcsstr(strTime.c_str(), _T("ms")) || _tcsstr(strTime.c_str(), _T("MS")))
-	{
-		nTimes = _tstol(strTime.c_str());
-	}
-	else if (_tcsstr(strTime.c_str(), _T("s")) || _tcsstr(strTime.c_str(), _T("S")))
-	{
-		nTimes = _tstol(strTime.c_str()) * 1000;
-	}
-	else if (_tcsstr(strTime.c_str(), _T("m")) || _tcsstr(strTime.c_str(), _T("M")))
-	{
-		nTimes = _tstol(strTime.c_str()) * 6000;
-	}
-	else
-	{
-		// 不带单位或其他的,默认ms;
-		nTimes = _tstol(strTime.c_str());
-	}
-#endif
-
-	return nTimes;
-}
-
-int parse_cmd_param_from_file(TCHAR *file_name, std::vector<CommandParam> &vtCommandParams)
-{
-	TCHAR buf[MAX_PATH] = {0};
-	TCHAR name[MAX_PATH] = {0};
-	TCHAR option[MAX_PATH] = {0};
-	TCHAR head[MAX_PATH] = {0};
-	TCHAR code[MAX_PATH] = {0};
-	TCHAR param[MAX_PATH] = {0};
-	TCHAR multicode[MAX_PATH] = {0};
-	TCHAR cmd_wait_time[MAX_PATH] = {0};
-	TCHAR read_wait_time[MAX_PATH] = {0};
-
-	int ret = -1;
-	FILE *fp = NULL;
-
-	if(!file_name || file_name[0] == '\0' )
-		return ret;
-
-	fp = fopen(file_name, "r");
-	if(!fp)
-		goto EXIT;
-
-	while((fgets((char*)buf, MAX_PATH, fp) != NULL)) {
-		int tmp_len = 0;
-		unsigned short keycode = 0;
-		unsigned int protocol = 0;
-		unsigned int scancode = 0;
-
-		tmp_len = _tcslen(buf);
-		if(tmp_len >= 1) {
-			if (buf[tmp_len - 1] == '\r' || buf[tmp_len - 1] == '\n')
-				buf[tmp_len - 1] = 0;
-			if(tmp_len >= 2) {
-				if(buf[tmp_len - 2] == '\r' || buf[tmp_len - 2] == '\n')
-					buf[tmp_len - 2] = 0;
-			} 
-		}
-
-#if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0 
-		if ( sscanf(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, option, head, code, param, multicode, read_wait_time, cmd_wait_time) == 8)
-#elif _MSC_VER >= 1500 
-		//if ( _stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8) // 等价下面;
-		if ( _stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%s", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8)
-#endif
-		{
-			CommandParam cp;
-			parse_key(cp.name, name, _T("Name"));
-			parse_key(cp.head, head, _T("HeadCode"));
-			parse_key(cp.code, code, _T("Command"));
-			parse_key(cp.param, param, _T("CMDParam"));
-
-			std::string value;
-			parse_key(value, option, _T("Option"));
-			if ( !_tcsicmp(value.c_str(), _T("None")) )
-				cp.nOption = CMDOPT_None;
-			else if (!_tcsicmp(value.c_str(), _T("Get")))
-				cp.nOption = CMDOPT_Get;
-			else if (!_tcsicmp(value.c_str(), _T("Set")))
-				cp.nOption = CMDOPT_Set;
-
-			parse_key(value, multicode, _T("MultiParams"));
-			cp.bMulticode = !_tcsicmp(value.c_str(), _T("true")) ? true : false;
-
-			parse_key(value, read_wait_time, _T("ReadWaitTime"));
-			cp.read_wait_time = pares_time_value(value.c_str());
-
-			parse_key(value, cmd_wait_time, _T("CMDWaitTime"));
-			cp.cmd_wait_time = pares_time_value(value.c_str());
-			cp.UpdateRtnCode();
-
-			vtCommandParams.push_back(cp);
-		}
-	}
-
-	ret = 0;
-EXIT:
-	if(fp)
-		fclose(fp);
-	return ret;
-}
-
-unsigned char TwoHexCharToInteger(char high, char low)
-{
-	std::string str = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
-	if ( str.find_first_of(high) == std::string::npos || str.find_first_of(low) == std::string::npos )
-	{
-		return 0;
-	}
-
-	char Numb1 = high >= 'A' ? (toupper(high) - '0' - 7) * 16 : (high - '0') * 16;
-	char Numb2 = low >= 'A' ? (toupper(low) - '0' - 7) : (low - '0');
-
-	return (Numb1 + Numb2);
-}
-
-const unsigned short CRC16_TABLE[16] = {
-	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
-	0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
-};
-
-unsigned short CRC16Calculate(byte *pBuffer, unsigned int wordLength)
-{
-	byte byteTemp(0);
-	unsigned short wordCRC(0);
-
-	wordCRC = 0xFFFF;
-	while (wordLength--) {
-		byteTemp = (byte)(wordCRC >> 0x0C);
-		wordCRC <<= 4;
-		wordCRC ^= CRC16_TABLE[byteTemp ^ ((*pBuffer) >> 0x04)];
-		byteTemp = (byte)(wordCRC >> 0x0C);
-		wordCRC <<= 4;
-		wordCRC ^= CRC16_TABLE[byteTemp ^ ((*pBuffer) & 0x0F)];
-		pBuffer++;
-	}
-
-	return wordCRC;
-}
-
-std::string HexStringToBytes(std::string strHex, const int &len /* = 3 */)
-{
-	byte value = 0;
-	std::string strBytes;
-	int nSize = strHex.size();
-	for (int i = 0; i < nSize; i += len)
-	{
-#if _MSC_VER >=1200 && _MSC_VER < 1500
-		strBytes.append((char)TwoHexCharToInteger(strHex[i], strHex[i + 1]),1);
-#elif _MSC_VER >=1500
-		strBytes.push_back((char)TwoHexCharToInteger(strHex[i], strHex[i + 1]));
-#endif
-	}
-
-	return strBytes;
-}
-
-std::string BytesToHexString(const unsigned char *pbuffer, int nLen, char chSpace)
-{
-	std::string hex;
-	char szhex[5] = {0};
-	for (int i = 0; i < nLen; i++)
-	{
-		memset(szhex, 0, 5);
-#if _MSC_VER >= 1200 && _MSC_VER < 1500
-		sprintf(szhex, "%02X%c", pbuffer[i], chSpace);
-#elif _MSC_VER >= 1500
-		_stprintf_s(szhex, "%02X%c", pbuffer[i], chSpace);
-#endif
-		hex.append(szhex);
-	}
-
-	return hex.substr(0, hex.size() - 1);
-}
-
-std::string BytesToHexString(const unsigned char *pbuffer, int nLen)
-{
-	std::string hex;
-	char szhex[5] = {0};
-	for (int i = 0; i < nLen; i++)
-	{
-		memset(szhex, 0, 5);
-
-#if _MSC_VER >= 1200 && _MSC_VER < 1500
-		sprintf(szhex, "%02X", pbuffer[i]);
-#elif _MSC_VER >= 1500
-		_stprintf_s(szhex, "%02X", pbuffer[i]);
-#endif
-		hex.append(szhex);
-	}
-
-	return hex;
-}
-
-std::string ByteToChars(byte b)
-{
-	char szhex[3] = { 0 };
-
-#if _MSC_VER >= 1200 && _MSC_VER < 1500
-		sprintf(szhex, "%02X", b);
-#elif _MSC_VER >= 1500
-		_stprintf_s(szhex, "%02X", b);
-#endif
-
-	return std::string(szhex);
-}
-
-BOOL IsValidString(LPCTSTR lpszString)
-{
-	if (lpszString == NULL)
-		return FALSE;
-
-	do {
-		// ASCII可显示的字符;
-		if (*lpszString < 32 || *lpszString > 126) {
-			return FALSE;
-		}
-	} while (*++lpszString);
-
-	return TRUE;
-}
-
-// 去除空格;
-std::string &trim(std::string &str)
-{
-#if 0
-	int nIndex = 0;
-	while ((nIndex = str.find_first_of(' ')) != std::string::npos)
-		str.erase(nIndex, 1);
-
-	return str;
-#endif
-
-#if _MSC_VER >= 1200 && _MSC_VER < 1600
-	for (std::string::iterator it = str.begin(); it != str.end();)	{
-		!isspace(*it) ? it++ : it = it = str.erase(it);
-	}
-#elif _MSC_VER >= 1600
-	str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char x) {return std::isspace(x); }), str.end()); //C++17
-#endif
-	return str;
-}
-
-std::string PackingCommand(CommandParam &cmdPara, std::string data, const int &dataLen)
-{
-	// Tag:[命令头][全命令长度][命令码]<命令码参数><附加数据>[crc1][crc2]
-	std::string command;
-	// 命令头标识位;
-	command.append(HexStringToBytes(cmdPara.head, 2).c_str(), cmdPara.head.size() / 2);
-	// 命令码;
-	command.append(HexStringToBytes(cmdPara.code, 2).c_str(), cmdPara.code.size() / 2);
-	// 命令码参数;
-	command.append(HexStringToBytes(cmdPara.param, 2).c_str(), cmdPara.param.size() / 2);
-	// 附加的数据;
-	if ( dataLen > 0)
-		command.append(data.c_str(), dataLen);
-
-	int len(0);
-	// 长度:可能1字节表示,超过255用2字节表示;
-	byte szlen[2] = {0};
-	//if ((byte)command[1] == 0xFE)
-	//if ( cmdPara.head.size() >= 4 && cmdPara.head.find("FE", 2, 2) != std::string::npos )
-	if ( _tcsicmp(_T("AAFE"), cmdPara.head.c_str()) == 0 )
-	{// 长度超过255,需要2字节表示;
-		len = command.size() + 4;	// 2位crc + 2位长度;
-		szlen[0] = (len >> 8) & 0xFF;
-		szlen[1] = len & 0xFF;
-		command.insert(2, (char *)szlen, 2);
-	} else {
-		// 2位crc + 1位长度;
-		len = command.size() + 3;	
-		//if ( _tcsicmp(cmdPara.code.c_str(), "99 00") == 0 )
-		//	len -= 2;
-
-		if ( len > 255 ) {// 长度超过255,多一个占位符;
-			++len;
-			szlen[0] = (len >> 8) & 0xFF;
-			szlen[1] = len  & 0xFF;
-			command.insert(1, (char *)szlen, 2);
-		} else {
-			szlen[0] = len & 0xFF;
-			command.insert(1, (char *)szlen, 1);
-		}
-	}
-
-	// crc校验;
-	byte szcrc[2] = {0};
-	WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), command.size()); // 如果有0断开有危险;
-	//WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), len - 2);
-	szcrc[0] = (usCRCValue >> 8) & 0xFF;
-	szcrc[1] = usCRCValue & 0xFF;
-	command.append((char *)szcrc, 2);
-
-	return command;
-}
-
-#define NoneOptLen 5
-
-bool TheFirstPart(CommandParam& cmdPara, std::string data)
-{
-	if (data.size() == NoneOptLen) {
-		if ((byte)data[0] == cmdPara._rtnCode) {
-			// 长度;
-			int nPackageLen = (byte)data[1];
-			if (nPackageLen != NoneOptLen) {
-				cmdPara._rtnError = _dprintf("None长度错误:%ld", (byte)data[1]);
-				return false;
-			}
-
-			// 执行状态;
-			cmdPara._rtnStatus = (byte)data[2];
-			_dprintf(_T("rtnStatus=%02X"), cmdPara._rtnStatus);
-
-			// 校验crc;
-			unsigned short usCRCValue = CRC16Calculate((byte*)data.data(), nPackageLen - 2);
-			if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPackageLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPackageLen - 1])
-			{
-				cmdPara._rtnError = _dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPackageLen - 2], (byte)data[nPackageLen - 1]);
-				return false;
-			}
-		}
-		else {
-			cmdPara._rtnError = _dprintf("返回码错误:%02X", (byte)data[0]);
-			return false;
-		}
-	}
-	else {
-		cmdPara._rtnError = _dprintf("长度对不上:Option.None");
-		return false;
-	}
-
-	return true;
-}
-
-bool TheSecondPart(CommandParam& cmdPara, std::string data)
-{
-	int nDataPos = 0;
-	int nPackageLen = 0;
-	if ((byte)data[0] == cmdPara._rtnCode) {
-		// 获取长度;
-		if ( (byte)data[1] == 0xFE ) {
-			nDataPos = 4;
-			nPackageLen = (byte)data[2] << 8 | (byte)data[3];
-			if ( data.size() < 255 && data[2] != 0 ) {	
-				cmdPara._rtnError = _dprintf(_T("长度异常"));
-				return false;
-			}
-		}
-		else
-		{
-			nDataPos = 2;
-			nPackageLen = (byte)data[1];
-#if 0 // 如果数据包含有非协议包内的数据,会判断异常;
-			if ( data.size() > 255 ){	
-				//nPackageLen = data[1] << 8 | data[2];
-				cmdPara._rtnError = _dprintf(_T("长度异常"));
-				return false;
-			}
-#endif
-		}
-
-#if 0
-		// 计算出的长度,必等于包长;// 如果包含有其他非包数据,会判断异常;
-		if ( nPackageLen != data.size() )
-			return false;
-#endif
-
-		if (_tcsicmp(cmdPara.code.c_str(), ByteToChars((byte)data[nDataPos]-1).c_str()) != 0) {
-			cmdPara._rtnError = _dprintf(_T("返回的指令错误, %s, %02X"), cmdPara.head.c_str(),(byte)data[nDataPos]);
-			return false;
-		}
-
-		// 执行状态;
-		cmdPara._rtnData = data.substr(nDataPos+1, nPackageLen - nDataPos - 3); //3 = crc + 返回指令码;
-		_dprintf(_T("rtnData=%s"), BytesToHexString((byte*)cmdPara._rtnData.c_str(), cmdPara._rtnData.size(), ' ').c_str());
-
-		// 校验crc;
-		unsigned short usCRCValue = CRC16Calculate((byte*)data.data(), nPackageLen - 2);
-		if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPackageLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPackageLen - 1])
-		{
-			cmdPara._rtnError = _dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPackageLen - 2], (byte)data[nPackageLen - 1]);
-			return false;
-		}
-
-#if 1
-		if ( data.size() > nPackageLen )
-			_dprintf("带有脏数据:%s", data.substr(nPackageLen));
-#endif
-	}
-	else {
-		cmdPara._rtnError = _dprintf("返回码错误:%02X", (byte)data[0]);
-		return false;
-	}
-
-	return true;
-}
-
-void ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen)
-{
-	// Tag:[返回头][全数据长度][返回码]<返回码子项><附加数据>[crc16]
-	if ( !TheFirstPart(cmdPara, data.substr(0, 5)) )
-		return;
-
-	switch ( cmdPara.nOption )
-	{
-	case CMDOPT_None:
-		break;
-	case CMDOPT_Get:
-	case CMDOPT_Set:
-		TheSecondPart(cmdPara, data.substr(5));
-		break;
-	default:
-		break;
-	}
-}

+ 1 - 71
Serail-Demo/Demo/stdafx.h

@@ -29,74 +29,4 @@
 #include <string>
 #include <vector>
 #include "Serial.h"
-
-enum CMDOPT
-{
-	CMDOPT_None = 0,
-	CMDOPT_Get = 1,
-	CMDOPT_Set = 2
-};
-
-typedef struct __CMDPARAM__ {
-	std::string name;		// 命令描述;
-	std::string head;		// 命令头;
-	std::string code;		// 命令码;
-	std::string param;		// 命令码参数;
-	// 命令属性类型:
-	// 0=None,只返回一段数据包;
-	// 1=Get,返回一段或两段数据包(成功时返回2段,失败时返回1段);
-	// 2=Set,返回一段或两段数据包(成功时返回1段,失败时返回1段);
-	int nOption;			
-	bool bMulticode ;		// 命令码是否多参数;
-	int cmd_wait_time ;		// 两条串口指令间隔时间;
-	int read_wait_time ;	// 写完串口后,等待多久读;
-	byte _rtnCode;
-	byte _rtnStatus;
-	std::string _rtnData;
-	std::string _rtnError;
-	void UpdateRtnCode()
-	{
-		if (!_tcsicmp(_T("AA"), head.c_str())) { // 调试用命令代码引导码;
-			_rtnCode = 0xAB;
-		}
-		else if (!_tcsicmp(_T("AC"), head.c_str())) { // 软件配屏参数调整命令代码引导码;
-			_rtnCode = 0xAD;
-		}
-		else if (!_tcsicmp(_T("AE"), head.c_str())) { // 保留命令发送类型引导码;
-			_rtnCode = 0xAF;
-		}
-	}
-
-	void Clean()
-	{
-		//_rtnCode = 0;
-		_rtnStatus = 0;
-#if _MSC_VER >= 1200 && _MSC_VER < 1500
-		_rtnData = "";
-		_rtnError = "";
-#elif _MSC_VER >= 1500
-		_rtnData.clear();
-		_rtnError.clear();
-#endif
-	}
-
-	__CMDPARAM__() {
-		_rtnCode = 0;
-		_rtnStatus = 0;
-		nOption = 0;
-		bMulticode = false;
-		cmd_wait_time = 100;
-		read_wait_time = 100;
-	}
-} CommandParam, *pCommandParam;
-
-std::string _dprintf(CHAR* pszStr, ...);
-int pares_time_value(std::string strTime);
-bool parse_key(std::string &value, std::string strLine, TCHAR *lpszText);
-int parse_cmd_param_from_file(TCHAR*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);
-void ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen);
-// TODO: 在此处引用程序需要的其他头文件
+#include "utils.h"

+ 167 - 0
Serail-Demo/Demo/utils.cpp

@@ -0,0 +1,167 @@
+#include "stdafx.h"
+#include "utils.h"
+
+namespace utils
+{
+	const unsigned short CRC16_TABLE[16] = {
+	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+	0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF
+	};
+
+	std::string& trim(std::string& str)
+	{
+#if _MSC_VER >= 1200 && _MSC_VER < 1600
+		for (std::string::iterator it = str.begin(); it != str.end();) {
+			!isspace(*it) ? it++ : it = it = str.erase(it);
+		}
+#elif _MSC_VER >= 1600
+		str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char x) {return std::isspace(x); }), str.end()); //C++17
+#endif
+		return str;
+	}
+
+	std::string _dprintf(CHAR* pszStr, ...)
+	{
+		const int LOGLEN = 8912;
+		char szData[LOGLEN] = { 0 };
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+		sprintf(szData, _T("[%s %s]\n\t"), _T("Db"), CTime::GetCurrentTime().Format(_T("%H:%M:%S")));
+#elif _MSC_VER >= 1500
+		_stprintf_s(szData, _T("[%s %s]\n\t"), _T("Db"), CTime::GetCurrentTime().Format(_T("%H:%M:%S")).GetString());
+#endif
+		int len = strlen(szData);
+		va_list args;
+		va_start(args, pszStr);
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+		_vsnprintf(szData + len, LOGLEN - len, pszStr, args);
+#elif _MSC_VER >= 1500
+		_vsntprintf_s(szData + len, LOGLEN - len, _TRUNCATE, pszStr, args);
+#endif
+		va_end(args);
+		if (szData[strlen(szData) - 1] != '\n')
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			strcat(szData, "\n");
+#elif _MSC_VER >= 1500
+			strcat_s(szData, "\n");
+#endif
+		OutputDebugStringA(szData);
+
+		return std::string(szData);
+	}
+
+	std::string ByteToChars(byte b)
+	{
+		char szhex[3] = { 0 };
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+		sprintf(szhex, "%02X", b);
+#elif _MSC_VER >= 1500
+		_stprintf_s(szhex, "%02X", b);
+#endif
+
+		return std::string(szhex);
+	}
+
+	BOOL IsValidString(LPCTSTR lpszString)
+	{
+		if (lpszString == NULL)
+			return FALSE;
+
+		do {
+			// ASCII¿ÉÏÔʾµÄ×Ö·û;
+			if (*lpszString < 32 || *lpszString > 126) {
+				return FALSE;
+			}
+		} while (*++lpszString);
+
+		return TRUE;
+	}
+
+	unsigned char TwoHexCharToInteger(char high, char low)
+	{
+		std::string str = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
+		if (str.find_first_of(high) == std::string::npos || str.find_first_of(low) == std::string::npos)
+		{
+			return 0;
+		}
+
+		char Numb1 = high >= 'A' ? (toupper(high) - '0' - 7) * 16 : (high - '0') * 16;
+		char Numb2 = low >= 'A' ? (toupper(low) - '0' - 7) : (low - '0');
+
+		return (Numb1 + Numb2);
+	}
+
+	std::string BytesToHexString(const unsigned char* pbuffer, int nLen)
+	{
+		std::string hex;
+		char szhex[5] = { 0 };
+		for (int i = 0; i < nLen; i++)
+		{
+			memset(szhex, 0, 5);
+
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			sprintf(szhex, "%02X", pbuffer[i]);
+#elif _MSC_VER >= 1500
+			_stprintf_s(szhex, "%02X", pbuffer[i]);
+#endif
+			hex.append(szhex);
+		}
+
+		return hex;
+	}
+
+	std::string BytesToHexString(const unsigned char* pbuffer, int nLen, char chSpace)
+	{
+		std::string hex;
+		char szhex[5] = { 0 };
+		for (int i = 0; i < nLen; i++)
+		{
+			memset(szhex, 0, 5);
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+			sprintf(szhex, "%02X%c", pbuffer[i], chSpace);
+#elif _MSC_VER >= 1500
+			_stprintf_s(szhex, "%02X%c", pbuffer[i], chSpace);
+#endif
+			hex.append(szhex);
+		}
+
+		return hex.substr(0, hex.size() - 1);
+	}
+
+	std::string HexStringToBytes(std::string strHex, const int& len)
+	{
+		byte value = 0;
+		std::string strBytes;
+		int nSize = strHex.size();
+		for (int i = 0; i < nSize; i += len)
+		{
+#if _MSC_VER >=1200 && _MSC_VER < 1500
+			strBytes.append((char)TwoHexCharToInteger(strHex[i], strHex[i + 1]), 1);
+#elif _MSC_VER >=1500
+			strBytes.push_back((char)TwoHexCharToInteger(strHex[i], strHex[i + 1]));
+#endif
+		}
+
+		return strBytes;
+	}
+
+	unsigned short CRC16Calculate(byte* pBuffer, unsigned int wordLength)
+	{
+		byte byteTemp(0);
+		unsigned short wordCRC(0);
+
+		wordCRC = 0xFFFF;
+		while (wordLength--) {
+			byteTemp = (byte)(wordCRC >> 0x0C);
+			wordCRC <<= 4;
+			wordCRC ^= CRC16_TABLE[byteTemp ^ ((*pBuffer) >> 0x04)];
+			byteTemp = (byte)(wordCRC >> 0x0C);
+			wordCRC <<= 4;
+			wordCRC ^= CRC16_TABLE[byteTemp ^ ((*pBuffer) & 0x0F)];
+			pBuffer++;
+		}
+
+		return wordCRC;
+	}
+
+}

+ 15 - 0
Serail-Demo/Demo/utils.h

@@ -0,0 +1,15 @@
+#pragma once
+namespace utils
+{
+	std::string& trim(std::string& str);
+	std::string _dprintf(CHAR* pszStr, ...);
+	std::string ByteToChars(byte b);
+	BOOL IsValidString(LPCTSTR lpszString);
+	unsigned char TwoHexCharToInteger(char high, char low);
+	std::string BytesToHexString(const unsigned char* pbuffer, int nLen);
+	std::string BytesToHexString(const unsigned char* pbuffer, int nLen, char chSpace);
+
+	std::string HexStringToBytes(std::string strHex, const int& len /* = 3 */);
+	unsigned short CRC16Calculate(byte* pBuffer, unsigned int wordLength);
+};
+