zhangyang пре 4 година
родитељ
комит
84e9167ebf

+ 39 - 6
zhipuzi_pos_windows/tool/CSerialPort.cpp

@@ -17,6 +17,20 @@ CSerialPort::CSerialPort(
 
 }
 
+CSerialPort::CSerialPort(
+	DWORD baudRate /* = 9600 */,
+	BYTE byteSize /* = 8 */,
+	BYTE parityBit /* = NOPARITY */,
+	BYTE stopBit /* = ONESTOPBIT */
+) : m_dwBaudRate(baudRate),
+m_byteSize(byteSize),
+m_parityBit(parityBit),
+m_stopBit(stopBit),
+m_bOpen(false)
+{
+
+}
+
 CSerialPort::~CSerialPort()
 {
 
@@ -43,8 +57,17 @@ bool CSerialPort::openComm()
     }
     else
     {
+		SetupComm(m_hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);	// 设置读写缓冲区大小
+
+		COMMTIMEOUTS TimeOuts; //设定读超时
+		TimeOuts.ReadIntervalTimeout = 1000;
+		TimeOuts.ReadTotalTimeoutMultiplier = 500;
+		TimeOuts.ReadTotalTimeoutConstant = 5000; //设定写超时
+		TimeOuts.WriteTotalTimeoutMultiplier = 500;
+		TimeOuts.WriteTotalTimeoutConstant = 2000;
+		SetCommTimeouts(m_hComm, &TimeOuts); //设置超时
+
         DCB dcb;
-        SetupComm(m_hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);	// 设置读写缓冲区大小
         GetCommState(m_hComm, &dcb);
         dcb.BaudRate = m_dwBaudRate;
         dcb.ByteSize = m_byteSize;
@@ -62,7 +85,13 @@ bool CSerialPort::openComm()
     }
 
     //在读写串口前,用 PurgeComm 函数清空缓冲区
-    PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
+    BOOL ret = PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
+	if (!ret)
+	{
+		TCHAR szBuf[1024] = { 0 };
+		wsprintf(szBuf, _T("清空缓冲区失败,错误代码: %d"), GetLastError());
+		MessageBox(NULL, szBuf, L"ERROR", MB_OK);
+	}
 
     m_bOpen = true;
 
@@ -71,9 +100,13 @@ bool CSerialPort::openComm()
 }
 
 // 关闭串口
-
 void CSerialPort::closeComm()
 {
+	if (!m_bOpen)
+	{
+		return;
+	}
+
     CloseHandle(m_hComm);
 }
 
@@ -138,9 +171,9 @@ bool CSerialPort::readFromComm(char buffer[], DWORD dwLength, DWORD* nReaded)
     }
     else
     {
-        TCHAR szBuf[1024] = { 0 };
-        wsprintf(szBuf, _T("数据读取失败,错误代码: %d"), GetLastError());
-		LOG_INFO(szBuf);
+		TCHAR szBuf[1024] = { 0 };
+		wsprintf(szBuf, _T("读取数据失败,错误代码: %d"), GetLastError());
+		MessageBox(NULL, szBuf, L"ERROR", MB_OK);
 
         return false;
     }

+ 9 - 1
zhipuzi_pos_windows/tool/CSerialPort.h

@@ -17,6 +17,13 @@ public:
         BYTE  stopBit = ONESTOPBIT		// 停止位
     );
 
+	CSerialPort(
+		DWORD baudRate = 9600,			// 波特率
+		BYTE  byteSize = 8,				// 数据位
+		BYTE  parityBit = NOPARITY,		// 检验位
+		BYTE  stopBit = ONESTOPBIT		// 停止位
+	);
+
     ~CSerialPort();
 
 public:
@@ -35,7 +42,8 @@ private:
     BYTE  m_parityBit;  // 校验位
     BYTE  m_stopBit;	// 停止位
     bool  m_bOpen;		// 串口开关标志
-private:
+
+public:
 
     enum BufferSize
     {

+ 56 - 102
zhipuzi_pos_windows/wnd/CChengzhongWnd.cpp

@@ -1,6 +1,5 @@
 #include "../pch/pch.h"
 #include "CChengzhongWnd.h"
-#include "../tool/CSerialPort.h"
 
 LRESULT CChengzhongWnd::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
 {
@@ -220,13 +219,16 @@ void CChengzhongWnd::ReadChuankouValue()
 
 	//CSerialPort serial(CLewaimaiString::UTF8ToUnicode(system_setting_jinezhuaqu_setting_xunichuankou_num_2), atoi(system_setting_jinezhuaqu_setting_xunichuankou_botelv.c_str()));
 
-	CSerialPort serial(L"COM3", 9600);
-
-	bool ret = serial.openComm();
+	m_serial.setPortNum(L"COM3");
+	m_serial.setBaudRate(9600);
 
+	bool ret = m_serial.openComm();
 	if (!ret)
 	{
-		LOG_INFO("open com failed!");
+		CLabelUI* pErrorInfo = static_cast<CLabelUI*>(m_pm.FindControl(_T("errinfo")));
+		pErrorInfo->SetText(L"串口打开失败!");
+		pErrorInfo->SetVisible(true);
+
 		return;
 	}
 
@@ -245,21 +247,13 @@ void CChengzhongWnd::ReadChuankouValue()
 		//开始读取串口的数据
 		DWORD nReaded = 0;
 
-		Sleep(2000);
-
-		serial.readFromComm(a, 1024, &nReaded);
+		m_serial.readFromComm(a, 1024, &nReaded);
 
 		if (nReaded > 0)
 		{
 			//把所有读到的内容,拼接到m_chuankou_string后面,避免有的数据中间截断导致格式混乱
 			m_chuankou_string += a;
 
-			if (m_chuankou_string.length() < 7)
-			{
-				//没有读到足够的长度,继续读(稳定模式7个字符,极速模式22个字符)
-				continue;
-			}
-
 			//已经有7个字符了,那么判断是稳定模式还是极速模式
 			std::string show_command = "\n\r";
 
@@ -270,107 +264,58 @@ void CChengzhongWnd::ReadChuankouValue()
 				continue;
 			}
 
-			if (nPos == 0)
+			std::string weight;
+
+			//如果前2个不是标志符,那么就判断标志符后面的数字长度够不够5个
+			if (m_chuankou_string.length() >= nPos + 7)
 			{
-				//稳定模式
-				std::string weight;
+				//这个情况是,标志符后面有5个数字
 				weight = m_chuankou_string.substr(nPos + 2, 5);
-				m_chuankou_string = m_chuankou_string.substr(7);
-
-				if (weight.at(0) == ' ')
-				{
-					weight = weight.substr(1);
-				}
-
-				std::string zhengshu;
-				std::string xiaoshu;
-				if (weight.length() == 4)
-				{
-					//重量小于10公斤,第一个数字为空
-					zhengshu = weight.substr(0, 1);
-					xiaoshu = weight.substr(1, 3);
-				}
-				else if (weight.length() == 5)
-				{
-					//重量大于10公斤,第一个数字为空
-					zhengshu = weight.substr(0, 2);
-					xiaoshu = weight.substr(2, 3);
-				}
-				else
-				{
-					continue;
-				}
 
-				m_weight = zhengshu + "." + xiaoshu;
+				//然后把前面的字符都删掉
+				m_chuankou_string = m_chuankou_string.substr(nPos + 7);
 			}
 			else
 			{
-				//极速模式
-				if (m_chuankou_string.length() < 22)
-				{
-					//没有读到足够的长度,继续读
-					continue;
-				}
-
-				std::string weight;
-				weight = m_chuankou_string.substr(0, 5);
-				m_chuankou_string = m_chuankou_string.substr(22);
-
-				if (weight.at(0) == ' ')
-				{
-					weight = weight.substr(1);
-				}
+				//标志符后面不够读取重量,继续读取串口
+				continue;
+			}
 
-				std::string zhengshu;
-				std::string xiaoshu;
-				if (weight.length() == 4)
-				{
-					//重量小于10公斤,第一个数字为空
-					zhengshu = weight.substr(0, 1);
-					xiaoshu = weight.substr(1, 3);
-				}
-				else if (weight.length() == 5)
-				{
-					//重量大于10公斤,第一个数字为空
-					zhengshu = weight.substr(0, 2);
-					xiaoshu = weight.substr(2, 3);
-				}
-				else
-				{
-					continue;
-				}
+			if (weight.at(0) == ' ')
+			{
+				weight = weight.substr(1);
+			}
 
-				m_weight = zhengshu + "." + xiaoshu;
+			std::string zhengshu;
+			std::string xiaoshu;
+			if (weight.length() == 4)
+			{
+				//重量小于10公斤,第一个数字为空
+				zhengshu = weight.substr(0, 1);
+				xiaoshu = weight.substr(1, 3);
+			}
+			else if (weight.length() == 5)
+			{
+				//重量大于10公斤,第一个数字为空
+				zhengshu = weight.substr(0, 2);
+				xiaoshu = weight.substr(2, 3);
+			}
+			else
+			{
+				continue;
 			}
 
+			m_weight = zhengshu + "." + xiaoshu;
+
 			SendMessage(WM_CHENGZHONG_SUCCESS, 0, 0);
 		}
-		else
-		{
-			Sleep(100);
-		}
 	}
 
-	serial.closeComm();
-
 	m_is_chuangkou_working = false;
 }
 
 void CChengzhongWnd::SaveWeight()
 {
-	if (m_is_watching == false || m_is_chuangkou_working == false)
-	{
-		return;
-	}
-
-	m_is_watching = false;
-
-	//等待串口关闭
-	while (m_is_chuangkou_working)
-	{
-		Sleep(100);
-	}
-
 	CEditUI* pContent = static_cast<CEditUI*>(m_pm.FindControl(_T("content")));
 	wstring wsReason = pContent->GetText();
 
@@ -385,19 +330,28 @@ void CChengzhongWnd::SaveWeight()
 		return;
 	}
 
+	m_is_watching = false;
+
+	//关闭串口,关闭之后读取串口的工作线程会退出
+	m_serial.closeComm();
+
+	//等待工作线程退出
+	while (m_is_chuangkou_working)
+	{
+		Sleep(100);
+	}
+
 	Close(IDOK);
 }
 
 void CChengzhongWnd::Quit()
 {
-	if (m_is_watching == false || m_is_chuangkou_working == false)
-	{
-		return;
-	}
-
 	m_is_watching = false;
 
-	//等待串口关闭
+	//关闭串口,关闭之后读取串口的工作线程会退出
+	m_serial.closeComm();
+
+	//等待工作线程退出
 	while (m_is_chuangkou_working)
 	{
 		Sleep(100);

+ 4 - 0
zhipuzi_pos_windows/wnd/CChengzhongWnd.h

@@ -2,6 +2,7 @@
 
 #include "../pch/pch.h"
 #include "CMainWnd.h"
+#include "../tool/CSerialPort.h"
 
 class CChengzhongWnd : public CWindowWnd, public INotifyUI, public IMessageFilterUI
 {
@@ -81,11 +82,14 @@ public:
 	//最终称出来的重量
 	std::string m_weight;
 
+	//临时读取到的串口数据
 	std::string m_chuankou_string;
 
 	//这个表示当前是否正在读取串口值
 	bool m_is_chuangkou_working = false;
 
 	bool m_is_watching = false;
+
+	CSerialPort m_serial;
 };