【发布时间】:2016-01-18 15:33:56
【问题描述】:
我正在为我的团队正在处理的一些串行通信编写一个测试应用程序。它在 VS2010 上用 Visual C++(非托管)编写。我们正在 Windows 7x64 上对其进行测试。如果我们先运行 Putty(并连接),我们的代码就可以工作。如果我们不先运行 Putty(并连接),就什么都做不了。
读/写文件的返回码如下:
无油灰
写入文件 = 1 读取文件 = 1
用腻子
写入文件 = 1 读取文件 = 1
SetCommState 例程返回 1(通过):https://msdn.microsoft.com/en-us/library/windows/desktop/aa363436%28v=vs.85%29.aspx 只需仔细检查:在 SetCommState 返回 0 后立即调用 GetLastError;
我们在 COM7 上运行,但在 GUI 中选择了 COM4(脏 hack)。发生的情况是 readfile 例程没有返回字符串(通过指针)。这表明 writefile 工作不正常,但我对此不是 100% 确定。
有没有人知道为什么会发生这种情况?
代码如下:
注意:我试图显示所有内容,但代码格式化程序搞砸了。重要的都在这里。
OutputDebugStringW(L"Previous COM port = " + portString + "\n");
comPort = 4;
com4 = true;
OutputDebugStringW(L"SETCOM - COM4\n");
hComm = CreateFile(L"COM7", GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
NULL);
if (hComm == INVALID_HANDLE_VALUE)
OutputDebugStringW(L"Error!");
else
OutputDebugStringW(L"Success!");
DCB comSettings;
SecureZeroMemory(&comSettings, sizeof(DCB));
comSettings.BaudRate = 9600;
comSettings.ByteSize = 8;
comSettings.Parity = NOPARITY;
comSettings.StopBits = ONESTOPBIT;
comSettings.fAbortOnError = TRUE;
b = SetCommState(hComm, &comSettings);
commSetupResult = GetLastError();
/*OutputDebugStringW(L"SetCommState = " + (int)SetCommState(hComm, &comSettings));*/
//s.Format("%d",4);//SetCommState(hComm, &comSettings));
// instance an object of COMMTIMEOUTS.
COMMTIMEOUTS comTimeOut;
// Specify time-out between charactor for receiving.
comTimeOut.ReadIntervalTimeout = 3;
// Specify value that is multiplied
// by the requested number of bytes to be read.
comTimeOut.ReadTotalTimeoutMultiplier = 3;
// Specify value is added to the product of the
// ReadTotalTimeoutMultiplier member
comTimeOut.ReadTotalTimeoutConstant = 2;
// Specify value that is multiplied
// by the requested number of bytes to be sent.
comTimeOut.WriteTotalTimeoutMultiplier = 3;
// Specify value is added to the product of the
// WriteTotalTimeoutMultiplier member
comTimeOut.WriteTotalTimeoutConstant = 2;
// set the time-out parameter into device control.
SetCommTimeouts(hComm, &comTimeOut);
break;
case ID_SETCOM_COM5:
OutputDebugStringW(L"Previous COM port = " + portString + "\n");
comPort = 5;
OutputDebugStringW(L"SETCOM - COM5\n");
hComm = CreateFile(L"COM5", GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE)
OutputDebugStringW(L"Error!");
else
OutputDebugStringW(L"Success!");
break;
case ID_SETCOM_COM6:
OutputDebugStringW(L"Previous COM port = " + portString + "\n");
comPort = 6;
OutputDebugStringW(L"SETCOM - COM6\n");
hComm = CreateFile(L"COM6", GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE)
OutputDebugStringW(L"Error!");
else
OutputDebugStringW(L"Success!");
break;
case ID_SETCOM_COM7:
OutputDebugStringW(L"Previous COM port = " + portString + "\n");
comPort = 7;
OutputDebugStringW(L"SETCOM - COM7\n");
hComm = CreateFile(L"COM7", GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE)
OutputDebugStringW(L"Error!");
else
OutputDebugStringW(L"Success!");
break;
case ID_SETCOM_COM8:
OutputDebugStringW(L"Previous COM port = " + portString + "\n");
comPort = 8;
OutputDebugStringW(L"SETCOM - COM8\n");
hComm = CreateFile(L"COM8", GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE)
OutputDebugStringW(L"Error!");
else
OutputDebugStringW(L"Success!");
break;
case ID_SETCOM_COM9:
OutputDebugStringW(L"Previous COM port = " + portString + "\n");
comPort = 9;
OutputDebugStringW(L"SETCOM - COM9\n");
hComm = CreateFile(L"COM9", GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE)
OutputDebugStringW(L"Error!");
else
OutputDebugStringW(L"Success!");
break;
case ID_SETCOM_COM10:
OutputDebugStringW(L"Previous COM port = " + portString + "\n");
comPort = 10;
OutputDebugStringW(L"SETCOM - COM10\n");
hComm = CreateFile(L"COM9", GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE)
OutputDebugStringW(L"Error!");
else
OutputDebugStringW(L"Success!");
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
DWORD dwRead;
BOOL fWaitingOnRead = FALSE;
OVERLAPPED osReader = { 0 };
// Create the overlapped event. Must be closed before exiting
// to avoid a handle leak.
osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osReader.hEvent == NULL) {}
// Error creating overlapped event; abort.
char lpBuf[32];
if (com4) {
if (!fWaitingOnRead)
{
// Issue read operation.
OVERLAPPED osWrite = { 0 };
DWORD dwWritten;
BOOL result = GetLastError();
result = WriteFile(hComm, "EO1\nJAX0\nDI\n", 12, &dwWritten, NULL);
CStringA WFError;
WFError.Format("\nSent %d result %d lasterror %d \n", dwWritten, result, GetLastError());
OutputDebugStringA(WFError);
Sleep(100);//min was 61, 100 to be safe
bool Wait = true;
DWORD start = GetTickCount() + 15000;
while (Wait && start > GetTickCount())
{
Sleep(200);
// GetLastError();
result = ReadFile(hComm, lpBuf, 32, &dwRead, NULL);
WFError.Format("Read %d, result %d, lasterror %d \n", dwRead, result, GetLastError());
OutputDebugStringA(WFError);
// WFError = "Read file error = " + WFError;
if (result != 0)
{
CString temp = lpBuf;
temp = temp.Left(dwRead);
if (temp.GetLength() > 0)
{
OutputDebugString(temp + "\n");
MessageBox(NULL, temp, L"Title", MB_OK);
// memset(&lpBuf[0], 0, sizeof(lpBuf));
}
//strcpy(lpBuf,"");
// goto start;
}
}
}
}
【问题讨论】:
-
不要责怪代码格式化程序。相反,请阅读Markdown Editing Help 来熟悉它。也完全不清楚,代码在哪里失败,它返回什么错误代码等等。
-
检查
SetCommState调用是否成功。我的猜测是它失败了,你的程序在 Putty 之后工作的原因是 Putty 为你配置了 COM 端口。最重要的是,您没有设置DCBlength。试试这个:用DCB comSettings = {sizeof(DCB)};替换DCB comSettings;(这有两件事:初始化DCBlength成员,并将所有其他成员归零)。
标签: c++ visual-c++ mfc serial-port