[英]Serial COM port communications not working
I'm writing a test app for some serial communications that my team is working on. 我正在为团队正在处理的一些串行通信编写测试应用程序。 Its written in Visual C++ (unmanaged) on VS2010.
它是用Visual C ++(非托管)在VS2010上编写的。 We're testing it on Windows 7x64.
我们正在Windows 7x64上对其进行测试。 If we run Putty first (and connect), our code works.
如果我们先运行Putty(并连接),我们的代码将起作用。 If we don't run Putty first (and connect), nothing works.
如果我们不先运行Putty(并连接),那么将无法进行任何操作。
The return codes from Read/Write file are as follows: 读/写文件的返回码如下:
w/o putty 不带腻子
write file = 1 read file = 1 写入文件= 1读取文件= 1
w/ putty 腻子
write file = 1 read file = 1 写入文件= 1读取文件= 1
The SetCommState routine returns 1 (a pass): https://msdn.microsoft.com/en-us/library/windows/desktop/aa363436%28v=vs.85%29.aspx Just double checking: Calling GetLastError immediately after SetCommState returns 0; SetCommState例程返回1(通过): https ://msdn.microsoft.com/zh-cn/library/windows/desktop/aa363436%28v=vs.85%29.aspx只是仔细检查一下:SetCommState之后立即调用GetLastError返回0;
We're running on COM7, but COM4 is selected in the GUI (dirty hack). 我们在COM7上运行,但是在GUI中选择了COM4(脏污)。 What happens is that the readfile routine doesn't return back a string (via pointer).
发生的情况是readfile例程不返回字符串(通过指针)。 This indicates that writefile isn't working properly, but I'm not 100% sure about this.
这表明writefile不能正常工作,但是我对此不是100%肯定。
Does anyone out there know why this might happen? 有谁知道为什么会这样吗?
Here is the code: 这是代码:
Note: I tried to show everything, but the code formatter screwed up. 注意:我试图显示所有内容,但是代码格式化程序搞砸了。 Everything that is important is here.
重要的一切都在这里。
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;
}
}
}
}
My educated guess would be, your SetCommState
call fails. 我的猜测是,您的
SetCommState
调用失败。 You are passing it a DCB
structure filled with random garbage. 您正在向其传递填充有随机垃圾的
DCB
结构。 The reason it works after Putty is that Putty configures the port for you, and your program gets to use that configuration (since it fails to establish its own). 在Putty之后它起作用的原因是Putty为您配置了端口,并且您的程序开始使用该配置(因为它无法建立自己的端口)。
Change DCB comSettings;
更改
DCB comSettings;
line to 线到
DCB comSettings = {sizeof(DCB)};
This initializes DCBlength
member correctly, and sets all other members to 0. Then set up other members as necessary for your device. 这将正确初始化
DCBlength
成员,并将所有其他成员设置为0。然后根据需要为设备设置其他成员。
And check the return value of SetCommState
for errors (as well as that of all other API calls). 并检查
SetCommState
的返回值SetCommState
有错误(以及所有其他API调用的返回值)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.